This repository has been archived by the owner on Apr 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Standardized ETH and ERC20 Gateways (#222)
* initial * get .calls test working * add assertions to withdrawal tests * add missing finalizeDeposit tests * clean up tests * clean up crosschain library * further clean up tests * clean up L1 Gateway, fix bug * further clean up contracts * quick save * quick save * Add unsupported to fix compiler bug, need to remove this * fix constructor inputs * build fixes * improve test case names * l1 gateway testing WIP * add comment on init * Add withdraw tests * temp only * All tests implemented, 2 still failing, needs polish * All tests implemented, 2 still failing, needs polish * add failing test for finalizeWithdrawAndCall * Add univ2erc20, broken build tho * get contracts building * clean up tests and interface * updates * move to uniswap ERC20 * more updates, fix gateway tests with uniswap * finish deploy config? * Add ETH deposit gateway (OVM_L1ETHGateway) (#225) * OVM_L1ETHGateway almost working * OVM_L1ETHGateway tests all passing * clean up unused stuff * lower gaslimit * lower gas further * typo * break out helper * resolve messenger * update deploy config * renaming * lint * update tests to use AM * restructure fs layout * clean unused envar * remove interface version bound * remove todo * various minor cleanups * add safemath to contract account * update naming conventions * fix test config and test name * cleanup for consistency * fix eth send test * remove .only * clean up, add deposit gas limit * lint * add gas config and tests * fix indent Co-authored-by: ben <[email protected]> Co-authored-by: Maurelian <[email protected]> Co-authored-by: Matt Masurka <[email protected]>
- Loading branch information
1 parent
5516771
commit 1b26510
Showing
32 changed files
with
1,612 additions
and
156 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
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
146 changes: 146 additions & 0 deletions
146
contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ERC20Gateway.sol
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,146 @@ | ||
// SPDX-License-Identifier: MIT | ||
// @unsupported: ovm | ||
pragma solidity >0.5.0 <0.8.0; | ||
pragma experimental ABIEncoderV2; | ||
|
||
/* Interface Imports */ | ||
import { iOVM_L1ERC20Gateway } from "../../../iOVM/bridge/tokens/iOVM_L1ERC20Gateway.sol"; | ||
import { iOVM_L2DepositedERC20 } from "../../../iOVM/bridge/tokens/iOVM_L2DepositedERC20.sol"; | ||
import { iOVM_ERC20 } from "../../../iOVM/precompiles/iOVM_ERC20.sol"; | ||
|
||
/* Library Imports */ | ||
import { OVM_CrossDomainEnabled } from "../../../libraries/bridge/OVM_CrossDomainEnabled.sol"; | ||
|
||
/** | ||
* @title OVM_L1ERC20Gateway | ||
* @dev The L1 ERC20 Gateway is a contract which stores deposited L1 funds that are in use on L2. | ||
* It synchronizes a corresponding L2 ERC20 Gateway, informing it of deposits, and listening to it | ||
* for newly finalized withdrawals. | ||
* | ||
* Compiler used: solc | ||
* Runtime target: EVM | ||
*/ | ||
contract OVM_L1ERC20Gateway is iOVM_L1ERC20Gateway, OVM_CrossDomainEnabled { | ||
|
||
/******************************** | ||
* External Contract References * | ||
********************************/ | ||
|
||
iOVM_ERC20 public l1ERC20; | ||
address public l2ERC20Gateway; | ||
|
||
/*************** | ||
* Constructor * | ||
***************/ | ||
|
||
/** | ||
* @param _l1ERC20 L1 ERC20 address this contract stores deposits for | ||
* @param _l2ERC20Gateway L2 Gateway address on the chain being deposited into | ||
* @param _l1messenger L1 Messenger address being used for cross-chain communications. | ||
*/ | ||
constructor( | ||
iOVM_ERC20 _l1ERC20, | ||
address _l2ERC20Gateway, | ||
address _l1messenger | ||
) | ||
OVM_CrossDomainEnabled(_l1messenger) | ||
{ | ||
l1ERC20 = _l1ERC20; | ||
l2ERC20Gateway = _l2ERC20Gateway; | ||
} | ||
|
||
/************** | ||
* Depositing * | ||
**************/ | ||
|
||
/** | ||
* @dev deposit an amount of the ERC20 to the caller's balance on L2 | ||
* @param _amount Amount of the ERC20 to deposit | ||
*/ | ||
function deposit( | ||
uint _amount | ||
) | ||
external | ||
override | ||
{ | ||
_initiateDeposit(msg.sender, msg.sender, _amount); | ||
} | ||
|
||
/** | ||
* @dev deposit an amount of ERC20 to a recipients's balance on L2 | ||
* @param _to L2 address to credit the withdrawal to | ||
* @param _amount Amount of the ERC20 to deposit | ||
*/ | ||
function depositTo( | ||
address _to, | ||
uint _amount | ||
) | ||
external | ||
override | ||
{ | ||
_initiateDeposit(msg.sender, _to, _amount); | ||
} | ||
|
||
/** | ||
* @dev Performs the logic for deposits by storing the ERC20 and informing the L2 ERC20 Gateway of the deposit. | ||
* | ||
* @param _from Account to pull the deposit from on L1 | ||
* @param _to Account to give the deposit to on L2 | ||
* @param _amount Amount of the ERC20 to deposit. | ||
*/ | ||
function _initiateDeposit( | ||
address _from, | ||
address _to, | ||
uint _amount | ||
) | ||
internal | ||
{ | ||
// Hold on to the newly deposited funds | ||
l1ERC20.transferFrom( | ||
_from, | ||
address(this), | ||
_amount | ||
); | ||
|
||
// Construct calldata for l2ERC20Gateway.finalizeDeposit(_to, _amount) | ||
bytes memory data = abi.encodeWithSelector( | ||
iOVM_L2DepositedERC20.finalizeDeposit.selector, | ||
_to, | ||
_amount | ||
); | ||
|
||
// Send calldata into L2 | ||
sendCrossDomainMessage( | ||
l2ERC20Gateway, | ||
data, | ||
DEFAULT_FINALIZE_DEPOSIT_L2_GAS | ||
); | ||
|
||
emit DepositInitiated(_from, _to, _amount); | ||
} | ||
|
||
/************************************* | ||
* Cross-chain Function: Withdrawing * | ||
*************************************/ | ||
|
||
/** | ||
* @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the | ||
* L1 ERC20 token. | ||
* This call will fail if the initialized withdrawal from L2 has not been finalized. | ||
* | ||
* @param _to L1 address to credit the withdrawal to | ||
* @param _amount Amount of the ERC20 to withdraw | ||
*/ | ||
function finalizeWithdrawal( | ||
address _to, | ||
uint _amount | ||
) | ||
external | ||
override | ||
onlyFromCrossDomainAccount(l2ERC20Gateway) | ||
{ | ||
l1ERC20.transfer(_to, _amount); | ||
|
||
emit WithdrawalFinalized(_to, _amount); | ||
} | ||
} |
160 changes: 160 additions & 0 deletions
160
contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ETHGateway.sol
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,160 @@ | ||
// SPDX-License-Identifier: MIT | ||
// @unsupported: ovm | ||
pragma solidity >0.5.0 <0.8.0; | ||
pragma experimental ABIEncoderV2; | ||
|
||
/* Interface Imports */ | ||
import { iOVM_L1ETHGateway } from "../../../iOVM/bridge/tokens/iOVM_L1ETHGateway.sol"; | ||
import { iOVM_L2DepositedERC20 } from "../../../iOVM/bridge/tokens/iOVM_L2DepositedERC20.sol"; | ||
import { iOVM_ERC20 } from "../../../iOVM/precompiles/iOVM_ERC20.sol"; | ||
|
||
/* Library Imports */ | ||
import { OVM_CrossDomainEnabled } from "../../../libraries/bridge/OVM_CrossDomainEnabled.sol"; | ||
import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol"; | ||
|
||
/** | ||
* @title OVM_L1ETHGateway | ||
* @dev The L1 ETH Gateway is a contract which stores deposited ETH that is in use on L2. | ||
* | ||
* Compiler used: solc | ||
* Runtime target: EVM | ||
*/ | ||
contract OVM_L1ETHGateway is iOVM_L1ETHGateway, OVM_CrossDomainEnabled, Lib_AddressResolver { | ||
/******************************** | ||
* External Contract References * | ||
********************************/ | ||
|
||
address public l2ERC20Gateway; | ||
|
||
/*************** | ||
* Constructor * | ||
***************/ | ||
|
||
/** | ||
* @param _libAddressManager Address manager for this OE deployment | ||
*/ | ||
constructor( | ||
address _libAddressManager, | ||
address _l2ERC20Gateway | ||
) | ||
OVM_CrossDomainEnabled(address(0)) // overridden in constructor code | ||
Lib_AddressResolver(_libAddressManager) | ||
{ | ||
l2ERC20Gateway = _l2ERC20Gateway; | ||
messenger = resolve("Proxy__OVM_L1CrossDomainMessenger"); // overrides OVM_CrossDomainEnabled constructor setting because resolve() is not yet accessible | ||
} | ||
|
||
/************** | ||
* Depositing * | ||
**************/ | ||
|
||
/** | ||
* @dev deposit an amount of the ERC20 to the caller's balance on L2 | ||
*/ | ||
function deposit() | ||
external | ||
override | ||
payable | ||
{ | ||
_initiateDeposit(msg.sender, msg.sender); | ||
} | ||
|
||
/** | ||
* @dev deposit an amount of ERC20 to a recipients's balance on L2 | ||
* @param _to L2 address to credit the withdrawal to | ||
*/ | ||
function depositTo( | ||
address _to | ||
) | ||
external | ||
override | ||
payable | ||
{ | ||
_initiateDeposit(msg.sender, _to); | ||
} | ||
|
||
/** | ||
* @dev Performs the logic for deposits by storing the ERC20 and informing the L2 ERC20 Gateway of the deposit. | ||
* | ||
* @param _from Account to pull the deposit from on L1 | ||
* @param _to Account to give the deposit to on L2 | ||
*/ | ||
function _initiateDeposit( | ||
address _from, | ||
address _to | ||
) | ||
internal | ||
{ | ||
// Construct calldata for l2ERC20Gateway.finalizeDeposit(_to, _amount) | ||
bytes memory data = | ||
abi.encodeWithSelector( | ||
iOVM_L2DepositedERC20.finalizeDeposit.selector, | ||
_to, | ||
msg.value | ||
); | ||
|
||
// Send calldata into L2 | ||
sendCrossDomainMessage( | ||
l2ERC20Gateway, | ||
data, | ||
DEFAULT_FINALIZE_DEPOSIT_L2_GAS | ||
); | ||
|
||
emit DepositInitiated(_from, _to, msg.value); | ||
} | ||
|
||
/************************* | ||
* Cross-chain Functions * | ||
*************************/ | ||
|
||
/** | ||
* @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the | ||
* L1 ERC20 token. | ||
* This call will fail if the initialized withdrawal from L2 has not been finalized. | ||
* | ||
* @param _to L1 address to credit the withdrawal to | ||
* @param _amount Amount of the ERC20 to withdraw | ||
*/ | ||
function finalizeWithdrawal( | ||
address _to, | ||
uint256 _amount | ||
) | ||
external | ||
override | ||
onlyFromCrossDomainAccount(l2ERC20Gateway) | ||
{ | ||
_safeTransferETH(_to, _amount); | ||
|
||
emit WithdrawalFinalized(_to, _amount); | ||
} | ||
|
||
/********************************** | ||
* Internal Functions: Accounting * | ||
**********************************/ | ||
|
||
/** | ||
* @dev Internal accounting function for moving around L1 ETH. | ||
* | ||
* @param _to L1 address to transfer ETH to | ||
* @param _value Amount of ETH to send to | ||
*/ | ||
function _safeTransferETH( | ||
address _to, | ||
uint256 _value | ||
) | ||
internal | ||
{ | ||
(bool success, ) = _to.call{value: _value}(new bytes(0)); | ||
require(success, 'TransferHelper::safeTransferETH: ETH transfer failed'); | ||
} | ||
|
||
/** | ||
* @dev Prevent users from sending ETH directly to this contract without calling deposit | ||
*/ | ||
receive() | ||
external | ||
payable | ||
{ | ||
revert("Deposits must be initiated via deposit() or depositTo()"); | ||
} | ||
} |
Oops, something went wrong.