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

feat: Foundry testing example #1

Closed
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ era_test_node.log
# misc
.DS_Store
*.pem

zkout/
cache_forge/
cache_hardhat-zk/
out/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ To run tests on a specific network:
yarn test [--network <network-name>]
```

For example, to run tests on the `lensTestnet` network:
For example, to run Hardhat tests (\*.test.ts) on the `lensTestnet` network:

```bash
yarn test --network lensTestnet
Expand All @@ -96,6 +96,34 @@ yarn test --network lensTestnet
> [!TIP]
> zkSync In-memory Node currently supports only the L2 node. If contracts also need L1, use another testing environment like [Dockerized Node](https://docs.zksync.io/build/test-and-debug/dockerized-l1-l2-nodes).

#### Testing With Foundry

A faster alternative for test running is to utilize Foundry to run tests on the Hardhat project.

First install the ZKSync Foundry library:

```bash
curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash
```

Switch to Foundry ZKSync version:

```bash
foundryup-zksync
```

To run Foundry tests (\*.t.sol) on the `lensTestnet` network, compile contract source:

```bash
FOUNDRY_PROFILE=zksync forge compile --zksync
```

Then run tests:

```bash
FOUNDRY_PROFILE=zksync forge test --zksync
```

### Deploy <!-- omit in toc -->

```bash
Expand Down
12 changes: 0 additions & 12 deletions contracts/Token.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
// It will be used by the Solidity compiler to validate its version.
pragma solidity ^0.8.20;

// We import this library to be able to use console.log
import "hardhat/console.sol";


// This is the main building block for smart contracts.
contract Token {
Expand Down Expand Up @@ -49,15 +46,6 @@ contract Token {
// transaction will revert.
require(balances[msg.sender] >= amount, "Not enough tokens");

// We can print messages and values using console.log, a feature of
// Hardhat Network:
console.log(
"Transferring from %s to %s %s tokens",
msg.sender,
to,
amount
);

// Transfer the amount.
balances[msg.sender] -= amount;
balances[to] += amount;
Expand Down
15 changes: 15 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']

[profile.zksync]
src = 'contracts'
solc-version = "0.8.24"
fallback_oz = true
is_system = false
mode = "3"
test = 'test'
script = 'script'
cache_path = 'cache_forge'
libs = ['node_modules', 'lib']
3 changes: 2 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "@matterlabs/hardhat-zksync";
import "@nomicfoundation/hardhat-chai-matchers";
import "@nomicfoundation/hardhat-toolbox";
import "@nomiclabs/hardhat-solhint";
import "@nomicfoundation/hardhat-foundry";

import { HardhatUserConfig } from "hardhat/config";

Expand All @@ -18,7 +19,7 @@ const config: HardhatUserConfig = {
lensTestnet: {
chainId: 37111,
ethNetwork: "sepolia", // or a Sepolia RPC endpoint from Infura/Alchemy/Chainstack etc.
url: "https://api.staging.lens.zksync.dev",
url: "https://rpc.testnet.lens.dev",
verifyURL:
"https://api-explorer-verify.staging.lens.zksync.dev/contract_verification",
zksync: true,
Expand Down
1 change: 1 addition & 0 deletions lib/forge-std
Submodule forge-std added at b93cf4
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@matterlabs/hardhat-zksync": "^1.1.0",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
"@nomicfoundation/hardhat-ethers": "^3.0.0",
"@nomicfoundation/hardhat-foundry": "^1.1.3",
"@nomicfoundation/hardhat-ignition": "^0.15.0",
"@nomicfoundation/hardhat-ignition-ethers": "^0.15.0",
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
Expand Down
58 changes: 58 additions & 0 deletions test/Token.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "forge-std/Test.sol";
import "../contracts/Token.sol";

contract TokenTest is Test {
Token token;
address owner;
address recipient;

event Transfer(address indexed from, address indexed to, uint256 value);

function setUp() public {
owner = vm.addr(1);
recipient = vm.addr(2);

vm.prank(owner);
token = new Token();
}

function testOwnerIsSetCorrectly() public {
assertEq(token.owner(), owner, "Owner should be set correctly");
}

function testTotalSupplyAssignedToOwner() public {
uint256 ownerBalance = token.balanceOf(owner);
assertEq(token.totalSupply(), ownerBalance, "Total supply should be assigned to owner");
}

function testTransferTokens() public {
uint256 initialBalance = token.balanceOf(owner);

vm.prank(owner);
token.transfer(recipient, 50);

assertEq(token.balanceOf(owner), initialBalance - 50, "Owner balance should decrease");
assertEq(token.balanceOf(recipient), 50, "Recipient balance should increase");
}

function testTransferEmitsEvent() public {
vm.prank(owner);
vm.expectEmit(true, true, false, true, address(token));
emit Transfer(owner, recipient, 50);
token.transfer(recipient, 50);
}

function testFailTransferWithoutEnoughTokens() public {
vm.prank(recipient);
token.transfer(owner, 1);
}

function testRevertTransferWithoutEnoughTokens() public {
vm.prank(recipient);
vm.expectRevert("Not enough tokens");
token.transfer(owner, 1);
}
}
103 changes: 61 additions & 42 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ __metadata:
version: 7.24.7
resolution: "@babel/code-frame@npm:7.24.7"
dependencies:
"@babel/highlight": ^7.24.7
picocolors: ^1.0.0
"@babel/highlight": "npm:^7.24.7"
picocolors: "npm:^1.0.0"
checksum: 830e62cd38775fdf84d612544251ce773d544a8e63df667728cc9e0126eeef14c6ebda79be0f0bc307e8318316b7f58c27ce86702e0a1f5c321d842eb38ffda4
languageName: node
linkType: hard
Expand All @@ -33,10 +33,10 @@ __metadata:
version: 7.24.7
resolution: "@babel/highlight@npm:7.24.7"
dependencies:
"@babel/helper-validator-identifier": ^7.24.7
chalk: ^2.4.2
js-tokens: ^4.0.0
picocolors: ^1.0.0
"@babel/helper-validator-identifier": "npm:^7.24.7"
chalk: "npm:^2.4.2"
js-tokens: "npm:^4.0.0"
picocolors: "npm:^1.0.0"
checksum: 5cd3a89f143671c4ac129960024ba678b669e6fc673ce078030f5175002d1d3d52bc10b22c5b916a6faf644b5028e9a4bd2bb264d053d9b05b6a98690f1d46f1
languageName: node
linkType: hard
Expand Down Expand Up @@ -933,6 +933,17 @@ __metadata:
languageName: node
linkType: hard

"@nomicfoundation/hardhat-foundry@npm:^1.1.3":
version: 1.1.3
resolution: "@nomicfoundation/hardhat-foundry@npm:1.1.3"
dependencies:
picocolors: "npm:^1.1.0"
peerDependencies:
hardhat: ^2.17.2
checksum: bfb24efb6479a92900f17374ce64844e49d5185c63aadf56794ef640381394391cb4c1689a967fca84d4483012811f18005879c2cfc2ac62bb34fb822b924a0d
languageName: node
linkType: hard

"@nomicfoundation/hardhat-ignition-ethers@npm:^0.15.0":
version: 0.15.5
resolution: "@nomicfoundation/hardhat-ignition-ethers@npm:0.15.5"
Expand Down Expand Up @@ -1137,7 +1148,7 @@ __metadata:
version: 3.1.0
resolution: "@nomiclabs/hardhat-solhint@npm:3.1.0"
dependencies:
solhint: ^3.4.0
solhint: "npm:^3.4.0"
peerDependencies:
hardhat: ^2.0.0
checksum: d53b8c273643adcf6f7afd94a4531c8c366edf698c9702c73b723bc6eea27db93a483a44d123516a917aca30b851c445297edbf85708d3d7be7401eed3ecebfc
Expand Down Expand Up @@ -1394,7 +1405,7 @@ __metadata:
version: 0.16.2
resolution: "@solidity-parser/parser@npm:0.16.2"
dependencies:
antlr4ts: ^0.5.0-alpha.4
antlr4ts: "npm:^0.5.0-alpha.4"
checksum: 109f7bec5de943c63e444fdde179d9bba6a592c18c836f585753798f428424cfcca72c715e7a345e4b79b83d6548543c9e56cb4b263e9b1e8352af2efcfd224a
languageName: node
linkType: hard
Expand Down Expand Up @@ -1723,10 +1734,10 @@ __metadata:
version: 6.12.6
resolution: "ajv@npm:6.12.6"
dependencies:
fast-deep-equal: ^3.1.1
fast-json-stable-stringify: ^2.0.0
json-schema-traverse: ^0.4.1
uri-js: ^4.2.2
fast-deep-equal: "npm:^3.1.1"
fast-json-stable-stringify: "npm:^2.0.0"
json-schema-traverse: "npm:^0.4.1"
uri-js: "npm:^4.2.2"
checksum: 874972efe5c4202ab0a68379481fbd3d1b5d0a7bd6d3cc21d40d3536ebff3352a2a1fabb632d4fd2cc7fe4cbdcd5ed6782084c9bbf7f32a1536d18f9da5007d4
languageName: node
linkType: hard
Expand Down Expand Up @@ -2659,10 +2670,10 @@ __metadata:
version: 8.3.6
resolution: "cosmiconfig@npm:8.3.6"
dependencies:
import-fresh: ^3.3.0
js-yaml: ^4.1.0
parse-json: ^5.2.0
path-type: ^4.0.0
import-fresh: "npm:^3.3.0"
js-yaml: "npm:^4.1.0"
parse-json: "npm:^5.2.0"
path-type: "npm:^4.0.0"
peerDependencies:
typescript: ">=4.9.5"
peerDependenciesMeta:
Expand Down Expand Up @@ -3063,7 +3074,7 @@ __metadata:
version: 1.3.2
resolution: "error-ex@npm:1.3.2"
dependencies:
is-arrayish: ^0.2.1
is-arrayish: "npm:^0.2.1"
checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001
languageName: node
linkType: hard
Expand Down Expand Up @@ -4329,8 +4340,8 @@ __metadata:
version: 3.3.0
resolution: "import-fresh@npm:3.3.0"
dependencies:
parent-module: ^1.0.0
resolve-from: ^4.0.0
parent-module: "npm:^1.0.0"
resolve-from: "npm:^4.0.0"
checksum: 2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa
languageName: node
linkType: hard
Expand Down Expand Up @@ -4855,6 +4866,7 @@ __metadata:
"@matterlabs/hardhat-zksync": ^1.1.0
"@nomicfoundation/hardhat-chai-matchers": ^2.0.0
"@nomicfoundation/hardhat-ethers": ^3.0.0
"@nomicfoundation/hardhat-foundry": ^1.1.3
"@nomicfoundation/hardhat-ignition": ^0.15.0
"@nomicfoundation/hardhat-ignition-ethers": ^0.15.0
"@nomicfoundation/hardhat-network-helpers": ^1.0.0
Expand Down Expand Up @@ -5630,7 +5642,7 @@ __metadata:
version: 1.0.1
resolution: "parent-module@npm:1.0.1"
dependencies:
callsites: ^3.0.0
callsites: "npm:^3.0.0"
checksum: 6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff
languageName: node
linkType: hard
Expand All @@ -5646,10 +5658,10 @@ __metadata:
version: 5.2.0
resolution: "parse-json@npm:5.2.0"
dependencies:
"@babel/code-frame": ^7.0.0
error-ex: ^1.3.1
json-parse-even-better-errors: ^2.3.0
lines-and-columns: ^1.1.6
"@babel/code-frame": "npm:^7.0.0"
error-ex: "npm:^1.3.1"
json-parse-even-better-errors: "npm:^2.3.0"
lines-and-columns: "npm:^1.1.6"
checksum: 62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2
languageName: node
linkType: hard
Expand Down Expand Up @@ -5747,6 +5759,13 @@ __metadata:
languageName: node
linkType: hard

"picocolors@npm:^1.1.0":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045
languageName: node
linkType: hard

"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1":
version: 2.3.1
resolution: "picomatch@npm:2.3.1"
Expand Down Expand Up @@ -6528,24 +6547,24 @@ __metadata:
version: 3.6.2
resolution: "solhint@npm:3.6.2"
dependencies:
"@solidity-parser/parser": ^0.16.0
ajv: ^6.12.6
antlr4: ^4.11.0
ast-parents: ^0.0.1
chalk: ^4.1.2
commander: ^10.0.0
cosmiconfig: ^8.0.0
fast-diff: ^1.2.0
glob: ^8.0.3
ignore: ^5.2.4
js-yaml: ^4.1.0
lodash: ^4.17.21
pluralize: ^8.0.0
prettier: ^2.8.3
semver: ^7.5.2
strip-ansi: ^6.0.1
table: ^6.8.1
text-table: ^0.2.0
"@solidity-parser/parser": "npm:^0.16.0"
ajv: "npm:^6.12.6"
antlr4: "npm:^4.11.0"
ast-parents: "npm:^0.0.1"
chalk: "npm:^4.1.2"
commander: "npm:^10.0.0"
cosmiconfig: "npm:^8.0.0"
fast-diff: "npm:^1.2.0"
glob: "npm:^8.0.3"
ignore: "npm:^5.2.4"
js-yaml: "npm:^4.1.0"
lodash: "npm:^4.17.21"
pluralize: "npm:^8.0.0"
prettier: "npm:^2.8.3"
semver: "npm:^7.5.2"
strip-ansi: "npm:^6.0.1"
table: "npm:^6.8.1"
text-table: "npm:^0.2.0"
dependenciesMeta:
prettier:
optional: true
Expand Down
Loading