-
Notifications
You must be signed in to change notification settings - Fork 222
Add support for two tokens in erc to native #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 6 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
b9cff12
Add support for two tokens in erc to native
patitonar e29e78f
minor fixes
patitonar 71e62eb
Add first part of unit tests
patitonar 7fdac53
fix test
patitonar ede2c50
fix coverage test
patitonar 94b2a85
Add pending unit tests
patitonar 360dcaa
Update migrateToMCD
patitonar 055bcb6
Fix onExecuteMessage
patitonar be3cd33
Update bridge validators interfaces version
patitonar c2c2c4c
Update bridge interfaces version
patitonar 251f949
Remove onlyOwner modifier from migrateToMCD method
patitonar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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,20 @@ | ||
| pragma solidity 0.4.24; | ||
|
|
||
| import "../upgradeable_contracts/erc20_to_native/ForeignBridgeErcToNative.sol"; | ||
|
|
||
| contract ForeignBridgeErcToNativeMock is ForeignBridgeErcToNative { | ||
| function migrationContract() internal pure returns (IScdMcdMigration) { | ||
| // Address generated in unit test | ||
| return IScdMcdMigration(0x44Bf5539DAAc4259f7F11A24280255ED2Fa3F7BF); | ||
| } | ||
|
|
||
| function halfDuplexErc20token() public pure returns (ERC20) { | ||
| // Address generated in unit test | ||
| return ERC20(0x872D709De609c391741c7595F0053F6060e59e0D); | ||
| } | ||
|
|
||
| function saiTopContract() internal pure returns (ISaiTop) { | ||
| // Address generated in unit test | ||
| return ISaiTop(0x96bc48adACdB60E6536E55a6727919a397F14540); | ||
| } | ||
| } |
This file contains hidden or 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,9 @@ | ||
| pragma solidity 0.4.24; | ||
|
|
||
| contract SaiTopMock { | ||
| uint256 public caged; | ||
|
|
||
| function setCaged(uint256 _value) public { | ||
| caged = _value; | ||
| } | ||
| } |
This file contains hidden or 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 hidden or 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 |
|---|---|---|
|
|
@@ -8,6 +8,9 @@ import "../../interfaces/IScdMcdMigration.sol"; | |
| contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideBridgeStorage { | ||
| event TokensSwapped(address indexed from, address indexed to, uint256 value); | ||
|
|
||
| bytes32 internal constant MIN_HDTOKEN_BALANCE = 0x48649cf195feb695632309f41e61252b09f537943654bde13eb7bb1bca06964e; // keccak256(abi.encodePacked("minHDTokenBalance")) | ||
| bytes4 internal constant SWAP_TOKENS = 0x73d00224; // swapTokens() | ||
|
|
||
| function initialize( | ||
| address _validatorContract, | ||
| address _erc20token, | ||
|
|
@@ -61,6 +64,11 @@ contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideB | |
|
|
||
| function claimTokens(address _token, address _to) public { | ||
| require(_token != address(erc20token())); | ||
| if (_token == address(halfDuplexErc20token())) { | ||
| // SCD is not claimable if the bridge accepts deposits of this token | ||
| // solhint-disable-next-line not-rely-on-time | ||
| require(!isTokenSwapAllowed(now)); | ||
| } | ||
| super.claimTokens(_token, _to); | ||
| } | ||
|
|
||
|
|
@@ -71,7 +79,13 @@ contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideB | |
| ) internal returns (bool) { | ||
| setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(_amount)); | ||
| uint256 amount = _amount.div(10**decimalShift()); | ||
| return erc20token().transfer(_recipient, amount); | ||
| bool res = erc20token().transfer(_recipient, amount); | ||
|
|
||
| if (AddressUtils.isContract(halfDuplexErc20token()) && tokenBalance(halfDuplexErc20token()) > 0) { | ||
akolotov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| address(this).call(abi.encodeWithSelector(SWAP_TOKENS)); | ||
| } | ||
|
|
||
| return res; | ||
| } | ||
|
|
||
| function onFailedMessage(address, uint256, bytes32) internal { | ||
|
|
@@ -102,4 +116,100 @@ contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideB | |
| emit TokensSwapped(saiContract, erc20token(), curBalance); | ||
| boolStorage[storageAddress] = true; | ||
| } | ||
|
|
||
| function saiTopContract() internal pure returns (ISaiTop) { | ||
| return ISaiTop(0x9b0ccf7C8994E19F39b2B4CF708e0A7DF65fA8a3); | ||
| } | ||
|
|
||
| function isTokenSwapAllowed(uint256 _ts) public view returns (bool) { | ||
| uint256 esTs = saiTopContract().caged(); | ||
| if (esTs > 0 && _ts > esTs) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| function halfDuplexErc20token() public pure returns (ERC20) { | ||
| return ERC20(0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359); | ||
| } | ||
|
|
||
| function setMinHDTokenBalance(uint256 _minBalance) external onlyOwner { | ||
akolotov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| uintStorage[MIN_HDTOKEN_BALANCE] = _minBalance; | ||
| } | ||
|
|
||
| function minHDTokenBalance() public view returns (uint256) { | ||
| return uintStorage[MIN_HDTOKEN_BALANCE]; | ||
| } | ||
|
|
||
| function isHDTokenBalanceAboveMinBalance() public view returns (bool) { | ||
| if (tokenBalance(halfDuplexErc20token()) > minHDTokenBalance()) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| function tokenBalance(ERC20 _token) internal view returns (uint256) { | ||
| return _token.balanceOf(address(this)); | ||
| } | ||
|
|
||
| function migrationContract() internal pure returns (IScdMcdMigration) { | ||
akolotov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return IScdMcdMigration(0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849); | ||
| } | ||
|
|
||
| function swapTokens() public { | ||
akolotov marked this conversation as resolved.
Show resolved
Hide resolved
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we increase the version returned by
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it makes sense. Updated to |
||
| // solhint-disable-next-line not-rely-on-time | ||
| require(isTokenSwapAllowed(now)); | ||
|
|
||
| IScdMcdMigration mcdMigrationContract = migrationContract(); | ||
| ERC20 hdToken = halfDuplexErc20token(); | ||
| ERC20 fdToken = erc20token(); | ||
|
|
||
| uint256 curHDTokenBalance = tokenBalance(hdToken); | ||
| require(curHDTokenBalance > 0); | ||
|
|
||
| uint256 curFDTokenBalance = tokenBalance(fdToken); | ||
|
|
||
| require(hdToken.approve(mcdMigrationContract, curHDTokenBalance)); | ||
| mcdMigrationContract.swapSaiToDai(curHDTokenBalance); | ||
|
|
||
| require(tokenBalance(fdToken).sub(curFDTokenBalance) == curHDTokenBalance); | ||
|
|
||
| emit TokensSwapped(hdToken, fdToken, curHDTokenBalance); | ||
| } | ||
|
|
||
| function relayTokens(address _from, address _receiver, uint256 _amount, address _token) external { | ||
| require(_from == msg.sender || _from == _receiver); | ||
| _relayTokens(_from, _receiver, _amount, _token); | ||
| } | ||
|
|
||
| function relayTokens(address _receiver, uint256 _amount, address _token) external { | ||
| _relayTokens(msg.sender, _receiver, _amount, _token); | ||
| } | ||
|
|
||
| function _relayTokens(address _sender, address _receiver, uint256 _amount, address _token) internal { | ||
| require(_receiver != bridgeContractOnOtherSide()); | ||
| require(_receiver != address(0)); | ||
| require(_receiver != address(this)); | ||
| require(_amount > 0); | ||
| require(withinLimit(_amount)); | ||
|
|
||
| ERC20 tokenToOperate = ERC20(_token); | ||
| ERC20 hdToken = halfDuplexErc20token(); | ||
| ERC20 fdToken = erc20token(); | ||
|
|
||
| if (tokenToOperate == ERC20(0x0)) { | ||
| tokenToOperate = fdToken; | ||
| } | ||
|
|
||
| require(tokenToOperate == fdToken || tokenToOperate == hdToken); | ||
|
|
||
| setTotalSpentPerDay(getCurrentDay(), totalSpentPerDay(getCurrentDay()).add(_amount)); | ||
|
|
||
| tokenToOperate.transferFrom(_sender, address(this), _amount); | ||
| emit UserRequestForAffirmation(_receiver, _amount); | ||
|
|
||
| if (tokenToOperate == hdToken) { | ||
| swapTokens(); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or 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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we increase a version in
getBridgeValidatorsInterfacesVersion?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should. Updated version to
2.3.0be3cd33