Commit 137f7765 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #2061 from ethereum-optimism/m/add-fake-token-test

test(integration): withdrawing a fake L2 token
parents 30ada8e6 0293749e
---
'@eth-optimism/integration-tests': patch
---
Add an integration test showing the infeasability of withdrawing a fake token in exchange for a legitimate token.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
contract FakeL2StandardERC20 {
address public immutable l1Token;
constructor(address _l1Token) {
l1Token = _l1Token;
}
// Burn will be called by the L2 Bridge to burn the tokens we are bridging to L1
function burn(address, uint256) external {}
}
...@@ -127,4 +127,58 @@ describe('Bridged tokens', () => { ...@@ -127,4 +127,58 @@ describe('Bridged tokens', () => {
) )
} }
) )
// This test demonstrates that an apparent withdrawal bug is in fact non-existent.
// Specifically, the L2 bridge does not check that the L2 token being burned corresponds
// with the L1 token which is specified for the withdrawal.
withdrawalTest(
'should not allow an arbitrary L2 token to be withdrawn in exchange for a legitimate L1 token',
async () => {
before(async () => {
// First deposit some of the L1 token to L2, so that there is something which could be stolen.
const depositTx = await env.l1Bridge
.connect(env.l1Wallet)
.depositERC20(
L1__ERC20.address,
L2__ERC20.address,
1000,
2000000,
'0x'
)
await env.waitForXDomainTransaction(depositTx, Direction.L1ToL2)
expect(await L2__ERC20.balanceOf(env.l2Wallet.address)).to.deep.equal(
BigNumber.from(1000)
)
})
// Deploy a Fake L2 token, which:
// - returns the address of a legitimate L1 token from its l1Token() getter.
// - allows the L2 bridge to call its burn() function.
const fakeToken = await (
await ethers.getContractFactory('FakeL2StandardERC20', env.l2Wallet)
).deploy(L1__ERC20.address)
await fakeToken.deployed()
const balBefore = await L1__ERC20.balanceOf(otherWalletL1.address)
// Withdraw some of the Fake L2 token, hoping to receive the same amount of the legitimate
// token on L1.
const withdrawalTx = await env.l2Bridge
.connect(otherWalletL2)
.withdrawTo(
fakeToken.address,
otherWalletL1.address,
500,
1_000_000,
'0x'
)
await env.relayXDomainMessages(withdrawalTx)
await env.waitForXDomainTransaction(withdrawalTx, Direction.L2ToL1)
// Ensure that the L1 recipient address has not received any additional L1 token balance.
expect(await L1__ERC20.balanceOf(otherWalletL1.address)).to.deep.equal(
balBefore
)
}
)
}) })
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