Description
Component
Forge
Describe the feature you would like
Hello,
I found that the forge tools for testing are very amazing. But I came across a bit frustrating issue: My goal is to run some simulations using the power of forge, but I didn't found any "clean" way of doing it.
Like my goal is to deal some tokens and ETH and then run interactions between smart contract and just "console.log" what is happening.
For now I am writing some tests with at the end:
function testMySimulations() public {
// deal some tokens
// interact with contracts
console.log("some output");
// etc...
assert(false);
}
My goal is just to see the output of console.log without expecting a specific output but I have to run forge test -vv to see the actual output.
The feature
In forge, we have:
script/
folder to write scripts to deploy our smart contractsrc/
folder to write our codetest/
folder to write our tests
My suggestion would be to add a simulation/
folder designed specifically just when you want to use all features available in test/
but instead you want to print some output and simulate some behavior rather than expecting a specific output
Example usages
A more clear example of usage, would be when you have a smart contract deployed without the source code available. You would want to make some simulations interacting with it, trying some stuff here and there to see how it behave.
For example an ERC20 token that you don't know if it is a honeypot or not, you could simulate the deployment then buy then see if you can sell or not, see if there is any tax on it...
More advanced feature suggestion
Once we have our simulation/
folder, it would be amazing to be able to "import" it in our favorite language.
Example:
The goal of this example project would be if we have an erc20 contract that is deploying but the source code is not available, we want to test out if it is a honeypot or not
Project structure
honeypot-simulation/
| - script/
| - simulation/
| - HoneyPotSimulation.sol
| - src/
| - test/
Inside honeypot simulation we have code like this:
contract HoneyPotSimulation is Simulation {
function isHoneyPot(address contract) public returns (bool) {
// TODO: deal some tokens, deploy the contract, buy it then try to sell
// TODO: return if we could sell or not
}
}
Then in rust for example, we have a create called: forge-simulations
we simply do:
// we point to the folder containing the honeypot simulation
simulation!(HoneyPotSimulation, "/home/user/honeypot-simulation");
The example way of importing simulation! is inspired of alloy-sol-types
where we can import a solidity abi to interact is using alloy.
Hard-coding the path to the folder is not such a good idea because it may fail depending on which computer you run it. It would be better to use sub-gitmodules, or a gitpath, or even a registry (public or private) of forge simulations that can be imported.
Once we have imported our simulation we do:
pub async fn is_honeypot(address: Address) -> Result<bool> {
HoneyPotSimulation.HoneyPotSimulation.HoneyPotSimulation.isHoneypot(address).await?;
}
The suggested structure is:
Name written in simulation!
macro => Name of the file in simulation/
folder => Name of the Contract to use => name of the function to call
This won't be a simple contract interaction but the full simulation, with all forge tools that will be executed (rollfork, deal, snapshot...).
It would be amazing to have this improvement because sometimes it is way easier to write solidity code using forge tools than it is to write rust for some parts and now solidity code would become very easy to import into rust.
Additional context
No response
Metadata
Metadata
Assignees
Type
Projects
Status