@@ -3,21 +3,17 @@ import { constants, ContractTransaction, Signer, utils } from 'ethers'
3
3
4
4
import { L2GraphToken } from '../../build/types/L2GraphToken'
5
5
import { L2GraphTokenGateway } from '../../build/types/L2GraphTokenGateway'
6
+ import { CallhookReceiverMock } from '../../build/types/CallhookReceiverMock'
6
7
7
8
import { L2FixtureContracts , NetworkFixture } from '../lib/fixtures'
8
9
9
10
import { FakeContract , smock } from '@defi-wonderland/smock'
10
11
11
- import path from 'path'
12
- import { Artifacts } from 'hardhat/internal/artifacts'
13
- const ARTIFACTS_PATH = path . resolve ( 'build/contracts' )
14
- const artifacts = new Artifacts ( ARTIFACTS_PATH )
15
- const rewardsManagerMockAbi = artifacts . readArtifactSync ( 'RewardsManagerMock' ) . abi
16
-
17
12
use ( smock . matchers )
18
13
19
14
import { getAccounts , toGRT , Account , toBN , getL2SignerFromL1 } from '../lib/testHelpers'
20
15
import { Interface } from 'ethers/lib/utils'
16
+ import { deployContract } from '../lib/deployment'
21
17
22
18
const { AddressZero } = constants
23
19
@@ -37,11 +33,14 @@ describe('L2GraphTokenGateway', () => {
37
33
let fixtureContracts : L2FixtureContracts
38
34
let grt : L2GraphToken
39
35
let l2GraphTokenGateway : L2GraphTokenGateway
36
+ let callhookReceiverMock : CallhookReceiverMock
40
37
41
38
const senderTokens = toGRT ( '1000' )
42
39
const defaultData = '0x'
43
- const mockIface = new Interface ( rewardsManagerMockAbi )
44
- const notEmptyCallHookData = mockIface . encodeFunctionData ( 'pow' , [ toBN ( 1 ) , toBN ( 2 ) , toBN ( 3 ) ] )
40
+ const notEmptyCallHookData = utils . defaultAbiCoder . encode (
41
+ [ 'uint256' , 'uint256' ] ,
42
+ [ toBN ( '1337' ) , toBN ( '42' ) ] ,
43
+ )
45
44
const defaultDataWithNotEmptyCallHookData = utils . defaultAbiCoder . encode (
46
45
[ 'bytes' , 'bytes' ] ,
47
46
[ '0x' , notEmptyCallHookData ] ,
@@ -64,6 +63,11 @@ describe('L2GraphTokenGateway', () => {
64
63
fixtureContracts = await fixture . loadL2 ( governor . signer )
65
64
; ( { grt, l2GraphTokenGateway } = fixtureContracts )
66
65
66
+ callhookReceiverMock = ( await deployContract (
67
+ 'CallhookReceiverMock' ,
68
+ governor . signer ,
69
+ ) ) as unknown as CallhookReceiverMock
70
+
67
71
// Give some funds to the token sender
68
72
await grt . connect ( governor . signer ) . mint ( tokenSender . address , senderTokens )
69
73
} )
@@ -319,32 +323,28 @@ describe('L2GraphTokenGateway', () => {
319
323
describe ( 'finalizeInboundTransfer' , function ( ) {
320
324
const testValidFinalizeTransfer = async function (
321
325
data : string ,
326
+ to ?: string ,
322
327
) : Promise < ContractTransaction > {
328
+ to = to ?? l2Receiver . address
323
329
const mockL1GatewayL2Alias = await getL2SignerFromL1 ( mockL1Gateway . address )
324
330
await me . signer . sendTransaction ( {
325
331
to : await mockL1GatewayL2Alias . getAddress ( ) ,
326
332
value : utils . parseUnits ( '1' , 'ether' ) ,
327
333
} )
328
334
const tx = l2GraphTokenGateway
329
335
. connect ( mockL1GatewayL2Alias )
330
- . finalizeInboundTransfer (
331
- mockL1GRT . address ,
332
- tokenSender . address ,
333
- l2Receiver . address ,
334
- toGRT ( '10' ) ,
335
- data ,
336
- )
336
+ . finalizeInboundTransfer ( mockL1GRT . address , tokenSender . address , to , toGRT ( '10' ) , data )
337
337
await expect ( tx )
338
338
. emit ( l2GraphTokenGateway , 'DepositFinalized' )
339
- . withArgs ( mockL1GRT . address , tokenSender . address , l2Receiver . address , toGRT ( '10' ) )
339
+ . withArgs ( mockL1GRT . address , tokenSender . address , to , toGRT ( '10' ) )
340
340
341
- await expect ( tx ) . emit ( grt , 'BridgeMinted' ) . withArgs ( l2Receiver . address , toGRT ( '10' ) )
341
+ await expect ( tx ) . emit ( grt , 'BridgeMinted' ) . withArgs ( to , toGRT ( '10' ) )
342
342
343
343
// Unchanged
344
344
const senderBalance = await grt . balanceOf ( tokenSender . address )
345
345
await expect ( senderBalance ) . eq ( toGRT ( '1000' ) )
346
346
// 10 newly minted GRT
347
- const receiverBalance = await grt . balanceOf ( l2Receiver . address )
347
+ const receiverBalance = await grt . balanceOf ( to )
348
348
await expect ( receiverBalance ) . eq ( toGRT ( '10' ) )
349
349
return tx
350
350
}
@@ -375,19 +375,23 @@ describe('L2GraphTokenGateway', () => {
375
375
it ( 'mints and sends tokens when called by the aliased gateway' , async function ( ) {
376
376
await testValidFinalizeTransfer ( defaultData )
377
377
} )
378
- it ( 'calls a callhook if the sender is whitelisted' , async function ( ) {
379
- const rewardsManagerMock = await smock . fake ( 'RewardsManagerMock' , {
380
- address : l2Receiver . address ,
381
- } )
382
- rewardsManagerMock . pow . returns ( 1 )
383
- await testValidFinalizeTransfer ( defaultDataWithNotEmptyCallHookData )
384
- expect ( rewardsManagerMock . pow ) . to . have . been . calledWith ( toBN ( 1 ) , toBN ( 2 ) , toBN ( 3 ) )
378
+ it ( 'calls a callhook if the transfer includes calldata' , async function ( ) {
379
+ const tx = await testValidFinalizeTransfer (
380
+ defaultDataWithNotEmptyCallHookData ,
381
+ callhookReceiverMock . address ,
382
+ )
383
+ // Emitted by the callhook:
384
+ await expect ( tx )
385
+ . emit ( callhookReceiverMock , 'TransferReceived' )
386
+ . withArgs ( tokenSender . address , toGRT ( '10' ) , toBN ( '1337' ) , toBN ( '42' ) )
385
387
} )
386
388
it ( 'reverts if a callhook reverts' , async function ( ) {
387
- const rewardsManagerMock = await smock . fake ( 'RewardsManagerMock' , {
388
- address : l2Receiver . address ,
389
- } )
390
- rewardsManagerMock . pow . reverts ( )
389
+ // The 0 will make the callhook revert (see CallhookReceiverMock.sol)
390
+ const callHookData = utils . defaultAbiCoder . encode (
391
+ [ 'uint256' , 'uint256' ] ,
392
+ [ toBN ( '0' ) , toBN ( '42' ) ] ,
393
+ )
394
+ const data = utils . defaultAbiCoder . encode ( [ 'bytes' , 'bytes' ] , [ '0x' , callHookData ] )
391
395
const mockL1GatewayL2Alias = await getL2SignerFromL1 ( mockL1Gateway . address )
392
396
await me . signer . sendTransaction ( {
393
397
to : await mockL1GatewayL2Alias . getAddress ( ) ,
@@ -398,11 +402,11 @@ describe('L2GraphTokenGateway', () => {
398
402
. finalizeInboundTransfer (
399
403
mockL1GRT . address ,
400
404
tokenSender . address ,
401
- l2Receiver . address ,
405
+ callhookReceiverMock . address ,
402
406
toGRT ( '10' ) ,
403
- defaultDataWithNotEmptyCallHookData ,
407
+ data ,
404
408
)
405
- await expect ( tx ) . revertedWith ( 'CALLHOOK_FAILED ' )
409
+ await expect ( tx ) . revertedWith ( 'FOO_IS_ZERO ' )
406
410
} )
407
411
} )
408
412
} )
0 commit comments