Skip to content

Commit 8e6a02b

Browse files
zimpharanchalpThegaram
authored
feat: euclid phase-2 contract changes (#74)
Co-authored-by: Alejandro Ranchal-Pedrosa <[email protected]> Co-authored-by: Péter Garamvölgyi <[email protected]>
1 parent 76e5df4 commit 8e6a02b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3257
-1453
lines changed

hardhat-test/EnforcedTxGateway.spec.ts

Lines changed: 120 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
/* eslint-disable node/no-missing-import */
33
import { HardhatEthersSigner, SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
44
import { expect } from "chai";
5-
import { BigNumberish, BytesLike, MaxUint256, ZeroAddress, getBytes } from "ethers";
6-
import { ethers } from "hardhat";
5+
import { BigNumberish, BytesLike, MaxUint256, ZeroAddress, getAddress, getBytes, toBeHex } from "ethers";
6+
import { ethers, network } from "hardhat";
77

8-
import { EnforcedTxGateway, L1MessageQueue, L2GasPriceOracle, MockCaller } from "../typechain";
8+
import { EnforcedTxGateway, L1MessageQueueV2, MockCaller, SystemConfig } from "../typechain";
99

1010
describe("EnforcedTxGateway.spec", async () => {
1111
let deployer: HardhatEthersSigner;
1212
let feeVault: HardhatEthersSigner;
1313
let signer: HardhatEthersSigner;
1414

1515
let caller: MockCaller;
16+
let system: SystemConfig;
1617
let gateway: EnforcedTxGateway;
17-
let oracle: L2GasPriceOracle;
18-
let queue: L1MessageQueue;
18+
let queue: L1MessageQueueV2;
1919

2020
const deployProxy = async (name: string, admin: string, args: any[]): Promise<string> => {
2121
const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer);
@@ -28,44 +28,57 @@ describe("EnforcedTxGateway.spec", async () => {
2828
beforeEach(async () => {
2929
[deployer, feeVault, signer] = await ethers.getSigners();
3030

31+
const EmptyContract = await ethers.getContractFactory("EmptyContract", deployer);
32+
const empty = await EmptyContract.deploy();
33+
3134
const ProxyAdmin = await ethers.getContractFactory("ProxyAdmin", deployer);
3235
const admin = await ProxyAdmin.deploy();
3336

34-
gateway = await ethers.getContractAt(
35-
"EnforcedTxGateway",
36-
await deployProxy("EnforcedTxGateway", await admin.getAddress(), []),
37-
deployer
38-
);
37+
const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer);
38+
const L1MessageQueueV1 = await ethers.getContractFactory("L1MessageQueueV1", deployer);
39+
const L1MessageQueueV2 = await ethers.getContractFactory("L1MessageQueueV2", deployer);
40+
const EnforcedTxGateway = await ethers.getContractFactory("EnforcedTxGateway", deployer);
3941

40-
queue = await ethers.getContractAt(
41-
"L1MessageQueue",
42-
await deployProxy("L1MessageQueue", await admin.getAddress(), [
43-
deployer.address,
44-
deployer.address,
45-
await gateway.getAddress(),
46-
]),
42+
system = await ethers.getContractAt(
43+
"SystemConfig",
44+
await deployProxy("SystemConfig", await admin.getAddress(), []),
4745
deployer
4846
);
49-
50-
oracle = await ethers.getContractAt(
51-
"L2GasPriceOracle",
52-
await deployProxy("L2GasPriceOracle", await admin.getAddress(), []),
53-
deployer
47+
const queueV1Proxy = await TransparentUpgradeableProxy.deploy(empty.getAddress(), admin.getAddress(), "0x");
48+
const queueV2Proxy = await TransparentUpgradeableProxy.deploy(empty.getAddress(), admin.getAddress(), "0x");
49+
const gatewayProxy = await TransparentUpgradeableProxy.deploy(empty.getAddress(), admin.getAddress(), "0x");
50+
51+
const queueV1Impl = await L1MessageQueueV1.deploy(deployer.address, deployer.address, gatewayProxy.getAddress());
52+
const queueV2Impl = await L1MessageQueueV2.deploy(
53+
deployer.address,
54+
deployer.address,
55+
gatewayProxy.getAddress(),
56+
queueV1Proxy.getAddress(),
57+
system.getAddress()
5458
);
59+
const gatewayImpl = await EnforcedTxGateway.deploy(queueV2Proxy.getAddress(), feeVault.address);
60+
await admin.upgrade(queueV1Proxy.getAddress(), queueV1Impl.getAddress());
61+
await admin.upgrade(queueV2Proxy.getAddress(), queueV2Impl.getAddress());
62+
await admin.upgrade(gatewayProxy.getAddress(), gatewayImpl.getAddress());
63+
64+
gateway = await ethers.getContractAt("EnforcedTxGateway", await gatewayProxy.getAddress(), deployer);
65+
queue = await ethers.getContractAt("L1MessageQueueV2", await queueV2Proxy.getAddress(), deployer);
5566

5667
const MockCaller = await ethers.getContractFactory("MockCaller", deployer);
5768
caller = await MockCaller.deploy();
5869

59-
await queue.initialize(ZeroAddress, ZeroAddress, ZeroAddress, oracle.getAddress(), 10000000);
60-
await gateway.initialize(queue.getAddress(), feeVault.address);
61-
await oracle.initialize(21000, 51000, 8, 16);
62-
63-
const Whitelist = await ethers.getContractFactory("Whitelist", deployer);
64-
const whitelist = await Whitelist.deploy(deployer.address);
65-
66-
await whitelist.updateWhitelistStatus([deployer.address], true);
67-
await oracle.updateWhitelist(whitelist.getAddress());
68-
await oracle.setL2BaseFee(1);
70+
await system.initialize(
71+
deployer.address,
72+
deployer.address,
73+
{
74+
maxGasLimit: 1000000,
75+
baseFeeOverhead: 10n ** 9n,
76+
baseFeeScalar: 10n ** 18n,
77+
},
78+
{ maxDelayEnterEnforcedMode: 0, maxDelayMessageQueue: 0 }
79+
);
80+
await queue.initialize();
81+
await gateway.initialize();
6982
});
7083

7184
context("auth", async () => {
@@ -77,25 +90,7 @@ describe("EnforcedTxGateway.spec", async () => {
7790
});
7891

7992
it("should revert, when initialize again", async () => {
80-
await expect(gateway.initialize(ZeroAddress, ZeroAddress)).to.revertedWith(
81-
"Initializable: contract is already initialized"
82-
);
83-
});
84-
85-
context("#updateFeeVault", async () => {
86-
it("should revert, when non-owner call", async () => {
87-
await expect(gateway.connect(signer).updateFeeVault(ZeroAddress)).to.revertedWith(
88-
"Ownable: caller is not the owner"
89-
);
90-
});
91-
92-
it("should succeed", async () => {
93-
expect(await gateway.feeVault()).to.eq(feeVault.address);
94-
await expect(gateway.updateFeeVault(deployer.address))
95-
.to.emit(gateway, "UpdateFeeVault")
96-
.withArgs(feeVault.address, deployer.address);
97-
expect(await gateway.feeVault()).to.eq(deployer.address);
98-
});
93+
await expect(gateway.initialize()).to.revertedWith("Initializable: contract is already initialized");
9994
});
10095

10196
context("#setPause", async () => {
@@ -121,66 +116,102 @@ describe("EnforcedTxGateway.spec", async () => {
121116
).to.revertedWith("Pausable: paused");
122117
});
123118

124-
it("should revert, when call is not EOA", async () => {
125-
const calldata = gateway.interface.encodeFunctionData("sendTransaction(address,uint256,uint256,bytes)", [
126-
signer.address,
127-
0,
128-
0,
129-
"0x",
130-
]);
131-
await expect(caller.callTarget(gateway.getAddress(), calldata)).to.revertedWith(
132-
"Only EOA senders are allowed to send enforced transaction"
133-
);
134-
});
135-
136119
it("should revert, when insufficient value for fee", async () => {
137120
const fee = await queue.estimateCrossDomainMessageFee(1000000);
121+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
138122
await expect(
139123
gateway
140124
.connect(signer)
141125
["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 1000000, "0x", { value: fee - 1n })
142126
).to.revertedWith("Insufficient value for fee");
143127
});
144128

145-
it("should revert, when failed to deduct the fee", async () => {
146-
await gateway.updateFeeVault(gateway.getAddress());
147-
const fee = await queue.estimateCrossDomainMessageFee(1000000);
148-
await expect(
149-
gateway
150-
.connect(signer)
151-
["sendTransaction(address,uint256,uint256,bytes)"](signer.address, 0, 1000000, "0x", { value: fee })
152-
).to.revertedWith("Failed to deduct the fee");
153-
});
154-
155-
it("should succeed, no refund", async () => {
129+
it("should succeed, with refund", async () => {
156130
const fee = await queue.estimateCrossDomainMessageFee(1000000);
157131
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
158-
await expect(
159-
gateway
160-
.connect(signer)
161-
["sendTransaction(address,uint256,uint256,bytes)"](deployer.address, 0, 1000000, "0x", { value: fee })
162-
)
132+
const signerBalanceBefore = await ethers.provider.getBalance(signer.address);
133+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
134+
const tx = await gateway
135+
.connect(signer)
136+
["sendTransaction(address,uint256,uint256,bytes)"](deployer.address, 0, 1000000, "0x", { value: fee + 100n });
137+
await expect(tx)
163138
.to.emit(queue, "QueueTransaction")
164139
.withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x");
140+
const receipt = await tx.wait();
165141
const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address);
142+
const signerBalanceAfter = await ethers.provider.getBalance(signer.address);
166143
expect(feeVaultBalanceAfter - feeVaultBalanceBefore).to.eq(fee);
144+
expect(signerBalanceBefore - signerBalanceAfter).to.eq(receipt!.gasUsed * receipt!.gasPrice + fee);
145+
});
146+
});
147+
148+
context("#sendTransaction, by Contract", async () => {
149+
it("should revert, when contract is paused", async () => {
150+
await gateway.setPause(true);
151+
await expect(
152+
caller.callTarget(
153+
gateway.getAddress(),
154+
gateway.interface.encodeFunctionData("sendTransaction(address,uint256,uint256,bytes)", [
155+
signer.address,
156+
0,
157+
0,
158+
"0x",
159+
])
160+
)
161+
).to.revertedWith("Pausable: paused");
162+
});
163+
164+
it("should revert, when insufficient value for fee", async () => {
165+
const fee = await queue.estimateCrossDomainMessageFee(1000000);
166+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
167+
await expect(
168+
caller.callTarget(
169+
gateway.getAddress(),
170+
gateway.interface.encodeFunctionData("sendTransaction(address,uint256,uint256,bytes)", [
171+
signer.address,
172+
0,
173+
1000000,
174+
"0x",
175+
]),
176+
{ value: fee - 1n }
177+
)
178+
).to.revertedWith("Insufficient value for fee");
167179
});
168180

169181
it("should succeed, with refund", async () => {
170182
const fee = await queue.estimateCrossDomainMessageFee(1000000);
183+
const callerBalanceBefore = await ethers.provider.getBalance(caller.getAddress());
171184
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
172185
const signerBalanceBefore = await ethers.provider.getBalance(signer.address);
173-
const tx = await gateway
186+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
187+
const sender = getAddress(
188+
"0x" +
189+
toBeHex(
190+
(BigInt(await caller.getAddress()) + BigInt("0x1111000000000000000000000000000000001111")) % 2n ** 160n
191+
)
192+
.slice(2)
193+
.padStart(40, "0")
194+
);
195+
const tx = await caller
174196
.connect(signer)
175-
["sendTransaction(address,uint256,uint256,bytes)"](deployer.address, 0, 1000000, "0x", { value: fee + 100n });
176-
await expect(tx)
177-
.to.emit(queue, "QueueTransaction")
178-
.withArgs(signer.address, deployer.address, 0, 0, 1000000, "0x");
197+
.callTarget(
198+
gateway.getAddress(),
199+
gateway.interface.encodeFunctionData("sendTransaction(address,uint256,uint256,bytes)", [
200+
deployer.address,
201+
0,
202+
1000000,
203+
"0x",
204+
]),
205+
{ value: fee + 100n }
206+
);
207+
await expect(tx).to.emit(queue, "QueueTransaction").withArgs(sender, deployer.address, 0, 0, 1000000, "0x");
179208
const receipt = await tx.wait();
209+
const callerBalanceAfter = await ethers.provider.getBalance(caller.getAddress());
180210
const feeVaultBalanceAfter = await ethers.provider.getBalance(feeVault.address);
181211
const signerBalanceAfter = await ethers.provider.getBalance(signer.address);
212+
expect(callerBalanceAfter - callerBalanceBefore).to.eq(100n);
182213
expect(feeVaultBalanceAfter - feeVaultBalanceBefore).to.eq(fee);
183-
expect(signerBalanceBefore - signerBalanceAfter).to.eq(receipt!.gasUsed * receipt!.gasPrice + fee);
214+
expect(signerBalanceBefore - signerBalanceAfter).to.eq(receipt!.gasUsed * receipt!.gasPrice + fee + 100n);
184215
});
185216
});
186217

@@ -303,6 +334,7 @@ describe("EnforcedTxGateway.spec", async () => {
303334
it("should revert, when insufficient value for fee", async () => {
304335
const signature = await getSignature(signer, signer.address, 0, 1000000, "0x");
305336
const fee = await queue.estimateCrossDomainMessageFee(1000000);
337+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
306338
await expect(
307339
gateway
308340
.connect(deployer)
@@ -320,32 +352,12 @@ describe("EnforcedTxGateway.spec", async () => {
320352
).to.revertedWith("Insufficient value for fee");
321353
});
322354

323-
it("should revert, when failed to deduct the fee", async () => {
324-
await gateway.updateFeeVault(gateway.getAddress());
325-
const signature = await getSignature(signer, signer.address, 0, 1000000, "0x");
326-
const fee = await queue.estimateCrossDomainMessageFee(1000000);
327-
await expect(
328-
gateway
329-
.connect(deployer)
330-
["sendTransaction(address,address,uint256,uint256,bytes,uint256,bytes,address)"](
331-
signer.address,
332-
signer.address,
333-
0,
334-
1000000,
335-
"0x",
336-
MaxUint256,
337-
signature,
338-
signer.address,
339-
{ value: fee }
340-
)
341-
).to.revertedWith("Failed to deduct the fee");
342-
});
343-
344355
it("should succeed, no refund", async () => {
345356
const signature = await getSignature(signer, deployer.address, 0, 1000000, "0x");
346357
const fee = await queue.estimateCrossDomainMessageFee(1000000);
347358
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
348359
expect(await gateway.nonces(signer.address)).to.eq(0);
360+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
349361
await expect(
350362
gateway
351363
.connect(deployer)
@@ -391,6 +403,7 @@ describe("EnforcedTxGateway.spec", async () => {
391403
const feeVaultBalanceBefore = await ethers.provider.getBalance(feeVault.address);
392404
const signerBalanceBefore = await ethers.provider.getBalance(signer.address);
393405
expect(await gateway.nonces(signer.address)).to.eq(0);
406+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
394407
await expect(
395408
gateway
396409
.connect(deployer)
@@ -435,6 +448,7 @@ describe("EnforcedTxGateway.spec", async () => {
435448
it("should revert, when refund failed", async () => {
436449
const signature = await getSignature(signer, signer.address, 0, 1000000, "0x1234");
437450
const fee = await queue.estimateCrossDomainMessageFee(1000000);
451+
await network.provider.send("hardhat_setNextBlockBaseFeePerGas", ["0"]);
438452
await expect(
439453
gateway
440454
.connect(deployer)

0 commit comments

Comments
 (0)