endstep2
This commit is contained in:
@@ -0,0 +1,119 @@
|
|||||||
|
---
|
||||||
|
name: hardhat-toolbox-mocha-ethers
|
||||||
|
description: Use alongside the `hardhat` skill when the project depends on `@nomicfoundation/hardhat-toolbox-mocha-ethers`. Covers the ethers helpers exposed on `network.create()`, contract interaction (`ethers.deployContract`, calling functions, `connect`), TypeChain-typed contract instances, and the chai matchers from `@nomicfoundation/hardhat-ethers-chai-matchers` (`.to.emit`, `.to.be.revertedWith*`, `.to.changeEtherBalance(s)`).
|
||||||
|
metadata:
|
||||||
|
package: "@nomicfoundation/hardhat-toolbox-mocha-ethers"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hardhat toolbox: ethers + Mocha
|
||||||
|
|
||||||
|
This skill builds on the core **`hardhat`** skill. Load that first for test organization, the `network.create()` shape, `networkHelpers`, fixtures, and the typechecking workflow. Everything below hangs off the connection returned by `network.create()`.
|
||||||
|
|
||||||
|
This stack runs tests under **Mocha** (global `describe` / `it`) and asserts with **chai**. Mocha doesn't await `describe` callbacks, so the connection is set up at the top of the file with top-level `await`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { expect } from "chai";
|
||||||
|
import { network } from "hardhat";
|
||||||
|
|
||||||
|
const { ethers, networkHelpers } = await network.create();
|
||||||
|
|
||||||
|
describe("Counter", function () {
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
One connection per file is the norm. State isolation between tests comes from `loadFixture` (see the `hardhat` skill), not from creating a fresh connection per `describe`.
|
||||||
|
|
||||||
|
## `ethers`: signers and contract interaction
|
||||||
|
|
||||||
|
Contract types are generated by **TypeChain** from the compiled ABI. Run `hardhat build` before typechecking so the types reflect the latest contracts.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Provider (read-only chain data)
|
||||||
|
const blockNumber = await ethers.provider.getBlockNumber();
|
||||||
|
const balance = await ethers.provider.getBalance("0xabc...");
|
||||||
|
|
||||||
|
// Signers (for sending transactions)
|
||||||
|
const [owner, alice, bob] = await ethers.getSigners(); // default funded accounts
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
const oneEth = ethers.parseEther("1.0");
|
||||||
|
|
||||||
|
// Deploy a contract, returns a fully typed instance.
|
||||||
|
// Pass constructor args as the second argument, and (optionally) a signer
|
||||||
|
// other than the default as the third.
|
||||||
|
const counter = await ethers.deployContract("Counter");
|
||||||
|
const counterWithArgs = await ethers.deployContract("Counter", [42n]);
|
||||||
|
const counterFromAlice = await ethers.deployContract("Counter", [], alice);
|
||||||
|
|
||||||
|
// Read state and call functions. Args and return types are type-checked
|
||||||
|
// against the ABI at compile time; passing wrong types or wrong argument
|
||||||
|
// counts is a TypeScript error.
|
||||||
|
const value = await counter.x();
|
||||||
|
await counter.inc();
|
||||||
|
await counter.incBy(3n);
|
||||||
|
|
||||||
|
// Send from a different signer
|
||||||
|
await counter.connect(alice).inc();
|
||||||
|
|
||||||
|
// Send ETH along with a payable call
|
||||||
|
await counter.deposit({ value: oneEth });
|
||||||
|
|
||||||
|
// Attach to an already-deployed contract
|
||||||
|
const existing = await ethers.getContractAt("Counter", "0xabc...");
|
||||||
|
```
|
||||||
|
|
||||||
|
Inside a `loadFixture` setup function (see the `hardhat` skill for the surrounding pattern), `ethers.deployContract` is the canonical deploy step:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
async function deployCounterFixture() {
|
||||||
|
const counter = await ethers.deployContract("Counter");
|
||||||
|
return { counter };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { counter } = await networkHelpers.loadFixture(deployCounterFixture);
|
||||||
|
```
|
||||||
|
|
||||||
|
To send a transaction from an arbitrary address (not one of the default-funded accounts), fund it for gas and pull an impersonating signer with `ethers.getImpersonatedSigner` — it handles the impersonation internally, no separate `networkHelpers.impersonateAccount` call needed:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const addr = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||||
|
await networkHelpers.setBalance(addr, ethers.parseEther("1.0"));
|
||||||
|
const signer = await ethers.getImpersonatedSigner(addr);
|
||||||
|
await counter.connect(signer).inc();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Chai matchers: Ethereum-specific assertions
|
||||||
|
|
||||||
|
The `hardhat-ethers-chai-matchers` plugin extends chai's `expect` with matchers for transactions, events, and balance changes. Pass the **transaction promise** (the result of a write call, unawaited) into `expect`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
// Reverts
|
||||||
|
await expect(counter.connect(banned).inc()).to.revert(ethers);
|
||||||
|
await expect(counter.connect(banned).inc()).to.be.revertedWith(
|
||||||
|
"only the owner can increment the counter",
|
||||||
|
);
|
||||||
|
await expect(counter.connect(banned).inc()).to.be.revertedWithCustomError(
|
||||||
|
counter,
|
||||||
|
"Unauthorized",
|
||||||
|
);
|
||||||
|
await expect(counter.connect(banned).inc())
|
||||||
|
.to.be.revertedWithCustomError(counter, "Unauthorized")
|
||||||
|
.withArgs(banned.address);
|
||||||
|
|
||||||
|
// Events
|
||||||
|
await expect(counter.inc()).to.emit(counter, "Increment");
|
||||||
|
await expect(counter.inc()).to.emit(counter, "Increment").withArgs(1n);
|
||||||
|
|
||||||
|
// ETH balance changes (positive = received, negative = spent, before gas)
|
||||||
|
await expect(game.claim()).to.changeEtherBalance(ethers, winner, PRIZE);
|
||||||
|
await expect(game.claim()).to.changeEtherBalances(
|
||||||
|
ethers,
|
||||||
|
[winner, loser],
|
||||||
|
[PRIZE, -STAKE],
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
For plain assertions (equality, arrays, types), use `expect` from chai directly without the Ethereum matchers.
|
||||||
152
tokenizerRendu/code/.agents/skills/hardhat/SKILL.md
Normal file
152
tokenizerRendu/code/.agents/skills/hardhat/SKILL.md
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
---
|
||||||
|
name: hardhat
|
||||||
|
description: Use when working with Hardhat 3 projects — writing or modifying Solidity tests, TypeScript tests, or any code touching hardhat.config.ts, the `hardhat` import, or `network.create()`. Covers test-layer choice, forge-std cheatcodes, the network connection API, `networkHelpers`, and the compile-then-typecheck workflow. For toolbox-specific guidance (clients, contract calls, assertions), also load the matching `hardhat-toolbox-*` skill.
|
||||||
|
metadata:
|
||||||
|
package: "hardhat"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hardhat 3
|
||||||
|
|
||||||
|
This skill covers Hardhat 3 itself. The toolbox layer (clients, contract interaction, ecosystem-specific assertions) lives in companion skills — load whichever matches the project:
|
||||||
|
|
||||||
|
- `@nomicfoundation/hardhat-toolbox-viem` → also load the **`hardhat-toolbox-viem`** skill.
|
||||||
|
- `@nomicfoundation/hardhat-toolbox-mocha-ethers` → also load the **`hardhat-toolbox-mocha-ethers`** skill.
|
||||||
|
|
||||||
|
## Test organization
|
||||||
|
|
||||||
|
Hardhat 3 supports two distinct test layers:
|
||||||
|
|
||||||
|
**Solidity tests** (`.t.sol` files in `contracts/`, or any `.sol` file in `test/`) are the default choice for unit tests on individual contracts. They run directly in the EVM, compile-check against the real ABI, and have access to cheatcodes for EVM state manipulation. Any public function whose name starts with `test` is executed as a test case.
|
||||||
|
|
||||||
|
**TypeScript tests** (`.ts` files in `test/`) are the right choice when a test requires off-chain orchestration: multi-contract interactions, fixture reuse across a large suite, assertions about gas or ETH balances from the outside, or integration scenarios driven by external state.
|
||||||
|
|
||||||
|
Reach for TypeScript only when Solidity isn't enough. Solidity tests cover all contract logic; TypeScript tests cover the end-to-end flow as a user or script would experience it.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hardhat test # run all tests (Solidity + TypeScript)
|
||||||
|
hardhat test solidity # Solidity tests only
|
||||||
|
```
|
||||||
|
|
||||||
|
TypeScript tests are run either with `hardhat test nodejs` or with `hardhat test mocha`, depending on the toolbox or plugins being used: the viem-based toolbox uses `nodejs` while the ethers+mocha toolbox uses `mocha`.
|
||||||
|
|
||||||
|
Pass `--coverage` to collect Solidity coverage while running tests. It works on the main `hardhat test` task as well as the `solidity` and TypeScript subtasks (`nodejs` / `mocha`), so you can scope coverage to a single test layer when needed.
|
||||||
|
|
||||||
|
## Solidity tests
|
||||||
|
|
||||||
|
Any contract that contains at least one `test*` function is treated as a test contract. Use `forge-std` (if present in `package.json`) for assertions and cheatcodes:
|
||||||
|
|
||||||
|
```solidity
|
||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity ^0.8.28;
|
||||||
|
|
||||||
|
import { Test } from "forge-std/Test.sol";
|
||||||
|
import { Counter } from "./Counter.sol";
|
||||||
|
|
||||||
|
contract CounterTest is Test {
|
||||||
|
Counter counter;
|
||||||
|
|
||||||
|
function setUp() public {
|
||||||
|
counter = new Counter();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_InitialValueIsZero() public view {
|
||||||
|
assertEq(counter.x(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_IncByIncreasesByAmount() public {
|
||||||
|
counter.incBy(3);
|
||||||
|
assertEq(counter.x(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fuzz test: Hardhat runs this with many random inputs automatically
|
||||||
|
function testFuzz_Inc(uint8 x) public {
|
||||||
|
for (uint8 i = 0; i < x; i++) {
|
||||||
|
counter.inc();
|
||||||
|
}
|
||||||
|
require(counter.x() == x, "Value after calling inc x times should be x");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `vm` object (from `forge-std/Test.sol`) exposes cheatcodes for EVM state manipulation. Commonly used ones:
|
||||||
|
|
||||||
|
| Cheatcode | Effect |
|
||||||
|
| --- | --- |
|
||||||
|
| `vm.prank(addr)` | Sets `msg.sender` for the next call only |
|
||||||
|
| `vm.startPrank(addr)` / `vm.stopPrank()` | Sets `msg.sender` for a range of calls |
|
||||||
|
| `vm.deal(addr, amount)` | Sets an account's ETH balance |
|
||||||
|
| `vm.warp(timestamp)` | Sets `block.timestamp` |
|
||||||
|
| `vm.roll(blockNum)` | Sets `block.number` |
|
||||||
|
| `vm.expectRevert(...)` | Asserts the next call reverts |
|
||||||
|
| `vm.expectEmit(...)` | Asserts the next call emits a specific event |
|
||||||
|
|
||||||
|
## TypeScript tests and the network connection
|
||||||
|
|
||||||
|
The central object in a TypeScript test is the **network connection**, created by `network.create()`. Toolbox plugins extend it with helper objects (e.g. `viem` or `ethers`, plus `networkHelpers`):
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { network } from "hardhat";
|
||||||
|
|
||||||
|
const { networkHelpers } = await network.create();
|
||||||
|
// Toolbox plugins also expose viem / ethers on this object;
|
||||||
|
// see the matching hardhat-toolbox-* skill.
|
||||||
|
```
|
||||||
|
|
||||||
|
Hardhat 3 only works with ESM, so top-level `await` is available. Each call to `network.create()` produces an **isolated blockchain state**. A top-level network connection can be used when the same connection and its associated state can be shared across all tests in the file. For more isolation, you can create a new connection for each test suite or even each test case.
|
||||||
|
|
||||||
|
### `networkHelpers`: EVM state manipulation
|
||||||
|
|
||||||
|
`networkHelpers` wraps all of Hardhat's development-only helpers behind a typed, ergonomic API. Prefer it over raw JSON-RPC calls:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Time
|
||||||
|
await networkHelpers.time.increase(60); // mine a block 60 s ahead
|
||||||
|
await networkHelpers.time.increaseTo(target); // mine to a specific timestamp
|
||||||
|
const now = await networkHelpers.time.latest(); // latest block timestamp
|
||||||
|
await networkHelpers.time.setNextBlockTimestamp(ts); // set without mining
|
||||||
|
|
||||||
|
// Blocks
|
||||||
|
await networkHelpers.mine(); // mine one block
|
||||||
|
await networkHelpers.mine(5); // mine several blocks
|
||||||
|
|
||||||
|
// Accounts
|
||||||
|
await networkHelpers.impersonateAccount(addr);
|
||||||
|
await networkHelpers.setBalance(addr, 10n ** 18n);
|
||||||
|
|
||||||
|
// Block parameters
|
||||||
|
await networkHelpers.setPrevRandao(value); // set block.prevrandao for the next block
|
||||||
|
await networkHelpers.setNextBlockBaseFeePerGas(baseFee);
|
||||||
|
|
||||||
|
// Fixtures
|
||||||
|
//
|
||||||
|
// loadFixture runs the setup once and snapshots the state. Subsequent calls
|
||||||
|
// restore the snapshot instead of re-deploying, much faster for large suites.
|
||||||
|
// The deploy step inside the fixture is toolbox-specific (e.g.
|
||||||
|
// viem.deployContract, an ethers ContractFactory) — see the matching
|
||||||
|
// hardhat-toolbox-* skill.
|
||||||
|
async function deployCounter() {
|
||||||
|
// ... toolbox-specific deploy ...
|
||||||
|
return { counter };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { counter } = await networkHelpers.loadFixture(deployCounter);
|
||||||
|
// loadFixture requires a named function for caching to work (not an
|
||||||
|
// arrow/anonymous function)
|
||||||
|
|
||||||
|
// Snapshots (manual)
|
||||||
|
const snap = await networkHelpers.takeSnapshot();
|
||||||
|
// ... do things ...
|
||||||
|
await snap.restore();
|
||||||
|
```
|
||||||
|
|
||||||
|
For plain TypeScript assertions (equality, arrays, types), use `node:assert/strict`. For ecosystem-specific assertions (reverts, events, balance changes), see the matching `hardhat-toolbox-*` skill.
|
||||||
|
|
||||||
|
## Typechecking
|
||||||
|
|
||||||
|
Generated contract types are derived from the compiled ABI (viem in the viem toolbox, TypeChain in the ethers toolbox), so recompile first, then typecheck. The example below uses npm; swap `npx` for whichever package manager runner this project uses:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx hardhat build && npx tsc --noEmit
|
||||||
|
```
|
||||||
|
|
||||||
|
The compiler will catch wrong argument types, missing arguments, and invalid options (e.g. `value` on a non-payable function) before you even start the test runner. Make this a habit: it surfaces many mistakes faster than running the full test suite.
|
||||||
1
tokenizerRendu/code/.claude
Symbolic link
1
tokenizerRendu/code/.claude
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
.agents
|
||||||
2
tokenizerRendu/code/.env.example
Normal file
2
tokenizerRendu/code/.env.example
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
BSC_TESTNET_RPC=https://data-seed-prebsc-1-s1.binance.org:8545/
|
||||||
|
PRIVATE_KEY=
|
||||||
31
tokenizerRendu/code/.gitignore
vendored
Normal file
31
tokenizerRendu/code/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Node modules
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# Compilation output
|
||||||
|
/dist
|
||||||
|
|
||||||
|
# pnpm deploy output
|
||||||
|
/bundle
|
||||||
|
|
||||||
|
# Hardhat Build Artifacts
|
||||||
|
/artifacts
|
||||||
|
|
||||||
|
# Hardhat compilation (v2) support directory
|
||||||
|
/cache
|
||||||
|
|
||||||
|
# Typechain output
|
||||||
|
/types
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Hardhat coverage reports
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# Gas snapshot files
|
||||||
|
/.gas-snapshot
|
||||||
|
|
||||||
|
# Snapshot cheatcodes output
|
||||||
|
/snapshots
|
||||||
22
tokenizerRendu/code/.npmignore
Normal file
22
tokenizerRendu/code/.npmignore
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Node modules
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# Compilation output
|
||||||
|
/dist
|
||||||
|
|
||||||
|
# pnpm deploy output
|
||||||
|
/bundle
|
||||||
|
|
||||||
|
# Hardhat Build Artifacts
|
||||||
|
/artifacts
|
||||||
|
|
||||||
|
# Hardhat compilation (v2) support directory
|
||||||
|
/cache
|
||||||
|
|
||||||
|
# Typechain output
|
||||||
|
/types
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
20
tokenizerRendu/code/AGENTS.md
Normal file
20
tokenizerRendu/code/AGENTS.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Hardhat + ethers project
|
||||||
|
|
||||||
|
## Project layout
|
||||||
|
|
||||||
|
```
|
||||||
|
contracts/ Solidity source files (*.sol) and unit tests (*.t.sol)
|
||||||
|
test/ TypeScript integration tests and Solidity unit tests (*.sol)
|
||||||
|
ignition/ Hardhat Ignition deployment modules
|
||||||
|
scripts/ Standalone scripts run with `hardhat run`
|
||||||
|
hardhat.config.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Working in this project
|
||||||
|
|
||||||
|
When writing or modifying tests, configuring `hardhat.config.ts`, or interacting with the network from TypeScript, invoke the **`hardhat`** skill. It covers Solidity and TypeScript testing, how to choose between them, `forge-std` cheatcodes, the `network.create()` API, `networkHelpers`, and the compile-then-typecheck workflow. The skill itself points to the matching `hardhat-toolbox-*` skill for toolbox-specific guidance (signers, contract interaction, assertions).
|
||||||
|
|
||||||
|
## Docs
|
||||||
|
|
||||||
|
- Hardhat 3 — https://hardhat.org/llms.txt
|
||||||
|
- ethers.js — https://docs.ethers.org/v6/
|
||||||
1
tokenizerRendu/code/CLAUDE.md
Symbolic link
1
tokenizerRendu/code/CLAUDE.md
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
AGENTS.md
|
||||||
@@ -1,14 +1,75 @@
|
|||||||
# Code — smart contract(s)
|
# Code — FGC42Forge (Hardhat 3)
|
||||||
|
|
||||||
Place ici les sources du token (ex. `contracts/`, `hardhat.config.js`, tests).
|
Sources du token **FGC42Forge** (symbole **FG42**), standard **BEP-20**, déploiement prévu sur **BNB Smart Chain Testnet** (chainId **97**).
|
||||||
|
|
||||||
**Exigences sujet :** code commenté, noms de variables et fonctions explicites, standard **BEP-20** (ou équivalent documenté).
|
Stack : **Solidity**, **Hardhat 3**, **OpenZeppelin**, tests **Mocha + ethers** et tests Solidity (`.t.sol`).
|
||||||
|
|
||||||
## Commandes (à compléter)
|
> Le contrat `FGC42Forge.sol` sera ajouté à l’étape 3. Le dossier contient encore l’exemple **Counter** généré par `npx hardhat --init`.
|
||||||
|
|
||||||
```bash
|
## Prérequis
|
||||||
# Exemple Hardhat — adapter
|
|
||||||
|
- Node.js ≥ 18 (Hardhat 3 recommande v22+)
|
||||||
|
- Compte testnet avec **tBNB** (ex. MetaMask, réseau BSC Testnet)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd code
|
||||||
npm install
|
npm install
|
||||||
npx hardhat compile
|
```
|
||||||
|
|
||||||
|
## Variables d’environnement
|
||||||
|
|
||||||
|
Copier le modèle et remplir les valeurs **localement** (ne jamais committer `.env`) :
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `BSC_TESTNET_RPC` | URL RPC du testnet BSC (défaut dans `.env.example`) |
|
||||||
|
| `PRIVATE_KEY` | Clé privée du compte de **test** uniquement (préfixe `0x`) |
|
||||||
|
|
||||||
|
Hardhat lit ces variables via `hardhat.config.ts` et `dotenv`.
|
||||||
|
|
||||||
|
## Commandes utiles
|
||||||
|
|
||||||
|
Compiler les contrats :
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npx hardhat build
|
||||||
|
```
|
||||||
|
|
||||||
|
Lancer tous les tests (exemple Counter, en attendant FGC42Forge) :
|
||||||
|
|
||||||
|
```shell
|
||||||
npx hardhat test
|
npx hardhat test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Tests séparés :
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npx hardhat test solidity
|
||||||
|
npx hardhat test mocha
|
||||||
|
```
|
||||||
|
|
||||||
|
## Réseau `bscTestnet`
|
||||||
|
|
||||||
|
Le réseau **`bscTestnet`** est déclaré dans `hardhat.config.ts`. Pour un déploiement (plus tard, avec Ignition ou un script) :
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npx hardhat ignition deploy --network bscTestnet ignition/modules/<module>.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Remplacer le module par celui du token une fois le contrat prêt.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
contracts/ Contrats Solidity (+ tests .t.sol)
|
||||||
|
test/ Tests TypeScript (Mocha)
|
||||||
|
ignition/ Modules de déploiement Hardhat Ignition
|
||||||
|
scripts/ Scripts `hardhat run`
|
||||||
|
hardhat.config.ts
|
||||||
|
```
|
||||||
|
|||||||
19
tokenizerRendu/code/contracts/Counter.sol
Normal file
19
tokenizerRendu/code/contracts/Counter.sol
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity ^0.8.34;
|
||||||
|
|
||||||
|
contract Counter {
|
||||||
|
uint public x;
|
||||||
|
|
||||||
|
event Increment(uint by);
|
||||||
|
|
||||||
|
function inc() public {
|
||||||
|
x++;
|
||||||
|
emit Increment(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function incBy(uint by) public {
|
||||||
|
require(by > 0, "incBy: increment should be positive");
|
||||||
|
x += by;
|
||||||
|
emit Increment(by);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
tokenizerRendu/code/contracts/Counter.t.sol
Normal file
32
tokenizerRendu/code/contracts/Counter.t.sol
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity ^0.8.34;
|
||||||
|
|
||||||
|
import {Counter} from "./Counter.sol";
|
||||||
|
import {Test} from "forge-std/Test.sol";
|
||||||
|
|
||||||
|
// Solidity tests are compatible with foundry, so they
|
||||||
|
// use the same syntax and offer the same functionality.
|
||||||
|
|
||||||
|
contract CounterTest is Test {
|
||||||
|
Counter counter;
|
||||||
|
|
||||||
|
function setUp() public {
|
||||||
|
counter = new Counter();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_InitialValue() public view {
|
||||||
|
require(counter.x() == 0, "Initial value should be 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFuzz_Inc(uint8 x) public {
|
||||||
|
for (uint8 i = 0; i < x; i++) {
|
||||||
|
counter.inc();
|
||||||
|
}
|
||||||
|
require(counter.x() == x, "Value after calling inc x times should be x");
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_IncByZero() public {
|
||||||
|
vm.expectRevert();
|
||||||
|
counter.incBy(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
tokenizerRendu/code/hardhat.config.ts
Normal file
39
tokenizerRendu/code/hardhat.config.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import hardhatToolboxMochaEthersPlugin from "@nomicfoundation/hardhat-toolbox-mocha-ethers";
|
||||||
|
import { configVariable, defineConfig } from "hardhat/config";
|
||||||
|
import "dotenv/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [hardhatToolboxMochaEthersPlugin],
|
||||||
|
solidity: {
|
||||||
|
profiles: {
|
||||||
|
default: {
|
||||||
|
version: "0.8.34",
|
||||||
|
},
|
||||||
|
production: {
|
||||||
|
version: "0.8.34",
|
||||||
|
settings: {
|
||||||
|
optimizer: {
|
||||||
|
enabled: true,
|
||||||
|
runs: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
networks: {
|
||||||
|
hardhatMainnet: {
|
||||||
|
type: "edr-simulated",
|
||||||
|
chainType: "l1",
|
||||||
|
},
|
||||||
|
hardhatOp: {
|
||||||
|
type: "edr-simulated",
|
||||||
|
chainType: "op",
|
||||||
|
},
|
||||||
|
bscTestnet: {
|
||||||
|
type: "http",
|
||||||
|
chainType: "l1",
|
||||||
|
url: configVariable("BSC_TESTNET_RPC"),
|
||||||
|
accounts: [configVariable("PRIVATE_KEY")],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
9
tokenizerRendu/code/ignition/modules/Counter.ts
Normal file
9
tokenizerRendu/code/ignition/modules/Counter.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
||||||
|
|
||||||
|
export default buildModule("CounterModule", (m) => {
|
||||||
|
const counter = m.contract("Counter");
|
||||||
|
|
||||||
|
m.call(counter, "incBy", [5n]);
|
||||||
|
|
||||||
|
return { counter };
|
||||||
|
});
|
||||||
3089
tokenizerRendu/code/package-lock.json
generated
Normal file
3089
tokenizerRendu/code/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
33
tokenizerRendu/code/package.json
Normal file
33
tokenizerRendu/code/package.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "code",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Place ici les sources du token (ex. `contracts/`, `hardhat.config.js`, tests).",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@nomicfoundation/hardhat-ethers": "^4.2.1",
|
||||||
|
"@nomicfoundation/hardhat-ignition": "^3.1.9",
|
||||||
|
"@nomicfoundation/hardhat-toolbox": "^7.0.0",
|
||||||
|
"@nomicfoundation/hardhat-toolbox-mocha-ethers": "^4.0.0",
|
||||||
|
"@types/chai": "^5.2.3",
|
||||||
|
"@types/chai-as-promised": "^8.0.2",
|
||||||
|
"@types/mocha": "^10.0.10",
|
||||||
|
"@types/node": "^22.20.5",
|
||||||
|
"chai": "^6.3.0",
|
||||||
|
"ethers": "^6.17.0",
|
||||||
|
"forge-std": "github:foundry-rs/forge-std#v1.16.2",
|
||||||
|
"hardhat": "^3.20.0",
|
||||||
|
"mocha": "^12.0.3",
|
||||||
|
"typescript": "~6.0.3"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"@openzeppelin/contracts": "^5.6.1",
|
||||||
|
"dotenv": "^18.0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
22
tokenizerRendu/code/scripts/send-op-tx.ts
Normal file
22
tokenizerRendu/code/scripts/send-op-tx.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { network } from "hardhat";
|
||||||
|
|
||||||
|
const { ethers } = await network.create({
|
||||||
|
network: "hardhatOp",
|
||||||
|
chainType: "op",
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Sending transaction using the OP chain type");
|
||||||
|
|
||||||
|
const [sender] = await ethers.getSigners();
|
||||||
|
|
||||||
|
console.log("Sending 1 wei from", sender.address, "to itself");
|
||||||
|
|
||||||
|
console.log("Sending L2 transaction");
|
||||||
|
const tx = await sender.sendTransaction({
|
||||||
|
to: sender.address,
|
||||||
|
value: 1n,
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.wait();
|
||||||
|
|
||||||
|
console.log("Transaction sent successfully");
|
||||||
36
tokenizerRendu/code/test/Counter.ts
Normal file
36
tokenizerRendu/code/test/Counter.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
import { network } from "hardhat";
|
||||||
|
|
||||||
|
const { ethers } = await network.create();
|
||||||
|
|
||||||
|
describe("Counter", function () {
|
||||||
|
it("Should emit the Increment event when calling the inc() function", async function () {
|
||||||
|
const counter = await ethers.deployContract("Counter");
|
||||||
|
|
||||||
|
await expect(counter.inc()).to.emit(counter, "Increment").withArgs(1n);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("The sum of the Increment events should match the current value", async function () {
|
||||||
|
const counter = await ethers.deployContract("Counter");
|
||||||
|
const deploymentBlockNumber = await ethers.provider.getBlockNumber();
|
||||||
|
|
||||||
|
// run a series of increments
|
||||||
|
for (let i = 1; i <= 10; i++) {
|
||||||
|
await counter.incBy(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const events = await counter.queryFilter(
|
||||||
|
counter.filters.Increment(),
|
||||||
|
deploymentBlockNumber,
|
||||||
|
"latest",
|
||||||
|
);
|
||||||
|
|
||||||
|
// check that the aggregated events match the current value
|
||||||
|
let total = 0n;
|
||||||
|
for (const event of events) {
|
||||||
|
total += event.args.by;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(await counter.x()).to.equal(total);
|
||||||
|
});
|
||||||
|
});
|
||||||
11
tokenizerRendu/code/tsconfig.json
Normal file
11
tokenizerRendu/code/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["es2023"],
|
||||||
|
"module": "node20",
|
||||||
|
"target": "es2023",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"types": ["node", "mocha"],
|
||||||
|
"verbatimModuleSyntax": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user