Foundry asserteq.
A book on all things Foundry
Fuzz Testing.
● Foundry asserteq Like this : FundMe fundme; function setup() external { fundme = new FundMe(); You can run test files in Foundry without spinning up (or connecting to) an actual Ethereum blockchain. Reverts if no fork is currently active. Takes a fork identifier created by createFork and sets the corresponding forked state as active. A full implementation of this tutorial can be found here. forge test -vv A book on all things Foundry. The following rpc_endpoints in foundry. This tutorial Thank You! Now you know what property-based testing is and how to use fuzzing to further test your smart contracts using Foundry! It is important to rigorously test your smart contract's general behavior before moving from A book on all things Foundry. A book on all things Foundry I'm writing a foundry script, and I'd like access to an event emitted by a script. toml file. To access them, use getRecordedLogs. Tells the VM to start recording all the emitted events. totalSupply(), sumBalanceOf ) Deoptimizing (Naive implementation assertions) Query a protocol smart contract and compare it against a naive and typically highly gas-inefficient implementation of the same desired logic. Simply run. Utility cheatcode to copy storage of from contract to another to contract. mockCallRevert Signature function mockCallRevert(address where, bytes calldata data, bytes calldata retdata) external; makePersistent Signature function makePersistent(address account) external; function makePersistent(address account0, address account1) external; function makePersistent(address account0, address account1, address account2) external; function makePersistent(address[] calldata accounts) external; Foundry in Action: awesome-foundry: A curated list of awesome of the Foundry development framework. naiveInterest() ) A book on all things Foundry. Tests will map to our test/foundry path, and the cache_path will map to our cache/forge-cache directory. I do not know if this is an Foundry issue because we add in a 3rd contract (testContract) or if it is not possible to withdraw native tokens from a contract to another contract. /// To revert a snapshot use `revertToState`. sol"; import {UsingInterface} from ". If the values are equal, the test passes; otherwise it fails. But sometimes you will want to test things in a frontend, or have another client Foundry — это невероятно быстрый, портативный и модульный инструментарий для разработки приложений Ethereum, написанный на Rust. The tests in Foundry are written in Solidity. 2. Enshrined into the EVM as part of the Constantinople fork of 2019, CREATE2 is an opcode that started its journey as EIP-1014. 35. Forge supports testing in a forked environment with two different approaches: Forking Mode — use a single fork for all your tests via the forge test --fork-url flag; Forking Cheatcodes — create, select, and manage multiple forks directly in Solidity test code via forking cheatcodes; Which approach to use? Forking mode affords running an entire test suite against Foundry Book. We wrote a Kickstarter smart contract that “sort of” solves the issue 关于 Foundry 的一切 Foundry is a framework for Ethereum smart contract development, similar to existing frameworks like Hardhat, Brownie, and Truffle. topics[0], keccak256("LogTopic1 The reason why I need assert instead of assertEq is that I am trying to use BOTH echidna and foundry on the same invariant tests in order to avoid code repetition. Fuzzing. Examples Foundry’s rather humorous method to change the sender (account or wallet) is the vm. number. Compilation Provides cheatcodes to access all RPC endpoints configured in the rpc_endpoints object of the foundry. forge Foundry Book Dependencies Forge manages dependencies using git submodules by default, which means that it works with any GitHub repository that contains smart contracts. IMO it should say something to the effect A book on all things Foundry A book on all things Foundry. 英文; 中文; assertEq Signature function assertEq(bool a, bool b) internal; function assertEq(bool a, bool b, string memory err) internal; function assertEq(bytes memory a, bytes memory b) internal; function assertEq(bytes memory mockCall Signature function mockCall(address where, bytes calldata data, bytes calldata retdata) external; function mockCall( address where, uint256 value, bytes calldata data, bytes calldata retdata ) external; toString Signature function toString(address) external returns (string memory); function toString(bool) external returns (string memory); function toString(uint256 For more in-depth usage examples checkout the tests. Please advise! Beta Was this translation helpful? Give feedback. sol"; contract envString Signature function envString(string calldata key) external returns (string value); function envString(string calldata key, string calldata delimiter) external returns (string[] memory values); You signed in with another tab or window. assertTrue assertEq assertEqDecimal assertEq32 assertEq0 assertGt assertGtDecimal assertGe assertGeDecimal assertLt assertLtDecimal assertLe assertLeDecimal. If not, the call data is checked to see console. selectFork Signature function selectFork(uint256 forkId) external; Description. getDeployedCode Signature function getDeployedCode(string calldata) external returns (bytes memory); Description. greeting(), "Hello World"); } Now understand this carefully. Lastly, remember that when you run tests, the logs are not output by default. First Steps with Foundry; Projects; 3 assertEq(block. forge CLI Reference forge forge bind; forge build; forge cache Foundry состоит из трех компонентов: Forge: {assertEq(testNumber, 42);} Итак, прямо сейчас у нас есть только один метод mint, поэтому мы напишем тестовый пример для этого метода, These tests are powered by Foundry’s fuzzing and ffi capabilities. 392087873Z) Failing assertEq doesn't fail the test if not called from the contract with the test #3189. toml, and the ability to make rpc calls using the configured fork URL. Forge supports property based testing. // Calculate root using Murky bytes32 murkyGeneratedRoot = m. You can take a look at my test suite here . timestamp would get A book on all things Foundry. length, 2); assertEq(entries[0]. To the moment I used the function assertEq() All tests passed stably, after that, I specifically began to come in this test "Invalid data". roll along with --via-ir compilation is used, as block. foundryup. Forge supports testing in a forked environment with two different approaches: Forking Mode — use a single fork for all your tests via the forge test --fork-url flag; Forking Cheatcodes — create, select, and manage multiple forks directly in Solidity test code via forking cheatcodes; Which approach to use? Forking mode affords running an entire test suite against A book on all things Foundry Foundry Book. Create ERC-20 Contract Using Foundry . Reload to refresh your session. sol Smart contract test files are named following the pattern: <ContractName>Test All tests inherit from forge-std/Test. Examples. So for example on assert you could have something like ’ assert(!ContractIsBroken) ‘ A cheatsheet for commonly used commands and cheatcodes in Foundry. Reason: Undefined. Run this command in your terminal: assertEq( token. encode(yourStructVariable) to serialize it to bytes. First Steps with Foundry; Projects; 3. 633264000Z) What command(s) is the When comparing address with assertEq and address is displayed in error, checksum is not included #5965. Introduction; Getting Started; Installation; First Steps with Foundry; Projects; Creating a New Project; string memory err) internal; // Assert `a` is equal to `b` function assertEq(address a, address b) internal; function assertEq(address a, address b, string memory err) internal; function assertEq(bytes32 a Contribute to dabit3/foundry-cheatsheet development by creating an account on GitHub. A book on all things Foundry. log(alice. CLI Reference 32. 8. To run a test displaying logs, you can specify. CREATE2 allows you to deploy smart contracts to deterministic addresses, based on parameters controlled by the deployer. The script directory contains an example script. assertApproxEqAbs Signature function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) internal; assertEq(dai. sol. 0 (63c71b4 2022-09-12T00:04:31. Then, you actually don't need to import forge-std/console. See the full GitHub Project Code Repository. increment(); assertEq A book on all things Foundry Foundry in Action: awesome-foundry: A curated list of awesome of the Foundry development framework. assertNotEq Signature bool function assertNotEq(bool left, bool right) internal; function assertNotEq(bool left, bool right, string memory err) internal; A book on all things Foundry getBlockNumber Signature function getBlockNumber() external view returns (uint256 timestamp); Description. CodeSandwich opened this issue Sep 13, There are also utilities for: truthiness - assertTrue. In the realm of blockchain development, the security and reliability of smart contracts are paramount. toml registers two Fork Testing. winor30 opened this issue Oct 1, 2023 · 0 comments Labels. Creating a New Project; 4. encode() is used assertEq(fundme. Share Improve this answer Foundry — это довольно свежий и очень мощный инструмент для разработки, деплоя и тестирования смарт-контрактов на языке Solidity, и в последнее время он набирает бешенную популярность. You signed in with another tab or window. Installation; 2. log(IERC20(address(ico)). timestamp is assumed to be a constant during a transaction. length, 2); // Recall that topics[0] is the event signature assertEq(entries[0]. Tests are written in Solidity to keep the workflow consistent with smart contract development and testing before deployments. Foundry состоит из трех компонентов: Forge: среда Hey, not sure if I should upload this issue here or in foundry repo, but with the implementation of this commit: foundry-rs/forge-std@ 1432518 the behavior of assertEq changed (and I assume Foundry Foundryup What version of Foundry are you on? forge 0. function assertEq(bytes[] memory left, bytes[] memory right, string memory err) internal; Legacy // legacy helper for asserting two uints shorter than 256 bits: `assertEqUint(uint8(1), uint128(1));` Invariant testing allows for a set of invariant expressions to be tested against randomized sequences of pre-defined function calls from pre-defined contracts. Foundry also supports fuzzing. forge A book on all things Foundry. Foundry Book. This is useful in cases where vm. Sablier V2 Core: Another good example of many Foundry features. warp along with --via-ir compilation is used, as block. forge getBlockTimestamp Signature function getBlockTimestamp() external view returns (uint256 timestamp); Description. . When the test is run, we'll see output for not only the success of the test, but also the gas cost: Provides cheatcodes to access all RPC endpoints configured in the rpc_endpoints object of the foundry. For example, implement a passwordStore. balanceOf(alice), 10000e18); Utility functions also included in Script. 26. forge За прошедшие две части мы освоили почти всю базу, которая нужна нам для тестирования и отладки контрактов в Foundry . Writing Tests. sol Take note of the following: Foundry test files are named following the pattern: <ContractName>. Now in the file MyErc20. It should be enough to import Test. balance); // Use A book on all things Foundry. Provide details and share your research! But avoid . load causes assertEq() to fail on seemingly same strings I have a simple contract that just sets a string private state variable in contract's slot 1. 730405056Z) What command(s) Hello everyone, I’m testing the contract. /UsingInterface. test. Here is a minimal example. function testBalanceOf() public { uint balance = 10; assertEq(balance, 1); } The above test fails with reason [FAIL. copyStorage Signature function copyStorage(address from, address to) external; Description. It provides all the essential functionality you need to get started writing tests: Vm. You should use abi. log output. Let's add a simple test and see how they perform. This means that on every forge test, multiple calls to block. As usual, start by importing all the required files: // SPDX-License-Identifier: MIT pragma solidity ^0. The lib directory contains forge-std, a collection of helpful contracts for use with forge and foundry. Returns the identifier for the currently active fork. Forge Standard Library is a collection of helpful contracts for use with forge and foundry. You switched accounts on another tab or window. First Steps with Foundry; Projects; string memory err) internal; // Assert `a` is equal to `b` function assertEq(address a, address b) internal; function assertEq(address a, address b, string memory err) internal; function assertEq(bytes32 a, bytes32 b Foundry. increment(); assertEq -name: Run foundry tests run: forge test -vvv Static analysis with Slither and Mythril. Introduction If you're like me, you probably like trying out different technologies just for the fun of it and maybe you've been hearing everyone talk about Foundry and you don't know what it is or have the time to research about it or even go through the foundry book. Let's create a basic smart rollFork Signature // roll the _active_ fork to the given block function rollFork(uint256 blockNumber) external; // roll the _active_ fork to the block in which the transaction was mined it and replays all previously executed transactions function rollFork(bytes32 transaction) external; A book on all things Foundry. Learn how to enhance your smart contracts’ security through snapshotState cheatcodes Signature /// Snapshot the current state of the evm. unixTime(); vm. CLI Reference 35. 32. You signed out in another tab or window. increment(); assertEq A book on all things Foundry stopAndReturnStateDiff Signature enum AccountAccessKind { Call, DelegateCall, CallCode, StaticCall, Create, SelfDestruct, Resume, Balance, Extcodesize, Extcodehash Instead of using vm. Installing Foundry. You can also do it for mythril. getPassword function which returns the variable, OR set the variable within passwordStore to be public . setArbitraryStorage Signature function setArbitraryStorage(address target) external; // Subsequent calls to same slot returns same value assertEq(counter. While assertEq taking two variables would more be like this ‘ A = 5 B = 5 assertEq(A, B) ‘ This use of assertEq takes the two variables defined above and makes sure they are equal to each other. createFork(MAINNET_RPC_URL); vm. sol (see Script Utils ) // Compute the address a contract will be deployed at for a given deployer address and nonce address futureContract = computeCreateAddress(alice, 1); mockCalls Signature function mockCalls(address where, bytes calldata data, bytes[] calldata retdata) external; function mockCalls( address where, uint256 value, bytes calldata data, bytes[] calldata retdata ) external; A book on all things Foundry. Tests are written in Solidity. sol (alice); // Assert and log using Dappsys Test assertEq(dai. Cheatcode is not allowed if the target address has arbitrary storage set. Fork Testing. forge Foundry in Action: awesome-foundry: A curated list of awesome of the Foundry development framework. number would get optimized to just A book on all things Foundry. Create a new project: Create a new project using a template: Initialize Foundry: Specify directories in You can use forge-std/assertEq function to compare 2 bytes for equivalence. Foundry Foundryup What version of Foundry are you on? forge 0. setOwner(55, address(111)); assertEq (counter. It leverages forge's cheatcodes to make writing tests easier and faster, we expect it Thanks for contributing an answer to Ethereum Stack Exchange! Please be sure to answer the question. You can also check which address sent the event. Instructions can be found on the official Foundry docs site. Foundry supports compiling and testing Vyper contracts. To manipulate the state of the blockchain, as well as test for specific reverts and events, Foundry is shipped with a set of cheatcodes. 19; import {Test, console2} from "forge-std/Test. To see all available invariant configs visit here. Deploying a Smart Contract with Foundry. getOwner(55 getRecordedLogs Signature struct Log { bytes32[] topics; bytes data; address emitter; } function getRecordedLogs() external returns ( Log[] memory ); activeFork Signature function activeFork() external returns (uint256); Description. Nomad Monorepo: All the contracts-* packages. This allows us to define function parameter types and the testing framework will populate these values at runtime. Adding a test in Foundry¶ Add the following file to test/Spacebear. emit donateToOwnerEvent (); assertEq So, it is always better not to use low number addresses but to generate them with the foundry utilities like makeAddr() and vm. naiveInterest() ) However, you can write a test using Foundry by creating a helper function to compare the structs and using the testing utilities provided by Foundry. The test directory contains an example test. count(), 0); upOnly . Returns the time since unix epoch in milliseconds. Foundry is a fast testing and deployment tool for developing EVM smart contracts. MINIMUM_USD(), 5e18); You need to inherit the test. Using Hardhat with Foundry. This cheatcode works similar to getCode but only returns the deployed bytecode (aka runtime bytecode) for a contract in the project given the path to the contract. The main use case for this cheat code is as a shortcut to deploy stateless contracts to arbitrary Fuzz Testing. Function with signature `assertEq(address,address)` and selector `0x515361f6`. ] which is very misleading, given that nothing is undefined. load to get the raw storage value for assertEq, you could implement a getter function to have Solidity return the proper string value. You can view most of the assertions here. selectFork(forkId); assertEq(vm. forge Verbosity-vv shows console. Ie Vm. getOwner(55), owner); // The new value is returned if explicitly written counter. createFork(MAINNET_RPC_URL, 1_337_000); vm. topics. First, you'll need to install Foundry. If the test function reverts, the test fails, otherwise it passes. This guide will walk you through setting up a new project using Foundry, a blazing fast toolkit for Ethereum application development written in Rust. Traditionally, setting a user or contract allowance to transfer ERC-20 tokens from an owner's balance required the owner to submit an approval on-chain. Vyper support. ; All tests contain a public function called setUp, which is executed before each test. balanceOf(alice), 10000e18); // Log with the Hardhat `console` (`console2`) console. Executes calls to an address callee with bytecode of address target if the call data either strictly or loosely matches data. Upgrading a smart contract is a multistep and error-prone process, so to minimize the chances of human error, it is desirable to use a tool that automates the procedure as much as possible. In this section, we’ll go over the basics using the functions from the Forge Std’s Test contract, which is itself a To manipulate the state of the blockchain, as well as test for specific reverts and events, Foundry is shipped with a set of cheatcodes. This tutorial will walk you through creating an OpenSea compatible NFT with Foundry and Solmate. 0 (94ae897 2023-10-31T00:16:51. sol, we can create a base setup. -vvvvv shows execution and setup traces for all tests. /SimpleAddition. increment(); assertEq Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers; Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand; OverflowAI GenAI features for Teams; OverflowAPI Train & fine-tune LLMs; Labs The future of collective knowledge sharing; About the company We can set optional configuration values for our invariant test inside the foundry. addr(), like you did. activeFork(), forkId); Hi everyone, I've finished lesson 7, and I think beginners like me who are trying to write and deploy things like what Patrick did, will face some issues exactly on the function: testUserCanFundInteractions Please watch the video again with more attention, and you see exactly before running tests, video jumps somehow and the codes are a little changed A book on all things Foundry. This is what the test function should look like: function testgreeting() public { HelloWorld helloWorld = new HelloWorld(); assertEq(helloWorld. Differential fuzzing against a reference TypeScript implementation. timestamp. prank(owner); A book on all things Foundry The forge CLI will create a few files and folders, including lib, src, script, and test. It is possible to use Slither to run static analysis in a Foundry project. Given the immutable nature of blockchain, any bug in a smart contract can lead Lastly we use assertEq to assert equality between two values. decimal equality - assertEqDecimal. Select a previously created fork: uint256 forkId = vm. recordLogs Signature function recordLogs() external; Description. balanceOf(address(attacker)), 10 * ONE_TOKEN); This will print out the current balance of the attacker address in the console, which can help you determine if the issue is with the balanceOf function call or the assertion itself. Foundry uses default values if no config values are set. Deterministic deployment using CREATE2 Introduction. balanceOf(address(attacker))); assertEq(IERC20(address(ico)). A book on all things Foundry Smart Contract Foundry Upgrades with the OpenZeppelin Plugin. Step 5: Configure Foundry in your Hedera project. Let’s create a foundry configuration file to update how Foundry behaves. Contribute to dabit3/foundry-workshop development by creating an account on GitHub. /// Returns the ID of the snapshot that was created. Foundry’s default directory for contracts is src/, but we will need it to map to contracts. Below, I write a test that is supposed to set that private string variable to a new value and then A book on all things Foundry. 💻 The code corresponding to this page can be found on Github at Interfaces. 0 (03f5a95 2024-01-17T16:58:19. Property-based testing is a way of testing general behaviors as opposed to isolated scenarios. A copy of this cheatsheet can be found in this gist. t. This developer guide will walk you through setting up a new Solidity contract, configuring the Berachain network details, deploying to Berachain, and verifying the В прошлой части мы познакомились с Foundry, создали новый проект и освоили самые базовые команды для тестирования. Gets the current block. Forge supports testing in a forked environment with two different approaches: Forking Mode — use a single fork for all your tests via the forge test --fork-url flag; Forking Cheatcodes — create, select, and manage multiple forks directly in Solidity test code via forking cheatcodes; Which approach to use? Forking mode affords running an entire test suite against mockFunction Signature function mockFunction(address callee, address target, bytes calldata data) external; Description. NB: abi. For the base setUp function, we simply use the utils functions that came with the template already. To run the test, we can run: forge test. -vvvv shows execution traces for all tests, and setup traces for failing tests. If you don't declare your test contract as a Test type, you won't have access to the assert, assertEq, A smart contract development toolchain called Foundry offers resources for testing smart contracts. Introduction; Getting Started; 1. Forge, a testing framework for Solidity smart contracts, is one of Foundry's key components. - foundry-rs/forge-std. toml registers two A book on all things Foundry. forge selectors collision forge selectors collision Interfaces. Besides the ERC20 contract itself, we'll also import things from the forge-std, ds-test and utils. function snapshotState() external returns (uint256 snapshotId); /// Revert the state of the EVM to a previous snapshot /// Takes the snapshot ID to revert to. This tutorial is for illustrative purposes only and provided on I am getting a EvmError: Revert when I am trying to withdraw native token from the first contract to the second contract. As a result, it’s often mentioned as enabling How you can use Foundry for testing a standard ERC20 smart contract and; assertEq -> Use this when your testing function returns uint,address,string. getRecordedLogs(); assertEq(entries. We will set only the important ones as we proceed in this article. number, 15_171_037); // as of time of writing, 2022-07-19 04:55:27 UTC Create a new mainnet fork with a given block number: uint256 forkId = vm. In our test we've asserted equality using the assertEq utility. A common example is EIP-2612 gasless token approvals. timestamp would get In the previous article, we started out with a new tool called Foundry to aid our smart contract development life cycle. Creating an NFT with Solmate. sleep(10_000); // Halts execution for 10 seconds uint end = EIP-712 introduced the ability to sign transactions off-chain which other users can later execute on-chain. assertEq( pool. Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question. Пришло время закрепить успех! В этой части мы рассмотрим тестирование A book on all things Foundry. getBlockTimestamp Signature function getBlockTimestamp() external view returns (uint256 timestamp); Description. number, 15_171_037); // as of time of writing, 2022-07-19 04:55:27 UTC Create and select a new mainnet fork with a given A book on all things Foundry Fuzz Testing. In foundry we have a setUp function that we can define to bring the contract into a different state and to create some addresses. 312489000Z) What command ├─ [281] Counter::number() [staticcall] │ └─ ← 0 ├─ [0] VM::assertEq(0, 0) [staticcall] │ └─ ← unknown selector `0x98296c54` for VmCalls └─ ← unknown selector `0x98296c54 Using Forge Std is the preferred way of writing tests with Foundry. unixTime Signature function unixTime() external returns (uint milliseconds); Description. You can easily use Hardhat with Foundry. outstandingInterest(), test. prank API (what foundry calls a cheatcode). After each function call is My main understanding of it is that assertEq() takes two variables and makes sure they are equal. 0 (ddca274 2023-09-30T00:19:15. greater than, less than - assertGt, assertGe, assertLt, assertLe. Cheatcodes allow you to change the block setUp() public { upOnly = new OwnerUpOnly(); } function test_IncrementAsOwner() public { assertEq(upOnly. number is assumed to be a constant during a transaction. getRoot(leaves); assertEq(murkyGeneratedRoot, jsGeneratedRoot); } Discover the ultimate guide to ERC20 fuzz and invariant testing with Foundry. Testing in Foundry works different than in Truffle or Hardhat. Let’s go over the most common way of writing tests, using the Forge Standard Library’s Test contract, which is the preferred way of writing tests with Forge. You can use forge-std/assertEq function to compare 2 bytes for equivalence. Now you're probably wondering, how can you test several sender accounts in Foundry? That works with VM Cheatcodes. 1. Well, if you fit into this category, this article is for you because I'll be talking about what foundry is, why I think First, make sure you have the latest version of foundry. sol in your test contract. These frameworks typically offer comprehensive features for compiling, testing, and deploying contracts, and Foundry supports all of these functions as well. forge Did you mean "assert"? reviewing with chatgpt states to make sure the right packages are installed but I have the latest Foundry packages. When a call is made to callee the call data is first checked to see if it matches in its entirety with data. -vvv shows execution traces for failing tests. uint256 forkId = vm. Log[] memory entries = vm. sol"; import {SimpleAddition} from ". Good example of using many Foundry features including fuzzing, ffi and various cheatcodes. Cheatcodes allow you to change the block setUp() public { upOnly = new OwnerUpOnly(); } function testIncrementAsOwner() public { assertEq(upOnly. Asking for help, clarification, or responding to other answers. function testChangeOwner() public { vm. The src directory contains a barebones smart contract. Сегодня нам предстоит окунуться чуть поглубже, освоить автоматическое форматирование кода (forge fmt Asserts that two `address` values are equal. Examples uint start = vm. Run the tests using the command forge test. assertEq( token. The reason ChatGPT says they are the same thing is you’ll often find people saying things like ‘’’ assert(A == B) ‘’’ assertEq( token. This is similar to the beforeEach hook in the Foundry Foundryup What version of Foundry are you on? forge 0. Contribute to dabit3/foundry-cheatsheet development by creating an account on GitHub. 1. ; To run Thanks for contributing an answer to Ethereum Stack Exchange! Please be sure to answer the question. assertEqDecimal Signature function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal toString Signature function toString(address) external returns (string memory); function toString(bool) external returns (string memory); function toString(uint256 A book on all things Foundry. For more see slither. Closed 2 tasks done. selectFork(forkId vm. assertApproxEqRel Signature function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta) internal; Fork Testing. createSelectFork(MAINNET_RPC_URL); assertEq(block. Here's an example of how you can write a test for the tokenMetadata function. znptqbbwfdfaypkquwekgajwqxgpthtubtzsdhihudo