Commit 927e68d1 authored by Kevin Ho's avatar Kevin Ho Committed by GitHub

Add OVM_L1ETHGateway Proxy (#358)

* add OVM_L1ETHGateway Proxy

* fix contract build

* pass tests with new initialize test, lint

* make delegate proxy payable

* remove now-inaccurate comment
Co-authored-by: default avatarBen Jones <ben@pseudonym.party>
Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
parent ac5482d0
...@@ -10,6 +10,7 @@ import { iOVM_L2DepositedToken } from "../../../iOVM/bridge/tokens/iOVM_L2Deposi ...@@ -10,6 +10,7 @@ import { iOVM_L2DepositedToken } from "../../../iOVM/bridge/tokens/iOVM_L2Deposi
/* Library Imports */ /* Library Imports */
import { OVM_CrossDomainEnabled } from "../../../libraries/bridge/OVM_CrossDomainEnabled.sol"; import { OVM_CrossDomainEnabled } from "../../../libraries/bridge/OVM_CrossDomainEnabled.sol";
import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol"; import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_AddressManager } from "../../../libraries/resolver/Lib_AddressManager.sol";
/** /**
* @title OVM_L1ETHGateway * @title OVM_L1ETHGateway
...@@ -36,19 +37,31 @@ contract OVM_L1ETHGateway is iOVM_L1ETHGateway, OVM_CrossDomainEnabled, Lib_Addr ...@@ -36,19 +37,31 @@ contract OVM_L1ETHGateway is iOVM_L1ETHGateway, OVM_CrossDomainEnabled, Lib_Addr
* Constructor * * Constructor *
***************/ ***************/
// This contract lives behind a proxy, so the constructor parameters will go unused.
constructor()
OVM_CrossDomainEnabled(address(0))
Lib_AddressResolver(address(0))
public
{}
/******************
* Initialization *
******************/
/** /**
* @param _libAddressManager Address manager for this OE deployment * @param _libAddressManager Address manager for this OE deployment
* @param _ovmEth L2 OVM_ETH implementation of iOVM_DepositedToken * @param _ovmEth L2 OVM_ETH implementation of iOVM_DepositedToken
*/ */
constructor( function initialize(
address _libAddressManager, address _libAddressManager,
address _ovmEth address _ovmEth
) )
OVM_CrossDomainEnabled(address(0)) // overridden in constructor code public
Lib_AddressResolver(_libAddressManager)
{ {
require(libAddressManager == Lib_AddressManager(0), "Contract has already been initialized.");
libAddressManager = Lib_AddressManager(_libAddressManager);
ovmEth = _ovmEth; ovmEth = _ovmEth;
messenger = resolve("Proxy__OVM_L1CrossDomainMessenger"); // overrides OVM_CrossDomainEnabled constructor setting because resolve() is not yet accessible messenger = resolve("Proxy__OVM_L1CrossDomainMessenger");
} }
/************** /**************
......
...@@ -50,6 +50,7 @@ contract Lib_ResolvedDelegateProxy { ...@@ -50,6 +50,7 @@ contract Lib_ResolvedDelegateProxy {
fallback() fallback()
external external
payable
{ {
address target = addressManager[address(this)].getAddress((implementationName[address(this)])); address target = addressManager[address(this)].getAddress((implementationName[address(this)]));
require( require(
......
...@@ -109,10 +109,23 @@ export const makeContractDeployConfig = async ( ...@@ -109,10 +109,23 @@ export const makeContractDeployConfig = async (
}, },
OVM_L1ETHGateway: { OVM_L1ETHGateway: {
factory: getContractFactory('OVM_L1ETHGateway'), factory: getContractFactory('OVM_L1ETHGateway'),
params: [ params: [],
AddressManager.address, },
'0x4200000000000000000000000000000000000006', Proxy__OVM_L1ETHGateway: {
], factory: getContractFactory('Lib_ResolvedDelegateProxy'),
params: [AddressManager.address, 'OVM_L1ETHGateway'],
afterDeploy: async (contracts): Promise<void> => {
const l1EthGateway = getContractFactory('OVM_L1ETHGateway')
.connect(config.deploymentSigner)
.attach(contracts.Proxy__OVM_L1ETHGateway.address)
await _sendTx(
l1EthGateway.initialize(
AddressManager.address,
'0x4200000000000000000000000000000000000006',
config.deployOverrides
)
)
},
}, },
OVM_L1MultiMessageRelayer: { OVM_L1MultiMessageRelayer: {
factory: getContractFactory('OVM_L1MultiMessageRelayer'), factory: getContractFactory('OVM_L1MultiMessageRelayer'),
......
...@@ -13,6 +13,7 @@ const L1_ETH_GATEWAY_NAME = 'Proxy__OVM_L1CrossDomainMessenger' ...@@ -13,6 +13,7 @@ const L1_ETH_GATEWAY_NAME = 'Proxy__OVM_L1CrossDomainMessenger'
const ERR_INVALID_MESSENGER = 'OVM_XCHAIN: messenger contract unauthenticated' const ERR_INVALID_MESSENGER = 'OVM_XCHAIN: messenger contract unauthenticated'
const ERR_INVALID_X_DOMAIN_MSG_SENDER = const ERR_INVALID_X_DOMAIN_MSG_SENDER =
'OVM_XCHAIN: wrong sender of cross-domain message' 'OVM_XCHAIN: wrong sender of cross-domain message'
const ERR_ALREADY_INITIALIZED = 'Contract has already been initialized.'
describe('OVM_L1ETHGateway', () => { describe('OVM_L1ETHGateway', () => {
// init signers // init signers
...@@ -45,14 +46,29 @@ describe('OVM_L1ETHGateway', () => { ...@@ -45,14 +46,29 @@ describe('OVM_L1ETHGateway', () => {
{ address: await l1MessengerImpersonator.getAddress() } // This allows us to use an ethers override {from: Mock__OVM_L2CrossDomainMessenger.address} to mock calls { address: await l1MessengerImpersonator.getAddress() } // This allows us to use an ethers override {from: Mock__OVM_L2CrossDomainMessenger.address} to mock calls
) )
// Deploy the contract under test // Deploy the contract under test and initialize
OVM_L1ETHGateway = await ( OVM_L1ETHGateway = await (
await ethers.getContractFactory('OVM_L1ETHGateway') await ethers.getContractFactory('OVM_L1ETHGateway')
).deploy(AddressManager.address, Mock__OVM_L2DepositedERC20.address) ).deploy()
await OVM_L1ETHGateway.initialize(
AddressManager.address,
Mock__OVM_L2DepositedERC20.address
)
finalizeDepositGasLimit = await OVM_L1ETHGateway.getFinalizeDepositL2Gas() finalizeDepositGasLimit = await OVM_L1ETHGateway.getFinalizeDepositL2Gas()
}) })
describe('initialize', () => {
it('Should only be callable once', async () => {
await expect(
OVM_L1ETHGateway.initialize(
ethers.constants.AddressZero,
ethers.constants.AddressZero
)
).to.be.revertedWith(ERR_ALREADY_INITIALIZED)
})
})
describe('finalizeWithdrawal', () => { describe('finalizeWithdrawal', () => {
it('onlyFromCrossDomainAccount: should revert on calls from a non-crossDomainMessenger L1 account', async () => { it('onlyFromCrossDomainAccount: should revert on calls from a non-crossDomainMessenger L1 account', async () => {
// Deploy new gateway, initialize with random messenger // Deploy new gateway, initialize with random messenger
...@@ -72,7 +88,11 @@ describe('OVM_L1ETHGateway', () => { ...@@ -72,7 +88,11 @@ describe('OVM_L1ETHGateway', () => {
OVM_L1ETHGateway = await ( OVM_L1ETHGateway = await (
await ethers.getContractFactory('OVM_L1ETHGateway') await ethers.getContractFactory('OVM_L1ETHGateway')
).deploy(AddressManager.address, Mock__OVM_L2DepositedERC20.address) ).deploy()
await OVM_L1ETHGateway.initialize(
AddressManager.address,
Mock__OVM_L2DepositedERC20.address
)
Mock__OVM_L1CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Mock__OVM_L1CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with(
NON_ZERO_ADDRESS NON_ZERO_ADDRESS
...@@ -147,10 +167,14 @@ describe('OVM_L1ETHGateway', () => { ...@@ -147,10 +167,14 @@ describe('OVM_L1ETHGateway', () => {
Mock__OVM_L1CrossDomainMessenger.address Mock__OVM_L1CrossDomainMessenger.address
) )
// Deploy the contract under test: // Deploy the contract under test and initialize
OVM_L1ETHGateway = await ( OVM_L1ETHGateway = await (
await ethers.getContractFactory('OVM_L1ETHGateway') await ethers.getContractFactory('OVM_L1ETHGateway')
).deploy(AddressManager.address, Mock__OVM_L2DepositedERC20.address) ).deploy()
await OVM_L1ETHGateway.initialize(
AddressManager.address,
Mock__OVM_L2DepositedERC20.address
)
}) })
it('deposit() escrows the deposit amount and sends the correct deposit message', async () => { it('deposit() escrows the deposit amount and sends the correct deposit message', async () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment