Skip to content

Commit c349914

Browse files
committed
add test script for testing bridge
1 parent 77c7a25 commit c349914

File tree

5 files changed

+519
-39
lines changed

5 files changed

+519
-39
lines changed

ethereum/.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ CONTRACTS_L1_ALLOW_LIST_ADDR=0x0000000000000000000000000000000000000000
1717
CONTRACTS_CREATE2_FACTORY_ADDR=0x0000000000000000000000000000000000000000
1818
CONTRACTS_VALIDATOR_TIMELOCK_ADDR=0x0000000000000000000000000000000000000000
1919
CONTRACTS_VALIDATOR_TIMELOCK_EXECUTION_DELAY=0
20+
21+
MNEMONIC="fine music test violin matrix prize squirrel panther purchase material script deal"

ethereum/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,11 @@
7070
"upgrade-3": "ts-node scripts/upgrades/upgrade-3.ts",
7171
"upgrade-4": "ts-node scripts/upgrades/upgrade-4.ts",
7272
"upgrade-5": "ts-node scripts/upgrades/upgrade-5.ts",
73-
"upgrade-6": "ts-node scripts/upgrades/upgrade-6.ts"
73+
"upgrade-6": "ts-node scripts/upgrades/upgrade-6.ts",
74+
"test:bridge": "ts-node src.ts/test-bridge.ts"
7475
},
7576
"dependencies": {
76-
"dotenv": "^16.0.3"
77-
},
78-
"optionalDependencies": {
77+
"dotenv": "^16.0.3",
7978
"zksync-web3": "^0.14.3"
8079
}
8180
}

ethereum/src.ts/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Test WETH Bridge Script
2+
3+
4+
- Deploy local devnet `zk reinit`
5+
- Copy `etc/env/.init.env` content and append it to `contracts/ethereum/.env`
6+
- Make sure zk server is running `zk server`
7+
- `yarn run test:bridge`
8+
9+
10+
11+
There are several functions in the script, need to **manually comment/uncomment** to activate.

ethereum/src.ts/test-bridge.ts

Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
import { ethers } from 'ethers';
2+
import { AllowListFactory, L1ERC20BridgeFactory, MailboxFacetFactory, WETH9Factory, TestnetERC20TokenFactory } from '../typechain';
3+
import * as dotenv from "dotenv";
4+
import { IZkSyncFactory } from '../typechain/IZkSyncFactory';
5+
import { utils, Provider as ZkSyncProvider, Wallet as ZKWallet } from 'zksync-web3';
6+
dotenv.config();
7+
8+
9+
const WETH_ADDRESS = process.env.CONTRACTS_L1_WETH_TOKEN_ADDR!;
10+
const L1_ERC20_BRIDGE_ADDRESS = process.env.CONTRACTS_L1_ERC20_BRIDGE_IMPL_ADDR!;
11+
const MNEMONIC = process.env.MNEMONIC!;
12+
const MAILBOX_ADDRESS = process.env.CONTRACTS_MAILBOX_FACET_ADDR!;
13+
const ALLOW_LIST_ADDRESS = process.env.CONTRACTS_L1_ALLOW_LIST_ADDR!;
14+
const ZKSYNC_ADDRESS = process.env.CONTRACTS_DIAMOND_PROXY_ADDR!;
15+
const L2WETH_ADDRESS = process.env.CONTRACTS_L2_WETH_IMPLEMENTATION_ADDR!;
16+
const L2ETH_ADDRESS = "0x000000000000000000000000000000000000800a";
17+
const ERC20_ADDRESS = "0x66fCdcFAb79983a331EA32B69D822178530738Ff";
18+
19+
const DERIVE_PATH = "m/44'/60'/0'/0/1";
20+
21+
const prepare = async () => {
22+
let wallet = ethers.Wallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
23+
console.log("wallet: ", wallet.address);
24+
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
25+
wallet = wallet.connect(provider);
26+
console.log("balance: ", ethers.utils.formatEther(await wallet.getBalance()));
27+
const WETH = WETH9Factory.connect(WETH_ADDRESS, wallet);
28+
const L1ERC20Bridge = L1ERC20BridgeFactory.connect(L1_ERC20_BRIDGE_ADDRESS, wallet);
29+
const MailBox = MailboxFacetFactory.connect(MAILBOX_ADDRESS, wallet);
30+
const AllowList = AllowListFactory.connect(ALLOW_LIST_ADDRESS, wallet);
31+
const ZKSync = IZkSyncFactory.connect(ZKSYNC_ADDRESS, wallet);
32+
const ERC20 = TestnetERC20TokenFactory.connect(ERC20_ADDRESS, wallet)
33+
34+
console.log("Mint WETH...");
35+
let tx = await WETH.mint(wallet.address, ethers.utils.parseEther("9999999999"), {
36+
});
37+
await tx.wait()
38+
const balance = await WETH.balanceOf(wallet.address);
39+
console.log("WETH balance: ", ethers.utils.formatEther(balance), "WETH");
40+
41+
console.log("Mint ERC20...");
42+
tx = await ERC20.mint(wallet.address, ethers.utils.parseEther("10000000"), {
43+
});
44+
await tx.wait()
45+
46+
console.log("Set access mode for L1ERC20Bridge...");
47+
tx = await AllowList.setAccessMode(L1ERC20Bridge.address, 2);
48+
await tx.wait();
49+
let res = await AllowList.getAccessMode(L1ERC20Bridge.address)
50+
console.log("AccessMode for L1WethBridge: ", res);
51+
52+
console.log("Set access mode for Mailbox...");
53+
tx = await AllowList.setAccessMode(MAILBOX_ADDRESS, 2);
54+
await tx.wait();
55+
res = await AllowList.getAccessMode(MAILBOX_ADDRESS)
56+
console.log("AccessMode for MailBox: ", res);
57+
58+
console.log("Set access mode for zksync");
59+
tx = await AllowList.setAccessMode(ZKSYNC_ADDRESS, 2);
60+
await tx.wait();
61+
res = await AllowList.getAccessMode(ZKSYNC_ADDRESS);
62+
console.log("Accessmode for zksync: ", res);
63+
64+
let v = await AllowList.canCall(wallet.address, MAILBOX_ADDRESS, MailBox.interface.getSighash("requestL2Transaction"))
65+
console.log("canCall: ", v);
66+
67+
v = await AllowList.canCall(wallet.address, ZKSYNC_ADDRESS, MailBox.interface.getSighash("finalizeEthWithdrawal"))
68+
console.log("canCall finalizeEthWithdrawal: ", v);
69+
70+
v = await AllowList.canCall(wallet.address, ZKSYNC_ADDRESS, ZKSync.interface.getSighash("requestL2Transaction"))
71+
console.log("canCall: ", v);
72+
73+
tx = await AllowList.setDepositLimit(WETH_ADDRESS, false, ethers.utils.parseEther("9999999"))
74+
await tx.wait();
75+
let limit = await AllowList.getTokenDepositLimitData(WETH_ADDRESS);
76+
console.log("deposit limit: ", limit);
77+
78+
tx = await AllowList.setDepositLimit(ERC20_ADDRESS, false, ethers.utils.parseEther("9999999"))
79+
await tx.wait();
80+
limit = await AllowList.getTokenDepositLimitData(WETH_ADDRESS);
81+
console.log("erc20 deposit limit: ", limit);
82+
}
83+
84+
const testWorkingMailBox = async () => {
85+
let wallet = ethers.Wallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
86+
console.log("wallet: ", wallet.address);
87+
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
88+
wallet = wallet.connect(provider);
89+
console.log("balance: ", ethers.utils.formatEther(await wallet.getBalance()));
90+
const WETH = WETH9Factory.connect(WETH_ADDRESS, wallet);
91+
const L1ERC20Bridge = L1ERC20BridgeFactory.connect(L1_ERC20_BRIDGE_ADDRESS, wallet);
92+
const allowList = AllowListFactory.connect(await L1ERC20Bridge.allowList(), wallet);
93+
const zkSync = IZkSyncFactory.connect(ZKSYNC_ADDRESS, wallet);
94+
95+
console.log("testing requestL2Transaction...");
96+
const MailBox = MailboxFacetFactory.connect(MAILBOX_ADDRESS, wallet);
97+
const DEPOSIT_L2_GAS_LIMIT = 10_000_000;
98+
99+
const gasPrice = await wallet.getGasPrice();
100+
const contract = new ethers.Contract(process.env.CONTRACTS_DIAMOND_PROXY_ADDR, utils.ZKSYNC_MAIN_ABI, wallet);
101+
const AMOUNT_TO_DEPOSIT = ethers.utils.parseEther('1000000000000');
102+
const expectedCost = await contract.l2TransactionBaseCost(
103+
gasPrice,
104+
DEPOSIT_L2_GAS_LIMIT,
105+
utils.DEFAULT_GAS_PER_PUBDATA_LIMIT
106+
);
107+
const overrides = {
108+
value: AMOUNT_TO_DEPOSIT.add(expectedCost)
109+
};
110+
111+
112+
let tx = await contract.requestL2Transaction(
113+
wallet.address,
114+
AMOUNT_TO_DEPOSIT,
115+
"0x",
116+
DEPOSIT_L2_GAS_LIMIT,
117+
800,
118+
[],
119+
wallet.address, overrides
120+
)
121+
let receipt = await tx.wait();
122+
console.log(receipt);
123+
}
124+
125+
126+
const testMailBox = async () => {
127+
let wallet = ethers.Wallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
128+
console.log("wallet: ", wallet.address);
129+
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
130+
wallet = wallet.connect(provider);
131+
console.log("balance: ", ethers.utils.formatEther(await wallet.getBalance()));
132+
const WETH = WETH9Factory.connect(WETH_ADDRESS, wallet);
133+
const L1ERC20Bridge = L1ERC20BridgeFactory.connect(L1_ERC20_BRIDGE_ADDRESS, wallet);
134+
const allowList = AllowListFactory.connect(await L1ERC20Bridge.allowList(), wallet);
135+
const zkSync = IZkSyncFactory.connect(ZKSYNC_ADDRESS, wallet);
136+
137+
console.log("testing requestL2Transaction...");
138+
const MailBox = MailboxFacetFactory.connect(MAILBOX_ADDRESS, wallet);
139+
const DEPOSIT_L2_GAS_LIMIT = 10_000_000;
140+
141+
const gasPrice = await wallet.getGasPrice();
142+
const contract = new ethers.Contract(process.env.CONTRACTS_DIAMOND_PROXY_ADDR, utils.ZKSYNC_MAIN_ABI, wallet);
143+
const AMOUNT_TO_DEPOSIT = ethers.utils.parseEther('1000000000000');
144+
const expectedCost = await contract.l2TransactionBaseCost(
145+
gasPrice,
146+
DEPOSIT_L2_GAS_LIMIT,
147+
utils.DEFAULT_GAS_PER_PUBDATA_LIMIT
148+
);
149+
const overrides = {
150+
value: AMOUNT_TO_DEPOSIT.add(expectedCost)
151+
};
152+
153+
154+
let tx = await contract.requestL2Transaction(
155+
ethers.constants.AddressZero,
156+
AMOUNT_TO_DEPOSIT,
157+
"0x",
158+
DEPOSIT_L2_GAS_LIMIT,
159+
800,
160+
[],
161+
wallet.address,
162+
overrides
163+
)
164+
let receipt = await tx.wait();
165+
console.log(receipt);
166+
}
167+
168+
const bridgeEthL1ToL2 = async () => {
169+
let wallet = ethers.Wallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
170+
console.log("Use wallet address : ", wallet.address);
171+
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
172+
wallet = wallet.connect(provider);
173+
const WETH = WETH9Factory.connect(WETH_ADDRESS, wallet);
174+
const l1Balance = await WETH.balanceOf(wallet.address);
175+
console.log("Current WETH balance on L1: ", ethers.utils.formatEther(l1Balance));
176+
177+
console.log("Approve ZKSync for spending WETH...");
178+
const zkSync = IZkSyncFactory.connect(ZKSYNC_ADDRESS, wallet);
179+
let tx = await WETH.approve(zkSync.address, ethers.utils.parseEther("9999999999"));
180+
await tx.wait();
181+
let allowance = await WETH.allowance(wallet.address, zkSync.address);
182+
console.log("allowance: ", ethers.utils.formatEther(allowance), "WETH");
183+
184+
console.log("Depositing ETH");
185+
const DEPOSIT_L2_GAS_LIMIT = 1_000_000;
186+
const gasPrice = await wallet.getGasPrice();
187+
const contract = new ethers.Contract(ZKSYNC_ADDRESS, utils.ZKSYNC_MAIN_ABI, wallet);
188+
const expectedCost = await contract.l2TransactionBaseCost(
189+
gasPrice,
190+
DEPOSIT_L2_GAS_LIMIT,
191+
utils.DEFAULT_GAS_PER_PUBDATA_LIMIT
192+
);
193+
194+
console.log("expectedCost: ", ethers.utils.formatEther(expectedCost));
195+
196+
const tx2 = await zkSync.requestL2Transaction(
197+
ethers.utils.parseEther("100000"),
198+
{
199+
l2Contract: '0x0000000000000000000000000000000000000000',
200+
l2Value: 0,
201+
gasAmount: ethers.utils.parseEther("1"),
202+
l2GasLimit: 1_000_000,
203+
l2GasPerPubdataByteLimit: 800
204+
205+
},
206+
'0x',
207+
[],
208+
wallet.address,
209+
{
210+
gasLimit: 210000,
211+
}
212+
)
213+
214+
let receipt = await tx2.wait();
215+
console.log(receipt);
216+
}
217+
218+
const getBalance = async () => {
219+
let wallet = ZKWallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
220+
const l2Provider = new ZkSyncProvider("http://127.0.0.1:3050");
221+
console.log("Check balance for wallet address : ", wallet.address);
222+
let balance = await l2Provider.getBalance(wallet.address)
223+
console.log("balance on l2: ", ethers.utils.formatEther(balance));
224+
225+
let wethBalance = await l2Provider.getBalance(wallet.address, "latest", L2WETH_ADDRESS);
226+
console.log("wethBalance on l2: ", ethers.utils.formatEther(wethBalance));
227+
228+
let ethBalance = await l2Provider.getBalance(wallet.address, "latest", L2ETH_ADDRESS);
229+
console.log("ethBalance on l2: ", ethers.utils.formatEther(ethBalance));
230+
231+
let l1wallet = ethers.Wallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
232+
const l1provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
233+
l1wallet = l1wallet.connect(l1provider);
234+
const WETH = WETH9Factory.connect(WETH_ADDRESS, l1wallet);
235+
const l1Balance = await WETH.balanceOf(l1wallet.address);
236+
console.log("Check balance for wallet address : ", wallet.address);
237+
console.log("wethbalance on l1: ", ethers.utils.formatEther(l1Balance), "WETH");
238+
const l1ethBalance = await l1provider.getBalance(l1wallet.address)
239+
console.log("ethbalance on l1: ", ethers.utils.formatEther(l1ethBalance), "ETH");
240+
241+
const proxyBalance = await WETH.balanceOf(ZKSYNC_ADDRESS);
242+
console.log("Diamon proxy WETH balance: ", ethers.utils.formatEther(proxyBalance), "WETH");
243+
244+
const ERC20 = TestnetERC20TokenFactory.connect(ERC20_ADDRESS, l1wallet);
245+
const l1erc20Balance = await ERC20.balanceOf(l1wallet.address);
246+
console.log("erc20 balance on l1: ", ethers.utils.formatEther(l1erc20Balance), "DAI");
247+
248+
}
249+
250+
const bridgeEthL2ToL1 = async () => {
251+
let zkwallet = ZKWallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
252+
console.log("wallet: ", zkwallet.address);
253+
const l2Provider = new ZkSyncProvider("http://127.0.0.1:3050");
254+
const l1Provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
255+
zkwallet = zkwallet.connect(l2Provider);
256+
zkwallet = zkwallet.connectToL1(l1Provider);
257+
const withdrawL2 = await zkwallet.withdraw({
258+
token: L2ETH_ADDRESS,
259+
amount: ethers.utils.parseEther("1"),
260+
to: zkwallet.address
261+
});
262+
263+
const receipt = await withdrawL2.waitFinalize();
264+
console.log("receipt: ", receipt.transactionHash);
265+
266+
const { l1BatchNumber, l2MessageIndex, l2TxNumberInBlock, message, sender, proof } =
267+
await zkwallet.finalizeWithdrawalParams(receipt.transactionHash, 0);
268+
269+
console.log("l1BatchNumber: ", l1BatchNumber);
270+
console.log("l2MessageIndex: ", l2MessageIndex);
271+
console.log("l2TxNumberInBlock: ", l2TxNumberInBlock);
272+
console.log("message: ", message);
273+
console.log("sender: ", sender);
274+
console.log("proof: ", proof);
275+
276+
let wallet = ethers.Wallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
277+
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
278+
wallet = wallet.connect(provider);
279+
const zkSync = IZkSyncFactory.connect(ZKSYNC_ADDRESS, wallet);
280+
281+
let tx = await zkSync.finalizeEthWithdrawal(
282+
l1BatchNumber,
283+
l2MessageIndex,
284+
l2TxNumberInBlock,
285+
message,
286+
proof,
287+
{
288+
gasLimit: 410000,
289+
}
290+
)
291+
292+
let finalizereceipt = await tx.wait();
293+
console.log(finalizereceipt);
294+
}
295+
296+
const bridgeERC20L1ToL2 = async () => {
297+
let wallet = ethers.Wallet.fromMnemonic(MNEMONIC, DERIVE_PATH);
298+
console.log("Use wallet address : ", wallet.address);
299+
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
300+
wallet = wallet.connect(provider);
301+
console.log("Current wallet balance on L2: ", ethers.utils.formatEther(await wallet.getBalance()));
302+
const L1ERC20Bridge = L1ERC20BridgeFactory.connect(L1_ERC20_BRIDGE_ADDRESS, wallet);
303+
304+
console.log("Approve Bridge for spending DAI...");
305+
const ERC20 = TestnetERC20TokenFactory.connect(ERC20_ADDRESS, wallet);
306+
let tx = await ERC20.approve(L1ERC20Bridge.address, ethers.utils.parseEther("9999999999"));
307+
await tx.wait();
308+
let allowance = await ERC20.allowance(wallet.address, L1ERC20Bridge.address);
309+
console.log("erc20 allowance: ", ethers.utils.formatEther(allowance), "DAI");
310+
311+
312+
console.log("Approve ZKSync for spending gas token...");
313+
const zkSync = IZkSyncFactory.connect(ZKSYNC_ADDRESS, wallet);
314+
const WETH = WETH9Factory.connect(WETH_ADDRESS, wallet);
315+
tx = await WETH.approve(zkSync.address, ethers.utils.parseEther("9999999999"));
316+
await tx.wait();
317+
allowance = await WETH.allowance(wallet.address, zkSync.address);
318+
console.log("gas token allowance allowance: ", ethers.utils.formatEther(allowance), "WETH");
319+
320+
const DEPOSIT_L2_GAS_LIMIT = 10_000_000;
321+
const gasPrice = await wallet.getGasPrice();
322+
const contract = new ethers.Contract(process.env.CONTRACTS_DIAMOND_PROXY_ADDR, utils.ZKSYNC_MAIN_ABI, wallet);
323+
const expectedCost = await contract.l2TransactionBaseCost(
324+
gasPrice,
325+
DEPOSIT_L2_GAS_LIMIT,
326+
utils.DEFAULT_GAS_PER_PUBDATA_LIMIT
327+
);
328+
329+
console.log("expectedCost: ", ethers.utils.formatEther(expectedCost));
330+
331+
332+
tx = await L1ERC20Bridge["deposit(address,address,uint256,uint256,uint256,address,uint256)"](
333+
wallet.address,
334+
ERC20_ADDRESS,
335+
ethers.utils.parseEther("100"),
336+
10_000_000,
337+
800,
338+
wallet.address,
339+
ethers.utils.parseEther("1"),
340+
{
341+
gasLimit: 410000,
342+
},
343+
)
344+
345+
let receipt = await tx.wait();
346+
console.log(receipt);
347+
}
348+
349+
350+
//prepare().then(() => {main()});
351+
352+
// mint token, set approval, set allowlist
353+
//prepare();
354+
355+
// call the bridge function
356+
//bridgeEthL1ToL2();
357+
358+
//getBalance();
359+
360+
//bridgeEthL2ToL1();
361+
362+
bridgeERC20L1ToL2();

0 commit comments

Comments
 (0)