Problem: Tests Fail, No Confidence
Imagine: you deploy a contract to mainnet, but an hour later discover a reentrancy vulnerability. Users lost funds — reputation damaged, audit didn't help. Every hour of downtime costs $5,000, and damages from reentrancy attacks exceed $100M. Or a typical situation: a new developer spends half a day installing dependencies and running the first test. The CI pipeline failed, but no one knows why — logs are empty.
Our team with 5 years of blockchain development experience has set up such environments for 50+ projects, including protocols with total TVL > $1B. As a result, deployment time decreased by 40%, and the number of bugs in production — by 70%. This is not just a toolchain — it's a guarantee of stability and reproducibility.
Which Framework to Choose for the Task?
For Solidity projects, there are currently two real options: Foundry and Hardhat. They solve different tasks and are often used together. The choice depends on what you are testing: contract logic or frontend integration.
| Parameter | Foundry | Hardhat |
|---|---|---|
| Test language | Solidity | TypeScript/JavaScript |
| Execution speed | Very fast (revm on Rust) | Slower (up to 5x) |
| Fuzz testing | Built-in (differential, invariant) | Only via plugins |
| Mainnet fork | vm.createFork() |
--fork-url |
| Frontend integration | Harder | Easier (ethers.js, Wagmi) |
| Deployment scripts | Solidity scripts | TypeScript + ethers.js |
| Transaction debugging | forge debug |
console.log() in contract |
Our standard: Foundry for unit and fuzz tests, Hardhat for deployment scripts and frontend integration. Both configs coexist in one repository — this allows writing tests in Solidity and deploying via TypeScript.
How Is the Project Structure Organized?
We use a module-based separation: contracts/core, contracts/interfaces, test/unit, test/integration, test/invariant, script (Foundry), deploy (Hardhat) and fixtures. This organization allows separating unit tests (without RPC) from integration tests (with fork). Unit tests should run in seconds, integration only on merge to main.
Setting Up Local Network, Mocks, and Fixtures
Local Network: Anvil Instead of Ganache
Anvil (included in Foundry) is a local EVM node on Rust. 10x faster than Ganache, actively maintained. For development, we run it in fork mode from mainnet or testnet:
# Fork Ethereum mainnet at a specific block (reproducibility)
anvil --fork-url $MAINNET_RPC --fork-block-number 19500000
# Fork with predefined accounts and balances
anvil --fork-url $MAINNET_RPC --accounts 10 --balance 10000
Fork testing is the only way to check integration with Uniswap, Aave, Chainlink without deploying to testnet. Transaction in a local fork is instant. On Sepolia — 12-15 seconds. Time savings per iteration: from 15 seconds to 0.1 seconds. Use Ethereum testnets to get familiar with networks.
Mocks and Fixtures: Isolation Without Fragility
For test isolation we use fixture inheritance:
// BaseFixture.sol — common dependencies
abstract contract BaseFixture is Test {
MockERC20 token;
MockChainlinkOracle oracle;
function setUp() public virtual {
token = new MockERC20("Test", "TST", 18);
oracle = new MockChainlinkOracle(2000e8); // $2000 price
}
}
// ProtocolFixture.sol — deploy the protocol under test
contract ProtocolFixture is BaseFixture {
Protocol protocol;
function setUp() public override {
super.setUp();
protocol = new Protocol(address(token), address(oracle));
}
}
We do not use vm.mockCall for core dependencies — it's fragile and doesn't check interfaces. We create full mock contracts with minimal implementation. This approach reduces false positives by 30%.
Step-by-Step Setup and CI/CD
Detailed instructions
- Install Foundry:
curl -L https://foundry.paradigm.xyz | bash. - Create config:
forge initand configurefoundry.tomlfor your project. - Add Hardhat:
npm install --save-dev hardhatand generatehardhat.config.ts. - Start local node:
anvilin a separate terminal. - Write your first test: use the fixture template above.
- Set up CI: add GitHub Actions workflow (see below).
CI/CD: Automation Without Surprises
GitHub Actions configuration for Foundry:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Run unit tests
run: forge test --match-path "test/unit/*" -vvv
- name: Run integration tests
run: forge test --match-path "test/integration/*" --fork-url ${{ secrets.MAINNET_RPC }}
- name: Coverage check
run: forge coverage --min-line-coverage 80
Separate unit and integration tests — unit tests must work without RPC keys. Integration tests only on PR to main. This reduces feedback time to 2 minutes.
Testnets and Scope of Work
Multi-Network Support
We set up a multi-network config in Hardhat:
networks: {
sepolia: {
url: process.env.SEPOLIA_RPC,
accounts: [process.env.DEPLOYER_KEY],
chainId: 11155111,
},
polygon_amoy: {
url: process.env.AMOY_RPC,
accounts: [process.env.DEPLOYER_KEY],
chainId: 80002,
},
}
| Testnet | Chain ID | Faucet | Block Time |
|---|---|---|---|
| Sepolia | 11155111 | Alchemy / Chainlink | 12 sec |
| Polygon Amoy | 80002 | Official Polygon | 2 sec |
| BNB Testnet | 97 | Binance Faucet | 3 sec |
Scope and Timelines
What is included in the setup:
- Configuration of Foundry and Hardhat (
foundry.toml,hardhat.config.ts) - Set of mock contracts (ERC-20, Chainlink Oracle)
- Fixture hierarchy for your protocol
- Local EVM node (Anvil) with fork mode
- CI pipeline (GitHub Actions) with separation of unit/integration tests
- Testnet setup (Sepolia, Polygon Amoy, BNB Chain testnet)
- Documentation on running and extending
- Team training (1-2 hours)
Timelines: basic setup — 1 business day. With custom mocks and fixtures — 1-2 days. For projects with multiple chains (EVM + Solana) — 2-3 days. Result: reduction in testing time up to 60%, early vulnerability detection, stable CI. Monthly savings from this approach can reach $10,000.
Order Test Environment Setup
Contact us — we'll conduct a free audit of your current process and propose a configuration for your protocol. Get a consultation on optimizing your test environment. We guarantee: after setup, every commit will pass checks without surprises. Order setup today — start testing with confidence.







