-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Paying interest in chai to avoid the oracle misbehavior (#380)
- Loading branch information
1 parent
4ffda3a
commit c073e83
Showing
18 changed files
with
373 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,51 @@ | ||
pragma solidity 0.4.24; | ||
|
||
contract GemLike { | ||
function mint(address, uint256) external returns (bool); | ||
function transferFrom(address, address, uint256) external returns (bool); | ||
} | ||
|
||
/** | ||
* @title ChaiMock2 | ||
* @dev This contract is used for e2e tests only, | ||
* bridge contract requires non-empty chai stub with correct daiToken value and possibility to call join | ||
* this mock represents a simplified version of Chai, which does not require other MakerDAO contracts to be deployed in e2e tests | ||
*/ | ||
contract ChaiMock2 { | ||
event Transfer(address indexed src, address indexed dst, uint256 wad); | ||
|
||
GemLike public daiToken; | ||
uint256 internal daiBalance; | ||
address public pot; | ||
|
||
// wad is denominated in dai | ||
function join(address, uint256 wad) external { | ||
daiToken.transferFrom(msg.sender, address(this), wad); | ||
daiBalance += wad; | ||
} | ||
|
||
function transfer(address to, uint256 wad) external { | ||
require(daiBalance >= wad); | ||
daiBalance -= wad; | ||
emit Transfer(msg.sender, to, wad); | ||
} | ||
|
||
function exit(address, uint256 wad) external { | ||
require(daiBalance >= wad); | ||
daiBalance -= wad; | ||
daiToken.mint(msg.sender, wad); | ||
} | ||
|
||
function draw(address, uint256 wad) external { | ||
require(daiBalance >= wad); | ||
daiBalance -= wad; | ||
daiToken.mint(msg.sender, wad); | ||
} | ||
|
||
function dai(address) external view returns (uint256) { | ||
return daiBalance; | ||
} | ||
|
||
function balanceOf(address) external view returns (uint256) { | ||
return daiBalance; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../upgradeable_contracts/InterestReceiver.sol"; | ||
|
||
contract InterestReceiverMock is InterestReceiver { | ||
bytes32 internal constant CHAI_TOKEN_MOCK = 0x5d6f4e61a116947624416975e8d26d4aff8f32e21ea6308dfa35cee98ed41fd8; // keccak256(abi.encodePacked("chaiTokenMock")) | ||
bytes32 internal constant DAI_TOKEN_MOCK = 0xbadb505d38473a045eb3ce02f80bb0c4b30c429923cd667bca7f33083bad4e14; // keccak256(abi.encodePacked("daiTokenMock")) | ||
|
||
function setChaiToken(IChai _chaiToken) external { | ||
addressStorage[CHAI_TOKEN_MOCK] = _chaiToken; | ||
addressStorage[DAI_TOKEN_MOCK] = _chaiToken.daiToken(); | ||
} | ||
|
||
function chaiToken() public view returns (IChai) { | ||
return IChai(addressStorage[CHAI_TOKEN_MOCK]); | ||
} | ||
|
||
function daiToken() public view returns (ERC20) { | ||
return ERC20(addressStorage[DAI_TOKEN_MOCK]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
pragma solidity 0.4.24; | ||
|
||
contract GemLike { | ||
function transfer(address, uint256) external returns (bool); | ||
function transferFrom(address, address, uint256) external returns (bool); | ||
} | ||
|
||
/** | ||
* @title PotMock2 | ||
* @dev This contract is used for e2e tests only | ||
*/ | ||
contract PotMock2 { | ||
// solhint-disable const-name-snakecase | ||
uint256 public constant dsr = 10**27; // the Dai Savings Rate | ||
uint256 public constant chi = 10**27; // the Rate Accumulator | ||
uint256 public constant rho = 10**27; // time of last drip | ||
// solhint-enable const-name-snakecase | ||
|
||
function drip() external returns (uint256) { | ||
return chi; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; | ||
import "../interfaces/IChai.sol"; | ||
import "../interfaces/ERC677Receiver.sol"; | ||
import "./Initializable.sol"; | ||
import "./Ownable.sol"; | ||
import "./Claimable.sol"; | ||
import "./TokenSwapper.sol"; | ||
|
||
/** | ||
* @title InterestReceiver | ||
* @dev Example contract for receiving Chai interest and immediatly converting it into Dai | ||
*/ | ||
contract InterestReceiver is ERC677Receiver, Initializable, Ownable, Claimable, TokenSwapper { | ||
/** | ||
* @dev Initializes interest receiver, sets an owner of a contract | ||
* @param _owner address of owner account, only owner can withdraw Dai tokens from contract | ||
*/ | ||
function initialize(address _owner) external onlyRelevantSender { | ||
require(!isInitialized()); | ||
setOwner(_owner); | ||
setInitialize(); | ||
} | ||
|
||
/** | ||
* @return Chai token contract address | ||
*/ | ||
function chaiToken() public view returns (IChai) { | ||
return IChai(0x06AF07097C9Eeb7fD685c692751D5C66dB49c215); | ||
} | ||
|
||
/** | ||
* @return Dai token contract address | ||
*/ | ||
function daiToken() public view returns (ERC20) { | ||
return ERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); | ||
} | ||
|
||
/** | ||
* @dev ERC677 transfer callback function, received interest from Chai token is converted into Dai and sent to owner | ||
* @param _value amount of transferred tokens | ||
*/ | ||
function onTokenTransfer(address, uint256 _value, bytes) external returns (bool) { | ||
require(isInitialized()); | ||
|
||
uint256 chaiBalance = chaiToken().balanceOf(address(this)); | ||
|
||
require(_value <= chaiBalance); | ||
|
||
uint256 initialDaiBalance = daiToken().balanceOf(address(this)); | ||
|
||
chaiToken().exit(address(this), chaiBalance); | ||
|
||
// Dai balance cannot decrease here, so SafeMath is not needed | ||
uint256 redeemed = daiToken().balanceOf(address(this)) - initialDaiBalance; | ||
|
||
emit TokensSwapped(chaiToken(), daiToken(), redeemed); | ||
|
||
// chi is always >= 10**27, so chai/dai rate is always >= 1 | ||
require(redeemed >= _value); | ||
} | ||
|
||
/** | ||
* @dev Withdraws DAI tokens from the receiver contract | ||
* @param _to address of tokens receiver | ||
*/ | ||
function withdraw(address _to) external onlyOwner { | ||
require(isInitialized()); | ||
|
||
daiToken().transfer(_to, daiToken().balanceOf(address(this))); | ||
} | ||
|
||
/** | ||
* @dev Claims tokens from receiver account | ||
* @param _token address of claimed token, address(0) for native | ||
* @param _to address of tokens receiver | ||
*/ | ||
function claimTokens(address _token, address _to) external onlyOwner validAddress(_to) { | ||
require(_token != address(chaiToken()) && _token != address(daiToken())); | ||
claimValues(_token, _to); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
pragma solidity 0.4.24; | ||
|
||
contract TokenSwapper { | ||
// emitted when two tokens is swapped (e. g. Sai to Dai, Chai to Dai) | ||
event TokensSwapped(address indexed from, address indexed to, uint256 value); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.