Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit-tests for WETH token and WETH bridge #53

Merged
merged 5 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 86 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Lint
run: yarn lint

build:
build-l1:
runs-on: ubuntu-latest

defaults:
Expand Down Expand Up @@ -66,8 +66,44 @@ jobs:
ethereum/cache
ethereum/typechain

test-hardhat:
needs: [build, lint]
build-l2:
runs-on: ubuntu-latest

defaults:
run:
working-directory: zksync

steps:
- name: Checkout the repository
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 18.18.0
cache: yarn
cache-dependency-path: zksync/yarn.lock

- name: Install yarn
run: npm install -g yarn

- name: Install dependencies
run: yarn install

- name: Build artifacts
run: yarn build

- name: Create cache
uses: actions/cache/save@v3
with:
key: artifacts-zk-${{ github.sha }}
path: |
zksync/artifacts-zk
zksync/cache-zk
zksync/typechain

test-hardhat-l1:
needs: [build-l1, lint]
runs-on: ubuntu-latest

defaults:
Expand Down Expand Up @@ -104,8 +140,8 @@ jobs:
- name: Run tests
run: yarn test --no-compile

test-foundry:
needs: [build, lint]
test-foundry-l1:
needs: [build-l1, lint]
runs-on: ubuntu-latest

defaults:
Expand Down Expand Up @@ -146,3 +182,48 @@ jobs:

- name: Run tests
run: forge test

test-hardhat-l2:
needs: [build-l2]
runs-on: ubuntu-latest

defaults:
run:
working-directory: zksync

steps:
- name: Checkout the repository
uses: actions/checkout@v3
with:
submodules: "recursive"

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 16.15.1
ly0va marked this conversation as resolved.
Show resolved Hide resolved
cache: yarn
cache-dependency-path: zksync/yarn.lock

- name: Install yarn
run: npm install -g yarn

- name: Install dependencies
run: yarn install

- name: Restore artifacts cache
uses: actions/cache/restore@v3
with:
fail-on-cache-miss: true
key: artifacts-zk-${{ github.sha }}
path: |
zksync/artifacts-zk
zksync/cache-zk
zksync/typechain

- name: Run Era test node
uses: dutterbutter/era-test-node-action@latest

- name: Run tests
run: yarn hardhat test


8 changes: 6 additions & 2 deletions zksync/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import '@nomicfoundation/hardhat-chai-matchers';
import '@nomiclabs/hardhat-solpp';
import '@matterlabs/hardhat-zksync-solc';
import '@nomiclabs/hardhat-ethers';
Expand All @@ -20,9 +21,12 @@ export default {
solidity: {
version: '0.8.19'
},
defaultNetwork: 'hardhat',
defaultNetwork: 'localhost',
networks: {
hardhat: {
localhost: {
// era-test-node default url
url: 'http://127.0.0.1:8011',
ethNetwork: null,
zksync: true
},
zkSyncTestnet: {
Expand Down
7 changes: 5 additions & 2 deletions zksync/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
"version": "0.1.0",
"license": "MIT",
"devDependencies": {
"@matterlabs/hardhat-zksync-deploy": "^0.6.5",
"@matterlabs/hardhat-zksync-solc": "^0.3.15",
"@matterlabs/hardhat-zksync-verify": "^0.2.0",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.6",
"@nomicfoundation/hardhat-ethers": "^3.0.4",
"@nomicfoundation/hardhat-verify": "^1.1.0",
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
Expand All @@ -28,7 +31,7 @@
"ts-node": "^10.1.0",
"typechain": "^4.0.0",
"typescript": "^4.3.5",
"zksync-web3": "^0.14.3"
"zksync-web3": "^0.15.4"
},
"scripts": {
"build": "hardhat compile",
Expand All @@ -43,4 +46,4 @@
"dependencies": {
"dotenv": "^16.0.3"
}
}
}
109 changes: 109 additions & 0 deletions zksync/test/weth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { expect } from "chai";
import { Wallet, Provider } from "zksync-web3";
import * as hre from "hardhat";
import { ethers } from "ethers";
import { L2WethFactory } from "../typechain/L2WethFactory";
import { L2Weth} from "../typechain/L2Weth";
import { L2WethBridgeFactory } from "../typechain/L2WethBridgeFactory";
import { L2WethBridge } from "../typechain/L2WethBridge";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";

const richAccount = {
address: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
privateKey: "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110",
};

const eth18 = ethers.utils.parseEther("18");

describe("WETH token & WETH bridge", function () {
let provider = new Provider(hre.config.networks.localhost.url);
let wallet = new Wallet(richAccount.privateKey, provider);
let wethToken: L2Weth;
let wethBridge: L2WethBridge;

before("Deploy token and bridge", async function () {
const deployer = new Deployer(hre, wallet);
const wethTokenImpl = await deployer.deploy(await deployer.loadArtifact("L2Weth"));
const wethBridgeImpl = await deployer.deploy(await deployer.loadArtifact("L2WethBridge"));
const randomAddress = ethers.utils.hexlify(ethers.utils.randomBytes(20));

const wethTokenProxy = await deployer.deploy(
await deployer.loadArtifact("TransparentUpgradeableProxy"),
[wethTokenImpl.address, randomAddress, "0x"]
);
const wethBridgeProxy = await deployer.deploy(
await deployer.loadArtifact("TransparentUpgradeableProxy"),
[wethBridgeImpl.address, randomAddress, "0x"]
) as any;

wethToken = L2WethFactory.connect(wethTokenProxy.address, wallet);
wethBridge = L2WethBridgeFactory.connect(wethBridgeProxy.address, wallet);

await wethToken.initialize("Wrapped Ether", "WETH");
await wethToken.initializeV2(wethBridge.address, randomAddress);

await wethBridge.initialize(randomAddress, randomAddress, wethToken.address);
});

it("Should deposit WETH by calling deposit()", async function () {
await wethToken.deposit({ value: eth18 }).then(tx => tx.wait());
expect(await wethToken.balanceOf(wallet.address)).to.equal(eth18);
});

it("Should deposit WETH by sending", async function () {
ly0va marked this conversation as resolved.
Show resolved Hide resolved
await wallet.sendTransaction({
to: wethToken.address,
value: eth18
}).then(tx => tx.wait());
expect(await wethToken.balanceOf(wallet.address)).to.equal(eth18.mul(2));
});

it("Should withdraw WETH to L2 ETH", async function () {
await wethToken.withdraw(eth18).then(tx => tx.wait());
expect(await wethToken.balanceOf(wallet.address)).to.equal(eth18);
});

it("Should withdraw WETH to L1 ETH", async function () {
await expect(wethBridge.withdraw(wallet.address, wethToken.address, eth18.div(2)))
.to.emit(wethBridge, "WithdrawalInitiated")
.and.to.emit(wethToken, "BridgeBurn");
expect(await wethToken.balanceOf(wallet.address)).to.equal(eth18.div(2));
});

it("Should deposit WETH to another account", async function () {
const anotherWallet = new Wallet(ethers.utils.randomBytes(32), provider);
await wethToken.depositTo(anotherWallet.address, { value: eth18 }).then(tx => tx.wait());
expect(await wethToken.balanceOf(anotherWallet.address)).to.equal(eth18);
});

it("Should withdraw WETH to another account", async function () {
const anotherWallet = new Wallet(ethers.utils.randomBytes(32), provider);
await wethToken.withdrawTo(anotherWallet.address, eth18.div(2)).then(tx => tx.wait());
expect(await anotherWallet.getBalance()).to.equal(eth18.div(2));
expect(await wethToken.balanceOf(wallet.address)).to.equal(0);
});


it("Should fail withdrawing with insufficient balance", async function () {
await expect(wethToken.withdraw(1, { gasLimit: 100_000 }))
.to.be.reverted;
});

it("Should fail depositing directly to WETH bridge", async function () {
await expect(wallet.sendTransaction({
to: wethBridge.address,
value: eth18,
gasLimit: 100_000
})).to.be.reverted;
});

it("Should fail calling bridgeMint()", async function () {
await expect(wethToken.bridgeMint(wallet.address, eth18, { gasLimit: 100_000 })).
to.be.revertedWith(/Use deposit\/depositTo methods instead/);
});

it("Should fail calling bridgeBurn() directly", async function () {
await expect(wethToken.bridgeBurn(wallet.address, eth18, { gasLimit: 100_000 })).to.be.reverted;
});

});
Loading
Loading