@@ -128,4 +128,58 @@ describe('Bridged tokens', () => {
128128 )
129129 }
130130 )
131+
132+ // This test demonstrates that an apparent withdrawal bug is in fact non-existent.
133+ // Specifically, the L2 bridge does not check that the L2 token being burned corresponds
134+ // with the L1 token which is specified for the withdrawal.
135+ withdrawalTest (
136+ 'should not allow an arbitrary L2 token to be withdrawn in exchange for a legitimate L1 token' ,
137+ async ( ) => {
138+ before ( async ( ) => {
139+ // First deposit some of the L1 token to L2, so that there is something which could be stolen.
140+ const depositTx = await env . l1Bridge
141+ . connect ( env . l1Wallet )
142+ . depositERC20 (
143+ L1__ERC20 . address ,
144+ L2__ERC20 . address ,
145+ 1000 ,
146+ 2000000 ,
147+ '0x'
148+ )
149+ await env . waitForXDomainTransaction ( depositTx , Direction . L1ToL2 )
150+ expect ( await L2__ERC20 . balanceOf ( env . l2Wallet . address ) ) . to . deep . equal (
151+ BigNumber . from ( 1000 )
152+ )
153+ } )
154+
155+ // Deploy a Fake L2 token, which:
156+ // - returns the address of a legitimate L1 token from its l1Token() getter.
157+ // - allows the L2 bridge to call its burn() function.
158+ const fakeToken = await (
159+ await ethers . getContractFactory ( 'FakeL2StandardERC20' , env . l2Wallet )
160+ ) . deploy ( L1__ERC20 . address )
161+ await fakeToken . deployed ( )
162+
163+ const balBefore = await L1__ERC20 . balanceOf ( otherWalletL1 . address )
164+
165+ // Withdraw some of the Fake L2 token, hoping to receive the same amount of the legitimate
166+ // token on L1.
167+ const withdrawalTx = await env . l2Bridge
168+ . connect ( otherWalletL2 )
169+ . withdrawTo (
170+ fakeToken . address ,
171+ otherWalletL1 . address ,
172+ 500 ,
173+ 1_000_000 ,
174+ '0x'
175+ )
176+ await env . relayXDomainMessages ( withdrawalTx )
177+ await env . waitForXDomainTransaction ( withdrawalTx , Direction . L2ToL1 )
178+
179+ // Ensure that the L1 recipient address has not received any additional L1 token balance.
180+ expect ( await L1__ERC20 . balanceOf ( otherWalletL1 . address ) ) . to . deep . equal (
181+ balBefore
182+ )
183+ }
184+ )
131185} )
0 commit comments