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

chore: add tests for paymaster contracts using era-test-node-action #15

Merged
merged 3 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 27 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: run
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your steps have such nice capitalised titles and this one's just called "run" 😆


on:
pull_request:
branches: [main]
workflow_dispatch:
jobs:
tests:
name: unit-tests
strategy:
matrix:
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}

steps:
- name: Checkout Code
uses: actions/checkout@v3

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

- name: Install Dependencies
run: yarn install

- name: Run Tests
run: |
yarn ci:tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: We should consider always printing out the logs of era_test_node in case the tests fail

- name: Era Test Node Logs
  if: always()
  run: cat ./era_test_node.log

Copy link
Contributor Author

@dutterbutter dutterbutter Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if a job fails it would be best the user updates the action to use logs:debug and then make use of the log file (either cat or artifacts approach) which I don't think should be used by default?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to you really, but I'd also prefer the CI showing test logs by default

33 changes: 22 additions & 11 deletions contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,48 @@ import "@matterlabs/hardhat-zksync-solc";
import "@matterlabs/hardhat-zksync-verify";
import "@nomiclabs/hardhat-etherscan";

// dynamically changes endpoints for local tests
const zkSyncTestnet =
process.env.NODE_ENV == "test"
? {
const getNetworkConfig = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, we should use this in other examples too come to think of it

const env = process.env.DEPLOY_ENV || "local";
switch (env) {
case "local":
return {
url: "http://localhost:3050",
ethNetwork: "http://localhost:8545",
zksync: true,
// Verification endpoint for Goerli
verifyURL:
"https://zksync2-testnet-explorer.zksync.dev/contract_verification",
}
: {
};
case "ci":
return {
url: "http://127.0.0.1:8011",
ethNetwork: "goerli",
zksync: true,
};
case "testnet":
return {
url: "https://zksync2-testnet.zksync.dev",
ethNetwork: "goerli",
zksync: true,
// Verification endpoint for Goerli
verifyURL:
"https://zksync2-testnet-explorer.zksync.dev/contract_verification",
};
default:
throw new Error(`Unsupported DEPLOY_ENV: ${env}`);
}
};

const networkConfig = getNetworkConfig();

const config: HardhatUserConfig = {
zksolc: {
version: "latest", // can be defined like 1.3.x
version: "latest",
settings: {},
},
defaultNetwork: "zkSyncTestnet",
networks: {
hardhat: {
zksync: false,
},
zkSyncTestnet,
zkSyncTestnet: networkConfig,
},
solidity: {
version: "0.8.17",
Expand Down
3 changes: 2 additions & 1 deletion contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"zksync-web3": "^0.14.3"
},
"scripts": {
"test": "NODE_ENV=test hardhat test --network zkSyncTestnet",
"test": "NODE_ENV=local hardhat test --network zkSyncTestnet",
"ci:tests": "DEPLOY_ENV=ci hardhat test --network zkSyncTestnet --show-stack-traces",
"deploy": "hardhat deploy-zksync",
"greeter": "hardhat deploy-zksync --script greeter.ts",
"gasless": "hardhat deploy-zksync --script gaslessPaymaster.ts",
Expand Down
14 changes: 7 additions & 7 deletions contracts/test/allowlist.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { expect } from "chai";
import { Wallet, Provider, Contract, utils } from "zksync-web3";
import * as hre from "hardhat";
import hardhatConfig from "../hardhat.config";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import * as ethers from "ethers";

import { deployContract, fundAccount } from "./utils";
import { deployContract, fundAccount, setupDeployer } from "./utils";

// load env file
import dotenv from "dotenv";
dotenv.config();

// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";
const PRIVATE_KEY =
process.env.WALLET_PRIVATE_KEY ||
"0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110";

describe("AllowlistPaymaster", function () {
let provider: Provider;
Expand All @@ -24,10 +26,9 @@ describe("AllowlistPaymaster", function () {
let greeter: Contract;

before(async function () {
const deployUrl = hardhatConfig.networks.zkSyncTestnet.url;
// setup deployer
provider = Provider.getDefaultProvider();
wallet = new Wallet(PRIVATE_KEY, provider);
deployer = new Deployer(hre, wallet);
[provider, wallet, deployer] = setupDeployer(deployUrl, PRIVATE_KEY);
// setup new wallet
emptyWallet = Wallet.createRandom();
console.log(`Empty wallet's address: ${emptyWallet.address}`);
Expand Down Expand Up @@ -99,7 +100,6 @@ describe("AllowlistPaymaster", function () {
expect(e.message).to.include("Ownable: caller is not the owner");
}
});

it("should prevent non-allowed user from calling Greeter", async function () {
dutterbutter marked this conversation as resolved.
Show resolved Hide resolved
const notAllowedWallet = Wallet.createRandom().connect(provider);
try {
Expand Down
13 changes: 7 additions & 6 deletions contracts/test/erc20fixed.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { expect } from "chai";
import { Wallet, Provider, Contract, utils } from "zksync-web3";
import * as hre from "hardhat";
import hardhatConfig from "../hardhat.config";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import * as ethers from "ethers";

import { deployContract, fundAccount } from "./utils";
import { deployContract, fundAccount, setupDeployer } from "./utils";

// load env file
import dotenv from "dotenv";
dotenv.config();

// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";
const PRIVATE_KEY =
process.env.WALLET_PRIVATE_KEY ||
"0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110";

describe("ERC20fixedPaymaster", function () {
let provider: Provider;
Expand All @@ -24,10 +26,9 @@ describe("ERC20fixedPaymaster", function () {
let token: Contract;

before(async function () {
const deployUrl = hardhatConfig.networks.zkSyncTestnet.url;
// setup deployer
provider = Provider.getDefaultProvider();
wallet = new Wallet(PRIVATE_KEY, provider);
deployer = new Deployer(hre, wallet);
[provider, wallet, deployer] = setupDeployer(deployUrl, PRIVATE_KEY);
// setup new wallet
const emptyWallet = Wallet.createRandom();
console.log(`Empty wallet's address: ${emptyWallet.address}`);
Expand Down
14 changes: 7 additions & 7 deletions contracts/test/erc721gated.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { expect } from "chai";
import { Wallet, Provider, Contract, utils } from "zksync-web3";
import * as hre from "hardhat";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import * as ethers from "ethers";
import hardhatConfig from "../hardhat.config";

import { deployContract, fundAccount } from "./utils";
import { deployContract, fundAccount, setupDeployer } from "./utils";

// load env file
import dotenv from "dotenv";
dotenv.config();

// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";
const PRIVATE_KEY =
process.env.WALLET_PRIVATE_KEY ||
"0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110";

describe("ERC721gatedPaymaster", function () {
let provider: Provider;
Expand All @@ -25,11 +27,9 @@ describe("ERC721gatedPaymaster", function () {
let erc721: Contract;

before(async function () {
const deployUrl = hardhatConfig.networks.zkSyncTestnet.url;
// setup deployer
provider = Provider.getDefaultProvider();
wallet = new Wallet(PRIVATE_KEY, provider);
deployer = new Deployer(hre, wallet);

[provider, wallet, deployer] = setupDeployer(deployUrl, PRIVATE_KEY);
// setup new wallet
userWallet = Wallet.createRandom();
userWallet = new Wallet(userWallet.privateKey, provider);
Expand Down
13 changes: 7 additions & 6 deletions contracts/test/gasless.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { expect } from "chai";
import { Wallet, Provider, Contract, utils } from "zksync-web3";
import * as hre from "hardhat";
import hardhatConfig from "../hardhat.config";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import * as ethers from "ethers";

import { deployContract, fundAccount } from "./utils";
import { deployContract, fundAccount, setupDeployer } from "./utils";

// load env file
import dotenv from "dotenv";
dotenv.config();

// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";
const PRIVATE_KEY =
process.env.WALLET_PRIVATE_KEY ||
"0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110";

describe("GaslessPaymaster", function () {
let provider: Provider;
Expand All @@ -24,10 +26,9 @@ describe("GaslessPaymaster", function () {
let greeter: Contract;

before(async function () {
const deployUrl = hardhatConfig.networks.zkSyncTestnet.url;
// setup deployer
provider = Provider.getDefaultProvider();
wallet = new Wallet(PRIVATE_KEY, provider);
deployer = new Deployer(hre, wallet);
[provider, wallet, deployer] = setupDeployer(deployUrl, PRIVATE_KEY);
// setup new wallet
emptyWallet = Wallet.createRandom();
console.log(`Empty wallet's address: ${emptyWallet.address}`);
Expand Down
17 changes: 15 additions & 2 deletions contracts/test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Contract, Wallet } from "zksync-web3";
import { Contract, Wallet, Provider } from "zksync-web3";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import * as hre from "hardhat";
import * as ethers from "ethers";

async function deployContract(
Expand Down Expand Up @@ -28,4 +29,16 @@ async function fundAccount(wallet: Wallet, address: string, amount: string) {
console.log(`Account ${address} funded with ${amount}`);
}

export { deployContract, fundAccount };
function setupDeployer(
url: string,
privateKey: string,
): [Provider, Wallet, Deployer] {
// setup deployer
const provider = new Provider(url);
const wallet = new Wallet(privateKey, provider);
const deployer = new Deployer(hre, wallet);

return [provider, wallet, deployer];
}

export { deployContract, fundAccount, setupDeployer };
94 changes: 86 additions & 8 deletions frontend/src/components/PaymasterMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,99 @@ const PaymasterMessage = ({

switch (selectedPaymaster) {
case "Allowlist Paymaster 📜":
message =
<> <p>You've selected the Allowlist Paymaster. Let's see if you are on the list! 📜</p> <br/><p className="flex-wrap max-w-4xl ">The Allowlist Paymaster uses the <span className="font-bold">general paymaster flow</span> which should be used if no prior actions are required from the user for the paymaster to operate. For more information, proceed to our docs <a className="text-cyan-400" href="https://era.zksync.io/docs/reference/concepts/aa.html#general-paymaster-flow">here.</a></p></>;
message = (
<>
{" "}
<p>
You've selected the Allowlist Paymaster. Let's see if you are on the
list! 📜
</p>{" "}
<br />
<p className="flex-wrap max-w-4xl ">
The Allowlist Paymaster uses the{" "}
<span className="font-bold">general paymaster flow</span> which
should be used if no prior actions are required from the user for
the paymaster to operate. For more information, proceed to our docs{" "}
<a
className="text-cyan-400"
href="https://era.zksync.io/docs/reference/concepts/aa.html#general-paymaster-flow"
>
here.
</a>
</p>
</>
);
break;
case "Gasless Paymaster 🆓":
message =
<><p>You've selected the Gasless Paymaster. Things are going to be cheap for you!</p> <br/><p className="flex-wrap max-w-4xl ">The Gasless Paymaster uses the <span className="font-bold">general paymaster flow</span> which should be used if no prior actions are required from the user for the paymaster to operate. For more information, proceed to our docs <a className="text-cyan-400" href="https://era.zksync.io/docs/reference/concepts/aa.html#general-paymaster-flow">here.</a></p></>;
message = (
<>
<p>
You've selected the Gasless Paymaster. Things are going to be cheap
for you!
</p>{" "}
<br />
<p className="flex-wrap max-w-4xl ">
The Gasless Paymaster uses the{" "}
<span className="font-bold">general paymaster flow</span> which
should be used if no prior actions are required from the user for
the paymaster to operate. For more information, proceed to our docs{" "}
<a
className="text-cyan-400"
href="https://era.zksync.io/docs/reference/concepts/aa.html#general-paymaster-flow"
>
here.
</a>
</p>
</>
);
break;
case "ERC20Fixed Paymaster 🎫":
message =
<><p>You've selected the ERC20Fixed Paymaster. You will need to input the token contract address that is required for the paymaster.</p> <br/><p className="flex-wrap max-w-4xl ">The ERC20Fixed Paymaster uses the <span className="font-bold">approval-based paymaster flow</span> which should be used if the user is required to set certain allowance to a token for the paymaster to operate. For more information, proceed to our docs <a className="text-cyan-400" href="https://era.zksync.io/docs/reference/concepts/aa.html#built-in-paymaster-flows">here.</a></p></>;
message = (
<>
<p>
You've selected the ERC20Fixed Paymaster. You will need to input the
token contract address that is required for the paymaster.
</p>{" "}
<br />
<p className="flex-wrap max-w-4xl ">
The ERC20Fixed Paymaster uses the{" "}
<span className="font-bold">approval-based paymaster flow</span>{" "}
which should be used if the user is required to set certain
allowance to a token for the paymaster to operate. For more
information, proceed to our docs{" "}
<a
className="text-cyan-400"
href="https://era.zksync.io/docs/reference/concepts/aa.html#built-in-paymaster-flows"
>
here.
</a>
</p>
</>
);
additionalInputNeeded = true;
break;
case "ERC721Gated Paymaster 🎨":
message =
<><p>You've selected the ERC721Gated Paymaster. You will need to input the NFT contract address that is gating the paymaster.</p> <br/><p className="flex-wrap max-w-4xl ">The ERC721Gated Paymaster uses the <span className="font-bold">general paymaster flow</span> which should be used if no prior actions are required from the user for the paymaster to operate. For more information, proceed to our docs <a className="text-cyan-400" href="https://era.zksync.io/docs/reference/concepts/aa.html#general-paymaster-flow">here.</a></p></>;
message = (
<>
<p>
You've selected the ERC721Gated Paymaster. You will need to input
the NFT contract address that is gating the paymaster.
</p>{" "}
<br />
<p className="flex-wrap max-w-4xl ">
The ERC721Gated Paymaster uses the{" "}
<span className="font-bold">general paymaster flow</span> which
should be used if no prior actions are required from the user for
the paymaster to operate. For more information, proceed to our docs{" "}
<a
className="text-cyan-400"
href="https://era.zksync.io/docs/reference/concepts/aa.html#general-paymaster-flow"
>
here.
</a>
</p>
</>
);
additionalInputNeeded = true;
break;
default:
Expand Down
Loading