Skip to content
This repository has been archived by the owner on Apr 12, 2021. It is now read-only.

Standardized ETH and ERC20 Gateways #222

Merged
merged 58 commits into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
1be2a21
initial
Feb 9, 2021
3d880f6
get .calls test working
Feb 9, 2021
fb4b9e9
add assertions to withdrawal tests
ben-chain Feb 9, 2021
3772799
add missing finalizeDeposit tests
ben-chain Feb 9, 2021
680fa6e
clean up tests
ben-chain Feb 10, 2021
33622bc
clean up crosschain library
ben-chain Feb 10, 2021
6e2bd0a
further clean up tests
ben-chain Feb 10, 2021
732eb8c
clean up L1 Gateway, fix bug
ben-chain Feb 10, 2021
c36e99b
further clean up contracts
ben-chain Feb 10, 2021
68aa686
quick save
maurelian Feb 9, 2021
4bd36b7
quick save
maurelian Feb 10, 2021
5d4865c
Add unsupported to fix compiler bug, need to remove this
maurelian Feb 10, 2021
08e0699
fix constructor inputs
maurelian Feb 10, 2021
c36da5f
build fixes
maurelian Feb 10, 2021
ab92251
improve test case names
maurelian Feb 10, 2021
f408a37
l1 gateway testing WIP
maurelian Feb 10, 2021
a327fa8
add comment on init
maurelian Feb 11, 2021
79a77aa
Add withdraw tests
maurelian Feb 11, 2021
5b95b78
temp only
maurelian Feb 11, 2021
1c8aefa
All tests implemented, 2 still failing, needs polish
maurelian Feb 11, 2021
21dafb6
All tests implemented, 2 still failing, needs polish
maurelian Feb 11, 2021
3f212f1
add failing test for finalizeWithdrawAndCall
maurelian Feb 11, 2021
daf8535
Add univ2erc20, broken build tho
maurelian Feb 11, 2021
e7db192
get contracts building
ben-chain Feb 11, 2021
f10c579
clean up tests and interface
ben-chain Feb 11, 2021
37d910b
updates
ben-chain Feb 12, 2021
26c934f
move to uniswap ERC20
ben-chain Feb 12, 2021
b3f29f9
more updates, fix gateway tests with uniswap
ben-chain Feb 12, 2021
ac41059
finish deploy config?
ben-chain Feb 12, 2021
5fa2a03
Add ETH deposit gateway (OVM_L1ETHGateway) (#225)
gigamesh Feb 13, 2021
73f13dd
clean up unused stuff
ben-chain Feb 13, 2021
5356683
lower gaslimit
ben-chain Feb 14, 2021
c7cd7a8
lower gas further
ben-chain Feb 14, 2021
ab1bd4d
typo
ben-chain Feb 14, 2021
b1d15fc
break out helper
ben-chain Feb 14, 2021
205b745
resolve messenger
ben-chain Feb 14, 2021
ee2f0bf
update deploy config
ben-chain Feb 14, 2021
7f9870f
renaming
ben-chain Feb 16, 2021
429b9bf
lint
ben-chain Feb 19, 2021
9456465
Merge branch 'master' into feat/567/L2Gateway
ben-chain Feb 19, 2021
c479e68
update tests to use AM
ben-chain Feb 19, 2021
7e61864
restructure fs layout
ben-chain Feb 19, 2021
505a8c8
clean unused envar
ben-chain Feb 19, 2021
89b6f36
remove interface version bound
ben-chain Feb 19, 2021
8472594
remove todo
ben-chain Feb 19, 2021
9138a85
various minor cleanups
ben-chain Feb 19, 2021
fa9aba8
add safemath to contract account
ben-chain Feb 19, 2021
7f3e771
update naming conventions
ben-chain Feb 19, 2021
a8a0617
fix test config and test name
ben-chain Feb 19, 2021
83dec33
Merge branch 'master' into feat/567/L2Gateway
ben-chain Feb 19, 2021
bed9788
cleanup for consistency
ben-chain Feb 22, 2021
7ff8ef2
fix eth send test
ben-chain Feb 22, 2021
c2fff09
remove .only
ben-chain Feb 22, 2021
39f14d0
clean up, add deposit gas limit
ben-chain Feb 22, 2021
a86da1d
lint
ben-chain Feb 22, 2021
b0e4d38
add gas config and tests
ben-chain Feb 22, 2021
a3f174b
fix indent
ben-chain Feb 22, 2021
2e0fd63
Merge branch 'master' into feat/567/L2Gateway
ben-chain Feb 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions bin/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,6 @@ const RELAYER_PRIVATE_KEY = env.RELAYER_PRIVATE_KEY;
owner: WHITELIST_OWNER,
allowArbitraryContractDeployment: WHITELIST_ALLOW_ARBITRARY_CONTRACT_DEPLOYMENT
},
ethConfig: {
initialAmount: 0,
},
deployOverrides: {
gasLimit: DEPLOY_TX_GAS_LIMIT
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {

// Transfer fee to relayer.
address relayer = Lib_SafeExecutionManagerWrapper.safeCALLER();
uint256 fee = decodedTx.gasLimit * decodedTx.gasPrice;
uint256 fee = Lib_SafeMathWrapper.mul(decodedTx.gasLimit, decodedTx.gasPrice);
(bool success, ) = Lib_SafeExecutionManagerWrapper.safeCALL(
gasleft(),
ETH_ERC20_ADDRESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2;

/* Interface Imports */
import { iAbs_BaseCrossDomainMessenger } from "../../iOVM/bridge/iAbs_BaseCrossDomainMessenger.sol";
import { iAbs_BaseCrossDomainMessenger } from "../../../iOVM/bridge/messenging/iAbs_BaseCrossDomainMessenger.sol";

/* Library Imports */
import { Lib_ReentrancyGuard } from "../../libraries/utils/Lib_ReentrancyGuard.sol";
import { Lib_ReentrancyGuard } from "../../../libraries/utils/Lib_ReentrancyGuard.sol";

/**
* @title Abs_BaseCrossDomainMessenger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2;

/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_AddressManager } from "../../libraries/resolver/Lib_AddressManager.sol";
import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol";
import { Lib_ReentrancyGuard } from "../../libraries/utils/Lib_ReentrancyGuard.sol";
import { Lib_OVMCodec } from "../../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_AddressManager } from "../../../libraries/resolver/Lib_AddressManager.sol";
import { Lib_SecureMerkleTrie } from "../../../libraries/trie/Lib_SecureMerkleTrie.sol";
import { Lib_ReentrancyGuard } from "../../../libraries/utils/Lib_ReentrancyGuard.sol";

/* Interface Imports */
import { iOVM_L1CrossDomainMessenger } from "../../iOVM/bridge/iOVM_L1CrossDomainMessenger.sol";
import { iOVM_CanonicalTransactionChain } from "../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_StateCommitmentChain } from "../../iOVM/chain/iOVM_StateCommitmentChain.sol";
import { iOVM_L1CrossDomainMessenger } from "../../../iOVM/bridge/messenging/iOVM_L1CrossDomainMessenger.sol";
import { iOVM_CanonicalTransactionChain } from "../../../iOVM/chain/iOVM_CanonicalTransactionChain.sol";
import { iOVM_StateCommitmentChain } from "../../../iOVM/chain/iOVM_StateCommitmentChain.sol";

/* Contract Imports */
import { Abs_BaseCrossDomainMessenger } from "./Abs_BaseCrossDomainMessenger.sol";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_L1CrossDomainMessenger } from "../../iOVM/bridge/iOVM_L1CrossDomainMessenger.sol";
import { iOVM_L1MultiMessageRelayer } from "../../iOVM/bridge/iOVM_L1MultiMessageRelayer.sol";
import { iOVM_L1CrossDomainMessenger } from "../../../iOVM/bridge/messenging/iOVM_L1CrossDomainMessenger.sol";
import { iOVM_L1MultiMessageRelayer } from "../../../iOVM/bridge/messenging/iOVM_L1MultiMessageRelayer.sol";

/* Contract Imports */
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol";


/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2;

/* Library Imports */
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_ReentrancyGuard } from "../../libraries/utils/Lib_ReentrancyGuard.sol";
import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_ReentrancyGuard } from "../../../libraries/utils/Lib_ReentrancyGuard.sol";

/* Interface Imports */
import { iOVM_L2CrossDomainMessenger } from "../../iOVM/bridge/iOVM_L2CrossDomainMessenger.sol";
import { iOVM_L1MessageSender } from "../../iOVM/precompiles/iOVM_L1MessageSender.sol";
import { iOVM_L2ToL1MessagePasser } from "../../iOVM/precompiles/iOVM_L2ToL1MessagePasser.sol";
import { iOVM_L2CrossDomainMessenger } from "../../../iOVM/bridge/messenging/iOVM_L2CrossDomainMessenger.sol";
import { iOVM_L1MessageSender } from "../../../iOVM/precompiles/iOVM_L1MessageSender.sol";
import { iOVM_L2ToL1MessagePasser } from "../../../iOVM/precompiles/iOVM_L2ToL1MessagePasser.sol";

/* Contract Imports */
import { Abs_BaseCrossDomainMessenger } from "./Abs_BaseCrossDomainMessenger.sol";
Expand Down
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 contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ETHGateway.sol
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);
}
ben-chain marked this conversation as resolved.
Show resolved Hide resolved

/**
* @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');
}
ben-chain marked this conversation as resolved.
Show resolved Hide resolved

/**
* @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()");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this receive(..) function supposed to be empty?

}
Loading