Skip to content

Commit

Permalink
#1 Added testing environment
Browse files Browse the repository at this point in the history
#2 Added missing events
#3 bump up compiler version to 0.5.12(same with DAI)
#6 use enum to represent contract state
#7 Added methods to prevent "approve" race condition
  • Loading branch information
Jongsic committed May 12, 2020
1 parent 0880343 commit 259c43b
Show file tree
Hide file tree
Showing 11 changed files with 5,074 additions and 12 deletions.
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
end_of_line = lf
indent_style = space
indent_size = 4
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true

[*.js]
indent_size = 2

[{*.bat, *.ps1, *.ps2, Makefile, *.go}]
indent_style = tab
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sol linguist-language=Solidity
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
### IDEs
.idea
.vscode

### Temporary Files
*.swp
*.tmp
*.log
logs
.DS_Store

### Node.js
node_modules

### Buidler Files
cache
artifacts
17 changes: 17 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
### IDEs
.idea
.vscode

### Temporary Files
*.swp
*.tmp
*.log
logs
.DS_Store

### Node.js
node_modules

### Buidler Files
cache
artifacts
74 changes: 74 additions & 0 deletions buidler.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
usePlugin('@nomiclabs/buidler-truffle5')

const { toEthString } = require('./utils')

const accountBalance = async account => {
const balance = await web3.eth.getBalance(account)
return [account, `${balance} Wei`, `${toEthString(balance)} Eth`]
}

// https://buidler.dev/guides/create-task.html
task('accounts', 'Prints the list of accounts with their balances', async () => {
const accounts = await web3.eth.getAccounts()
await Promise.all(
accounts.map(async (account, index) => {
console.log([index, ...(await accountBalance(account).catch(err => [account, err.message]))].join('\t'))
})
)
})

task('balance', 'Prints the balance in each account')
.addVariadicPositionalParam('accounts', 'ETH address(es)', undefined, undefined, false)
.setAction(async taskArgs =>
Promise.all(
taskArgs.accounts.map(async (account, index) => {
console.log([index, ...(await accountBalance(account).catch(err => [account, err.message]))].join('\t'))
})
)
)

task('info', 'Prints current network info', async () => {
const getters = {
provider: async () => web3.currentProvider._provider._url,
chainId: web3.eth.getChainId,
networkType: web3.eth.net.getNetworkType,
blockNumber: web3.eth.getBlockNumber,
}

await Promise.all(
Object.entries(getters).map(async ([field, valueGetter]) => {
console.log(`${field}: ${await valueGetter().catch(err => err.message)}`)
})
)
})

task('tx', 'Find and prints the transaction with given txid')
.addPositionalParam('txid', 'Transaction ID', undefined, undefined, false)
.setAction(async taskArgs => {
console.log(await web3.eth.getTransaction(taskArgs.txid))
})

// You have to export an object to set up your config
// This object can have the following optional entries:
// defaultNetwork, networks, solc, and paths.
// Go to https://buidler.dev/config/ to learn more
module.exports = {
defaultNetwork: 'buidlerevm',
solc: {
version: '0.5.12',
optimizer: { enabled: true, runs: 200 },
},
// networks: {
// ropsten: {
// chainId: 3,
// url: 'https://provider-url.somewhere.you.know',
// gasMultiplier: 1.2,
// accounts: {
// mnemonic: 'some mnemonics here if you really want to do use slow ropsten testing',
// path: `m/44'/60'/0'/0`,
// initialIndex: 0,
// count: 4,
// },
// },
// },
}
33 changes: 25 additions & 8 deletions contracts/DaiProxy.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.5.12;

contract ReserveLike {
function depositToken(address, address, uint, address) public;
Expand Down Expand Up @@ -49,7 +49,7 @@ contract VatLike {
}

contract DaiProxy {
string public constant version = "0401";
string public constant version = "0511";

// --- Owner ---
address public owner;
Expand All @@ -67,15 +67,17 @@ contract DaiProxy {
}

// --- State ---
uint public state = 0; // 0 : 시작 전, 1 : 작동 중, 2 : 사망
enum State { Ready, Running, Killed }

State public state = State.Ready;

modifier notStarted {
require(state == 0);
require(state == State.Ready);
_;
}

modifier notPaused {
require(state == 1);
require(state == State.Running);
_;
}

Expand Down Expand Up @@ -153,6 +155,8 @@ contract DaiProxy {
WrappedDaiLike public EDai;
WrappedDaiLike public ODai;

event SetReserve(address reserve);

constructor(address dai, address join, address pot, address vat, address eDai, address oDai) public {
owner = msg.sender;

Expand Down Expand Up @@ -186,6 +190,8 @@ contract DaiProxy {
// approve for Reserve.depositToken
require(EDai.approve(reserve, uint(-1)));
require(ODai.approve(reserve, uint(-1)));

emit SetReserve(reserve);
}

modifier onlyEDai {
Expand Down Expand Up @@ -317,6 +323,10 @@ contract DaiProxy {
// --- Migration ---
DaiProxy public NewProxy;

event SetNewProxy(address proxy);
event StartProxy(address prev);
event KillProxy(address next, bool mig);

modifier onlyNewProxy {
require(msg.sender == address(NewProxy));
_;
Expand All @@ -325,21 +335,24 @@ contract DaiProxy {
// 새로운 프록시가 발행되었음을 알린다
function setNewProxy(address proxy) public onlyOwner {
NewProxy = DaiProxy(proxy);
emit SetNewProxy(proxy);
}

// 프록시의 작동을 완전히 중지하고 돈을 전부 다른 지갑으로 옮긴다
function killProxy(address to) public notPaused onlyOwner {
state = 2;
state = State.Killed;

chi();

Pot.exit(Pot.pie(address(this)));
Join.exit(to, Vat.dai(address(this)) / ONE);

emit KillProxy(to, false);
}

// 새로 생긴 프록시로 자산을 옮긴다.
function migrateProxy() public notPaused onlyNewProxy {
state = 2;
state = State.Killed;

EDai.setProxy(address(NewProxy));
ODai.setProxy(address(NewProxy));
Expand All @@ -348,17 +361,21 @@ contract DaiProxy {

Pot.exit(Pot.pie(address(this)));
Vat.move(address(this), address(NewProxy), Vat.dai(address(this)));

emit KillProxy(address(NewProxy), true);
}

// 프록시를 켠다.
function startProxy(address oldProxy) public notStarted onlyOwner {
state = 1;
state = State.Running;

if (oldProxy != address(0)) {
DaiProxy(oldProxy).migrateProxy();

uint vat = Vat.dai(address(this));
Pot.join(div(vat, chi()));
}

emit StartProxy(oldProxy);
}
}
39 changes: 35 additions & 4 deletions contracts/OrbitDai.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.5.12;

contract ReserveLike {
}
Expand All @@ -9,7 +9,7 @@ contract ProxyLike {
}

contract WrappedDai {
string public constant version = "0327";
string public constant version = "0511";

// --- Owner ---
address public owner;
Expand Down Expand Up @@ -40,6 +40,8 @@ contract WrappedDai {
// --- Proxy ---
ProxyLike public Proxy;

event SetProxy(address proxy);

modifier onlyProxy {
require(msg.sender == address(Proxy));
_;
Expand All @@ -51,20 +53,26 @@ contract WrappedDai {
}

// 최초 발행 시에는 Owner, 그 뒤에는 Proxy가 호출
function setProxy(address _proxy) public onlyOwnerOrProxy {
Proxy = ProxyLike(_proxy);
function setProxy(address proxy) public onlyOwnerOrProxy {
Proxy = ProxyLike(proxy);
emit SetProxy(proxy);
}

// --- Contracts & Constructor ---
ReserveLike public Reserve;
uint public reserveLimit;

event SetReserve(address reserve);
event SetReserveLimit(uint limit);

function setReserve(address reserve) public onlyProxy {
Reserve = ReserveLike(reserve);
emit SetReserve(reserve);
}

function setReserveLimit(uint limit) public onlyOwner {
reserveLimit = limit;
emit SetReserveLimit(limit);
}

constructor() public {
Expand Down Expand Up @@ -104,6 +112,29 @@ contract WrappedDai {
return true;
}

function increaseApproval(address spender, uint amount) public returns (bool) {
amount = add(allowance[msg.sender][spender], amount);

allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);

return true;
}

function decreaseApproval(address spender, uint amount) public returns (bool) {
if (amount > allowance[msg.sender][spender]) {
amount = 0;
}
else {
amount = allowance[msg.sender][spender] - amount;
}

allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);

return true;
}

function mint(address user, uint amount) public onlyProxy {
balanceOf[user] = add(balanceOf[user], amount);
totalSupply = add(totalSupply, amount);
Expand Down
34 changes: 34 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "ethereum-orbit-dai",
"version": "1.0.0",
"private": true,
"description": "Ethereum Orbit Dai",
"repository": "https://github.com/orbit-chain/ethereum-orbit-dai.git",
"license": "UNLICENSED",
"main": "index.js",
"scripts": {
"clean": "buidler clean",
"compile": "buidler compile",
"lint": "prettier -c **/*.js package.json",
"lint:fix": "prettier **/*.js package.json --write",
"test": "buidler test"
},
"prettier": {
"arrowParens": "avoid",
"endOfLine": "lf",
"printWidth": 120,
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false
},
"dependencies": {
"@nomiclabs/buidler": "^1.3.2",
"@nomiclabs/buidler-truffle5": "^1.3.2",
"@nomiclabs/buidler-web3": "^1.3.2",
"prettier": "^2.0.5",
"prettier-plugin-packagejson": "^2.2.3",
"web3": "^1.2.7"
}
}
Loading

0 comments on commit 259c43b

Please sign in to comment.