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
/* Library Imports */
import { OVM_CrossDomainEnabled } from "../../../libraries/bridge/OVM_CrossDomainEnabled.sol";
import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_AddressManager } from "../../../libraries/resolver/Lib_AddressManager.sol";
/**
* @title OVM_L1ETHGateway
......@@ -36,19 +37,31 @@ contract OVM_L1ETHGateway is iOVM_L1ETHGateway, OVM_CrossDomainEnabled, Lib_Addr
* 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 _ovmEth L2 OVM_ETH implementation of iOVM_DepositedToken
*/
constructor(
function initialize(
address _libAddressManager,
address _ovmEth
)
OVM_CrossDomainEnabled(address(0)) // overridden in constructor code
Lib_AddressResolver(_libAddressManager)
public
{
require(libAddressManager == Lib_AddressManager(0), "Contract has already been initialized.");
libAddressManager = Lib_AddressManager(_libAddressManager);
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 {
fallback()
external
payable
{
address target = addressManager[address(this)].getAddress((implementationName[address(this)]));
require(
......
......@@ -109,10 +109,23 @@ export const makeContractDeployConfig = async (
},
OVM_L1ETHGateway: {
factory: getContractFactory('OVM_L1ETHGateway'),
params: [
AddressManager.address,
'0x4200000000000000000000000000000000000006',
],
params: [],
},
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: {
factory: getContractFactory('OVM_L1MultiMessageRelayer'),
......
......@@ -13,6 +13,7 @@ const L1_ETH_GATEWAY_NAME = 'Proxy__OVM_L1CrossDomainMessenger'
const ERR_INVALID_MESSENGER = 'OVM_XCHAIN: messenger contract unauthenticated'
const ERR_INVALID_X_DOMAIN_MSG_SENDER =
'OVM_XCHAIN: wrong sender of cross-domain message'
const ERR_ALREADY_INITIALIZED = 'Contract has already been initialized.'
describe('OVM_L1ETHGateway', () => {
// init signers
......@@ -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
)
// Deploy the contract under test
// Deploy the contract under test and initialize
OVM_L1ETHGateway = await (
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()
})
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', () => {
it('onlyFromCrossDomainAccount: should revert on calls from a non-crossDomainMessenger L1 account', async () => {
// Deploy new gateway, initialize with random messenger
......@@ -72,7 +88,11 @@ describe('OVM_L1ETHGateway', () => {
OVM_L1ETHGateway = await (
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(
NON_ZERO_ADDRESS
......@@ -147,10 +167,14 @@ describe('OVM_L1ETHGateway', () => {
Mock__OVM_L1CrossDomainMessenger.address
)
// Deploy the contract under test:
// Deploy the contract under test and initialize
OVM_L1ETHGateway = await (
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 () => {
......
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