Skip to content

Commit

Permalink
Merge pull request #53 from matter-labs/lyova-l2-contracts-unit-tests
Browse files Browse the repository at this point in the history
Add unit-tests for WETH token and WETH bridge
  • Loading branch information
vladbochok authored Oct 2, 2023
2 parents 2d18251 + 110a051 commit d8085ac
Show file tree
Hide file tree
Showing 5 changed files with 627 additions and 17 deletions.
93 changes: 87 additions & 6 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 All @@ -124,7 +160,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 16.15.1
node-version: 18.18.0
cache: yarn
cache-dependency-path: ethereum/yarn.lock

Expand All @@ -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: 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: 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"
}
}
}
118 changes: 118 additions & 0 deletions zksync/test/weth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
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 () {
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 fail depositing with random calldata", async function () {
await expect(wallet.sendTransaction({
data: ethers.utils.randomBytes(36),
to: wethToken.address,
value: eth18,
gasLimit: 100_000
})).to.be.reverted;
});

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

0 comments on commit d8085ac

Please sign in to comment.