Skip to content

Commit 6b970a1

Browse files
committed
arb gateway unit tests
1 parent cdeea53 commit 6b970a1

File tree

2 files changed

+712
-0
lines changed

2 files changed

+712
-0
lines changed
Lines changed: 392 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,392 @@
1+
const { ethers } = require('hardhat');
2+
const { expect } = require('chai');
3+
4+
let accounts,
5+
deployer,
6+
depositor,
7+
depositorAddress,
8+
recipient,
9+
recipientAddress,
10+
router,
11+
routerAddress,
12+
counterpartGateway,
13+
counterpartAddress,
14+
inbox,
15+
ampl,
16+
policy,
17+
vault,
18+
xcAmple,
19+
gateway;
20+
21+
// l2 gas paramters
22+
const maxSubmissionCost = 1;
23+
const maxGas = 500000;
24+
const gasPriceBid = 0;
25+
26+
async function setupContracts() {
27+
accounts = await ethers.getSigners();
28+
deployer = accounts[0];
29+
depositor = deployer;
30+
depositorAddress = await deployer.getAddress();
31+
recipient = accounts[1];
32+
recipientAddress = await recipient.getAddress();
33+
router = accounts[2];
34+
routerAddress = await router.getAddress();
35+
counterpartGateway = accounts[3];
36+
counterpartAddress = await counterpartGateway.getAddress();
37+
38+
inbox = await (
39+
await ethers.getContractFactory(
40+
'contracts/_mocks/MockArbitrum.sol:MockArbitrumInbox',
41+
)
42+
)
43+
.connect(deployer)
44+
.deploy();
45+
46+
const uFragmentsFactory = await ethers.getContractFactory(
47+
'uFragments/contracts/UFragments.sol:UFragments',
48+
);
49+
ampl = await upgrades.deployProxy(
50+
uFragmentsFactory.connect(deployer),
51+
[depositorAddress],
52+
{ initializer: 'initialize(address)' },
53+
);
54+
await ampl.setMonetaryPolicy(depositorAddress);
55+
56+
policy = await (
57+
await ethers.getContractFactory(
58+
'contracts/_mocks/MockAmpleforth.sol:MockAmpleforth',
59+
)
60+
)
61+
.connect(deployer)
62+
.deploy();
63+
vault = await (
64+
await ethers.getContractFactory('contracts/_mocks/MockVault.sol:MockVault')
65+
)
66+
.connect(deployer)
67+
.deploy();
68+
69+
xcAmple = await (
70+
await ethers.getContractFactory(
71+
'contracts/_mocks/MockXCAmple.sol:MockXCAmple',
72+
)
73+
)
74+
.connect(deployer)
75+
.deploy();
76+
77+
gateway = await (
78+
await ethers.getContractFactory(
79+
'contracts/_mocks/MockArbitrum.sol:MockAMPLArbitrumGateway',
80+
)
81+
)
82+
.connect(deployer)
83+
.deploy(ampl.address, policy.address, vault.address);
84+
85+
await gateway.initialize(
86+
inbox.address,
87+
routerAddress,
88+
xcAmple.address,
89+
counterpartAddress,
90+
);
91+
await inbox.setL2ToL1Sender(counterpartAddress);
92+
93+
await policy.updateEpoch(1);
94+
await ampl.rebase(1, '-49999999999950000');
95+
}
96+
97+
describe('AMPLArbitrumGateway:Initialization', () => {
98+
before('setup AMPLArbitrumGateway contract', setupContracts);
99+
100+
it('should initialize the references', async function () {
101+
expect(await gateway.ampl()).to.eq(ampl.address);
102+
expect(await gateway.policy()).to.eq(policy.address);
103+
expect(await gateway.vault()).to.eq(vault.address);
104+
expect(await gateway.inbox()).to.eq(inbox.address);
105+
expect(await gateway.router()).to.eq(routerAddress);
106+
expect(await gateway.counterpartGateway()).to.eq(counterpartAddress);
107+
expect(await gateway.xcAmple()).to.eq(xcAmple.address);
108+
expect(await gateway.calculateL2TokenAddress(ampl.address)).to.eq(
109+
xcAmple.address,
110+
);
111+
});
112+
});
113+
114+
describe('AMPLArbitrumGateway:reportRebaseInit', () => {
115+
let r, seqNumber;
116+
before('setup AMPLArbitrumGateway contract', async function () {
117+
await setupContracts();
118+
seqNumber = await gateway
119+
.connect(depositor)
120+
.callStatic.reportRebaseInit(maxSubmissionCost, maxGas, gasPriceBid);
121+
r = gateway
122+
.connect(depositor)
123+
.reportRebaseInit(maxSubmissionCost, maxGas, gasPriceBid);
124+
});
125+
126+
it('should emit XCRebaseReportOut', async function () {
127+
await expect(r).to.emit(gateway, 'XCRebaseReportOut').withArgs(1, 50000);
128+
});
129+
130+
it('should emit RebaseReportInitiated', async function () {
131+
await expect(r)
132+
.to.emit(gateway, 'RebaseReportInitiated')
133+
.withArgs(seqNumber);
134+
});
135+
});
136+
137+
describe('AMPLArbitrumGateway:outboundTransfer:accessControl', () => {
138+
before('setup AMPLArbitrumGateway contract', setupContracts);
139+
140+
it('should NOT be callable by non-router', async function () {
141+
await expect(
142+
gateway
143+
.connect(depositor)
144+
.outboundTransfer(
145+
ampl.address,
146+
recipientAddress,
147+
1001,
148+
maxGas,
149+
gasPriceBid,
150+
[],
151+
),
152+
).to.be.revertedWith('AMPLArbitrumGateway: NOT_FROM_ROUTER');
153+
});
154+
155+
it('should NOT be callable for other tokens', async function () {
156+
await expect(
157+
gateway
158+
.connect(router)
159+
.outboundTransfer(
160+
xcAmple.address,
161+
recipientAddress,
162+
1001,
163+
maxGas,
164+
gasPriceBid,
165+
[],
166+
),
167+
).to.be.revertedWith('AMPLArbitrumGateway: ONLY_AMPL_ALLOWED');
168+
});
169+
170+
it('should NOT allow extra data', async function () {
171+
let data = ethers.utils.defaultAbiCoder.encode(
172+
['uint256', 'bytes'],
173+
[
174+
maxSubmissionCost,
175+
ethers.utils.defaultAbiCoder.encode(['uint256'], ['123']),
176+
],
177+
);
178+
179+
data = ethers.utils.defaultAbiCoder.encode(
180+
['address', 'bytes'],
181+
[depositorAddress, data],
182+
);
183+
184+
await expect(
185+
gateway
186+
.connect(router)
187+
.outboundTransfer(
188+
ampl.address,
189+
recipientAddress,
190+
1001,
191+
maxGas,
192+
gasPriceBid,
193+
data,
194+
),
195+
).to.be.revertedWith('AMPLArbitrumGateway: EXTRA_DATA_DISABLED');
196+
});
197+
});
198+
199+
describe('AMPLArbitrumGateway:outboundTransfer', () => {
200+
let r, seqNumber;
201+
before('setup AMPLArbitrumGateway contract', async function () {
202+
await setupContracts();
203+
204+
// router usually does this encoding part
205+
let data = ethers.utils.defaultAbiCoder.encode(
206+
['uint256', 'bytes'],
207+
[maxSubmissionCost, '0x'],
208+
);
209+
210+
data = ethers.utils.defaultAbiCoder.encode(
211+
['address', 'bytes'],
212+
[depositorAddress, data],
213+
);
214+
215+
await ampl.connect(depositor).approve(gateway.address, 1001);
216+
217+
seqNumber = await gateway
218+
.connect(router)
219+
.callStatic.outboundTransfer(
220+
ampl.address,
221+
recipientAddress,
222+
1001,
223+
maxGas,
224+
gasPriceBid,
225+
data,
226+
);
227+
r = gateway
228+
.connect(router)
229+
.outboundTransfer(
230+
ampl.address,
231+
recipientAddress,
232+
1001,
233+
maxGas,
234+
gasPriceBid,
235+
data,
236+
);
237+
});
238+
239+
it('should emit XCTransferOut', async function () {
240+
await expect(r)
241+
.to.emit(gateway, 'XCTransferOut')
242+
.withArgs(depositorAddress, ethers.constants.AddressZero, 1001, 50000);
243+
});
244+
245+
it('should emit DepositInitiated', async function () {
246+
await expect(r)
247+
.to.emit(gateway, 'DepositInitiated')
248+
.withArgs(
249+
ampl.address,
250+
depositorAddress,
251+
recipientAddress,
252+
seqNumber,
253+
1001,
254+
);
255+
});
256+
257+
it('should lock into vault', async function () {
258+
await expect(r)
259+
.to.emit(vault, 'Lock')
260+
.withArgs(ampl.address, depositorAddress, 1001);
261+
});
262+
});
263+
264+
describe('AMPLArbitrumGateway:finalizeInboundTransfer:accessControl', () => {
265+
before('setup AMPLArbitrumGateway contract', setupContracts);
266+
267+
it('should revert when called by non counterpart', async function () {
268+
const r = gateway
269+
.connect(deployer)
270+
.finalizeInboundTransfer(
271+
ampl.address,
272+
depositorAddress,
273+
recipientAddress,
274+
1001,
275+
[],
276+
);
277+
await expect(r).to.be.revertedWith(
278+
'AMPLArbitrumGateway: ONLY_COUNTERPART_GATEWAY',
279+
);
280+
});
281+
});
282+
283+
describe('AMPLArbitrumGateway:finalizeInboundTransfer', () => {
284+
let r, seqNumber;
285+
286+
describe('when supply is out of sync', function () {
287+
before('setup AMPLArbitrumGateway contract', async function () {
288+
await setupContracts();
289+
290+
const exitNum = 123213213;
291+
const withdrawData = ethers.utils.defaultAbiCoder.encode(
292+
['uint256', 'uint256'],
293+
[exitNum, 50000],
294+
);
295+
296+
await policy.updateEpoch(2);
297+
await ampl.rebase(2, 50000);
298+
299+
r = gateway
300+
.connect(counterpartGateway)
301+
.finalizeInboundTransfer(
302+
ampl.address,
303+
depositorAddress,
304+
recipientAddress,
305+
1001,
306+
withdrawData,
307+
);
308+
});
309+
310+
it('should emit XCTransferIn', async function () {
311+
await expect(r)
312+
.to.emit(gateway, 'XCTransferIn')
313+
.withArgs(
314+
ethers.constants.AddressZero,
315+
recipientAddress,
316+
50000,
317+
1001,
318+
100000,
319+
);
320+
});
321+
322+
it('should emit WithdrawalFinalized', async function () {
323+
await expect(r)
324+
.to.emit(gateway, 'WithdrawalFinalized')
325+
.withArgs(
326+
ampl.address,
327+
depositorAddress,
328+
recipientAddress,
329+
123213213,
330+
2002,
331+
);
332+
});
333+
334+
it('should unlock from vault', async function () {
335+
await expect(r)
336+
.to.emit(vault, 'Unlock')
337+
.withArgs(ampl.address, recipientAddress, 2002);
338+
});
339+
});
340+
341+
describe('when supply is in sync', function () {
342+
before('setup AMPLArbitrumGateway contract', async function () {
343+
await setupContracts();
344+
345+
const exitNum = 89324;
346+
const withdrawData = ethers.utils.defaultAbiCoder.encode(
347+
['uint256', 'uint256'],
348+
[exitNum, 50000],
349+
);
350+
351+
r = gateway
352+
.connect(counterpartGateway)
353+
.finalizeInboundTransfer(
354+
ampl.address,
355+
depositorAddress,
356+
recipientAddress,
357+
1001,
358+
withdrawData,
359+
);
360+
});
361+
362+
it('should emit XCTransferIn', async function () {
363+
await expect(r)
364+
.to.emit(gateway, 'XCTransferIn')
365+
.withArgs(
366+
ethers.constants.AddressZero,
367+
recipientAddress,
368+
50000,
369+
1001,
370+
50000,
371+
);
372+
});
373+
374+
it('should emit WithdrawalFinalized', async function () {
375+
await expect(r)
376+
.to.emit(gateway, 'WithdrawalFinalized')
377+
.withArgs(
378+
ampl.address,
379+
depositorAddress,
380+
recipientAddress,
381+
89324,
382+
1001,
383+
);
384+
});
385+
386+
it('should unlock from vault', async function () {
387+
await expect(r)
388+
.to.emit(vault, 'Unlock')
389+
.withArgs(ampl.address, recipientAddress, 1001);
390+
});
391+
});
392+
});

0 commit comments

Comments
 (0)