- 
                Notifications
    You must be signed in to change notification settings 
- Fork 157
Add Orbit token bridge deployer and e2e tests #35
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
Changes from all commits
571eead
              1264253
              ba6306d
              decaefa
              9b1371c
              03424af
              16f6575
              44ec120
              f0f78ff
              77dfa6f
              a071786
              1fd99ff
              51f1995
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -12,3 +12,6 @@ forge-cache/ | |
|  | ||
| #Storage layout test files | ||
| test/storage/*-old.dot | ||
|  | ||
| # local deployment files | ||
| network.json | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,3 +1,7 @@ | ||
| [submodule "lib/forge-std"] | ||
| path = lib/forge-std | ||
| url = https://github.com/foundry-rs/forge-std | ||
| url = https://github.com/foundry-rs/forge-std | ||
| [submodule "lib/nitro-contracts"] | ||
| path = lib/nitro-contracts | ||
| url = git@github.com:OffchainLabs/nitro-contracts.git | ||
| branch = feature-orbit-bridge | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -6,8 +6,10 @@ import "../libraries/aeERC20.sol"; | |
| import "../ethereum/ICustomToken.sol"; | ||
| import "../ethereum/gateway/L1CustomGateway.sol"; | ||
| import "../ethereum/gateway/L1GatewayRouter.sol"; | ||
| import { IERC20Bridge } from "../libraries/IERC20Bridge.sol"; | ||
| import "@openzeppelin/contracts/utils/Context.sol"; | ||
| import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
| import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | ||
|  | ||
| interface IL1CustomGateway { | ||
| function registerTokenToL2( | ||
|  | @@ -19,6 +21,17 @@ interface IL1CustomGateway { | |
| ) external payable returns (uint256); | ||
| } | ||
|  | ||
| interface IL1OrbitCustomGateway { | ||
| function registerTokenToL2( | ||
| address _l2Address, | ||
| uint256 _maxGas, | ||
| uint256 _gasPriceBid, | ||
| uint256 _maxSubmissionCost, | ||
| address _creditBackAddress, | ||
| uint256 _feeAmount | ||
| ) external returns (uint256); | ||
| } | ||
|  | ||
| interface IGatewayRouter2 { | ||
| function setGateway( | ||
| address _gateway, | ||
|  | @@ -29,10 +42,23 @@ interface IGatewayRouter2 { | |
| ) external payable returns (uint256); | ||
| } | ||
|  | ||
| interface IOrbitGatewayRouter { | ||
| function setGateway( | ||
| address _gateway, | ||
| uint256 _maxGas, | ||
| uint256 _gasPriceBid, | ||
| uint256 _maxSubmissionCost, | ||
| address _creditBackAddress, | ||
| uint256 _feeAmount | ||
| ) external returns (uint256); | ||
|  | ||
| function inbox() external returns (address); | ||
| } | ||
|  | ||
| contract TestCustomTokenL1 is aeERC20, ICustomToken { | ||
| address public gateway; | ||
| address public router; | ||
| bool private shouldRegisterGateway; | ||
| bool internal shouldRegisterGateway; | ||
|  | ||
| constructor(address _gateway, address _router) { | ||
| gateway = _gateway; | ||
|  | @@ -52,7 +78,9 @@ contract TestCustomTokenL1 is aeERC20, ICustomToken { | |
| return ERC20Upgradeable.transferFrom(sender, recipient, amount); | ||
| } | ||
|  | ||
| function balanceOf(address account) | ||
| function balanceOf( | ||
| address account | ||
| ) | ||
| public | ||
| view | ||
| virtual | ||
|  | @@ -78,7 +106,7 @@ contract TestCustomTokenL1 is aeERC20, ICustomToken { | |
| uint256 valueForGateway, | ||
| uint256 valueForRouter, | ||
| address creditBackAddress | ||
| ) public payable override { | ||
| ) public payable virtual override { | ||
| // we temporarily set `shouldRegisterGateway` to true for the callback in registerTokenToL2 to succeed | ||
| bool prev = shouldRegisterGateway; | ||
| shouldRegisterGateway = true; | ||
|  | @@ -103,6 +131,72 @@ contract TestCustomTokenL1 is aeERC20, ICustomToken { | |
| } | ||
| } | ||
|  | ||
| contract TestOrbitCustomTokenL1 is TestCustomTokenL1 { | ||
| using SafeERC20 for IERC20; | ||
|  | ||
| constructor(address _gateway, address _router) TestCustomTokenL1(_gateway, _router) {} | ||
|  | ||
| function registerTokenOnL2( | ||
| address l2CustomTokenAddress, | ||
| uint256 maxSubmissionCostForCustomGateway, | ||
| uint256 maxSubmissionCostForRouter, | ||
| uint256 maxGasForCustomGateway, | ||
| uint256 maxGasForRouter, | ||
| uint256 gasPriceBid, | ||
| uint256 valueForGateway, | ||
| uint256 valueForRouter, | ||
| address creditBackAddress | ||
| ) public payable override { | ||
| // we temporarily set `shouldRegisterGateway` to true for the callback in registerTokenToL2 to succeed | ||
| bool prev = shouldRegisterGateway; | ||
| shouldRegisterGateway = true; | ||
|  | ||
| address inbox = IOrbitGatewayRouter(router).inbox(); | ||
| address bridge = address(IInbox(inbox).bridge()); | ||
|  | ||
| // transfer fees from user to here, and approve router to use it | ||
| { | ||
| address nativeToken = IERC20Bridge(bridge).nativeToken(); | ||
|  | ||
| IERC20(nativeToken).safeTransferFrom( | ||
| msg.sender, | ||
| address(this), | ||
| valueForGateway + valueForRouter | ||
| ); | ||
| IERC20(nativeToken).approve(router, valueForRouter); | ||
| 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. All this value gets used right? If it doesnt we should probably set approval to 0 at the end of this func 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. Good point, value is not totally used in case Inbox would for some reason already hold some amount of native tokens. Added re-setting to 0 | ||
| IERC20(nativeToken).approve(gateway, valueForGateway); | ||
| } | ||
|  | ||
| IL1OrbitCustomGateway(gateway).registerTokenToL2( | ||
| l2CustomTokenAddress, | ||
| maxGasForCustomGateway, | ||
| gasPriceBid, | ||
| maxSubmissionCostForCustomGateway, | ||
| creditBackAddress, | ||
| valueForGateway | ||
| ); | ||
|  | ||
| IOrbitGatewayRouter(router).setGateway( | ||
| gateway, | ||
| maxGasForRouter, | ||
| gasPriceBid, | ||
| maxSubmissionCostForRouter, | ||
| creditBackAddress, | ||
| valueForRouter | ||
| ); | ||
|  | ||
| // reset allowance back to 0 in case not all approved native tokens are spent | ||
| { | ||
| address nativeToken = IERC20Bridge(bridge).nativeToken(); | ||
|  | ||
| IERC20(nativeToken).approve(router, 0); | ||
| IERC20(nativeToken).approve(gateway, 0); | ||
| } | ||
|  | ||
| shouldRegisterGateway = prev; | ||
| } | ||
| } | ||
|  | ||
| contract MintableTestCustomTokenL1 is L1MintableToken, TestCustomTokenL1 { | ||
| constructor(address _gateway, address _router) TestCustomTokenL1(_gateway, _router) {} | ||
|  | ||
|  | @@ -111,21 +205,16 @@ contract MintableTestCustomTokenL1 is L1MintableToken, TestCustomTokenL1 { | |
| _; | ||
| } | ||
|  | ||
| function bridgeMint(address account, uint256 amount) | ||
| public | ||
| override(L1MintableToken) | ||
| onlyGateway | ||
| { | ||
| function bridgeMint( | ||
| address account, | ||
| uint256 amount | ||
| ) public override(L1MintableToken) onlyGateway { | ||
| _mint(account, amount); | ||
| } | ||
|  | ||
| function balanceOf(address account) | ||
| public | ||
| view | ||
| virtual | ||
| override(TestCustomTokenL1, ICustomToken) | ||
| returns (uint256 amount) | ||
| { | ||
| function balanceOf( | ||
| address account | ||
| ) public view virtual override(TestCustomTokenL1, ICustomToken) returns (uint256 amount) { | ||
| return super.balanceOf(account); | ||
| } | ||
|  | ||
|  | @@ -141,20 +230,16 @@ contract MintableTestCustomTokenL1 is L1MintableToken, TestCustomTokenL1 { | |
| contract ReverseTestCustomTokenL1 is L1ReverseToken, MintableTestCustomTokenL1 { | ||
| constructor(address _gateway, address _router) MintableTestCustomTokenL1(_gateway, _router) {} | ||
|  | ||
| function bridgeBurn(address account, uint256 amount) | ||
| public | ||
| override(L1ReverseToken) | ||
| onlyGateway | ||
| { | ||
| function bridgeBurn( | ||
| address account, | ||
| uint256 amount | ||
| ) public override(L1ReverseToken) onlyGateway { | ||
| _burn(account, amount); | ||
| } | ||
|  | ||
| function balanceOf(address account) | ||
| public | ||
| view | ||
| override(MintableTestCustomTokenL1, ICustomToken) | ||
| returns (uint256 amount) | ||
| { | ||
| function balanceOf( | ||
| address account | ||
| ) public view override(MintableTestCustomTokenL1, ICustomToken) returns (uint256 amount) { | ||
| return super.balanceOf(account); | ||
| } | ||
|  | ||
|  | ||
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.
Could remove the payable if the compiler allows
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.
Compiler complains:
Error (6959): Overriding function changes state mutability from "payable" to "nonpayable".