Skip to main content

test-fixtures

Use when setting up test environments for Solidity protocols. Covers mock contracts, fork-based fixtures, shared setUp, factory patterns, token deployments, and reusable test helpers.

Zur Installation springen

Quellinformationen

Repository
ccashwell/evm-cortex
Letzte Quellaktivität
10. April 2026 um 16:31
Erkannte Sprache von SKILL.md
Englisch
Sterne
131
Forks
18

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
test-fixtures
description
Use when setting up test environments for Solidity protocols. Covers mock contracts, fork-based fixtures, shared setUp, factory patterns, token deployments, and reusable test helpers.
# Test Fixtures & Helpers ## Base Test Contract Shared setUp that all test files inherit: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; abstract contract BaseTest is Test { address public alice; address public bob; address public carol; address public deployer; address public treasury; function setUp() public virtual { alice = makeAddr("alice"); bob = makeAddr("bob"); carol = makeAddr("carol"); deployer = makeAddr("deployer"); treasury = makeAddr("treasury"); vm.deal(alice, 100 ether); vm.deal(bob, 100 ether); vm.deal(carol, 100 ether); } function _labelAll() internal { vm.label(alice, "Alice"); vm.label(bob, "Bob"); vm.label(carol, "Carol"); vm.label(deployer, "Deployer"); vm.label(treasury, "Treasury"); } function _fundToken(address token, address to, uint256 amount) internal { deal(token, to, amount); } function _approveToken(address token, address owner, address spender, uint256 amount) internal { vm.prank(owner); IERC20(token).approve(spender, amount); } } ``` ## Mock ERC20 Token ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MockERC20 is ERC20 { uint8 private _decimals; constructor(string memory name, string memory symbol, uint8 decimals_) ERC20(name, symbol) { _decimals = decimals_; } function decimals() public view override returns (uint8) { return _decimals; } function mint(address to, uint256 amount) external { _mint(to, amount); } function burn(address from, uint256 amount) external { _burn(from, amount); } } ``` ## Token Fixture Library ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {MockERC20} from "./MockERC20.sol"; library TokenFixtures { function deployUSDC() internal returns (MockERC20) { return new MockERC20("USD Coin", "USDC", 6); } function deployWETH() internal returns (MockERC20) { return new MockERC20("Wrapped Ether", "WETH", 18); } function deployDAI() internal returns (MockERC20) { return new MockERC20("Dai Stablecoin", "DAI", 18); } function deployWithDecimals(uint8 decimals) internal returns (MockERC20) { return new MockERC20("Test Token", "TEST", decimals); } } ``` ## Mock Oracle ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract MockChainlinkFeed { int256 private _price; uint8 private _decimals; uint256 private _updatedAt; uint80 private _roundId; constructor(int256 price, uint8 decimals_) { _price = price; _decimals = decimals_; _updatedAt = block.timestamp; _roundId = 1; } function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return (_roundId, _price, _updatedAt, _updatedAt, _roundId); } function decimals() external view returns (uint8) { return _decimals; } function setPrice(int256 newPrice) external { _price = newPrice; _updatedAt = block.timestamp; _roundId++; } function setStale() external { _updatedAt = block.timestamp - 2 days; } } ``` ## Protocol Deployment Fixture ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {BaseTest} from "./BaseTest.sol"; import {Vault} from "../../src/Vault.sol"; import {StakingRewards} from "../../src/StakingRewards.sol"; import {MockERC20} from "./MockERC20.sol"; import {MockChainlinkFeed} from "./MockChainlinkFeed.sol"; abstract contract ProtocolFixture is BaseTest { MockERC20 public usdc; MockERC20 public weth; MockChainlinkFeed public ethUsdFeed; Vault public vault; StakingRewards public staking; function setUp() public virtual override { super.setUp(); vm.startPrank(deployer); usdc = new MockERC20("USDC", "USDC", 6); weth = new MockERC20("WETH", "WETH", 18); ethUsdFeed = new MockChainlinkFeed(3500e8, 8); vault = new Vault(address(usdc)); staking = new StakingRewards( address(vault), address(usdc), deployer ); vm.stopPrank(); _fundUsers(); _labelAll(); vm.label(address(usdc), "USDC"); vm.label(address(weth), "WETH"); vm.label(address(vault), "Vault"); vm.label(address(staking), "Staking"); } function _fundUsers() internal { for (uint256 i = 0; i < _users().length; i++) { address user = _users()[i]; usdc.mint(user, 1_000_000e6); weth.mint(user, 1_000e18); vm.startPrank(user); usdc.approve(address(vault), type(uint256).max); usdc.approve(address(staking), type(uint256).max); weth.approve(address(vault), type(uint256).max); vm.stopPrank(); } } function _users() internal view returns (address[] memory) { address[] memory users = new address[](3); users[0] = alice; users[1] = bob; users[2] = carol; return users; } } ``` ## Usage in Tests ```solidity import {ProtocolFixture} from "./helpers/ProtocolFixture.sol"; contract VaultTest is ProtocolFixture { function test_deposit() public { vm.prank(alice); vault.deposit(1000e6, alice); assertEq(vault.balanceOf(alice), 1000e6); } function test_priceDropLiquidation() public { vm.prank(alice); vault.deposit(1000e6, alice); ethUsdFeed.setPrice(1000e8); // crash ETH price assertTrue(vault.isLiquidatable(alice)); } } ``` ## Fork-Based Fixtures ```solidity abstract contract MainnetFixture is BaseTest { IERC20 constant USDC = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); IPool constant AAVE = IPool(0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2); function setUp() public virtual override { super.setUp(); vm.createSelectFork("mainnet", 19_500_000); _labelMainnet(); } function _labelMainnet() internal { vm.label(address(USDC), "USDC"); vm.label(address(WETH), "WETH"); vm.label(address(AAVE), "Aave Pool"); } } ``` ## Checklist - [ ] Base test contract provides common users, funding, and labels - [ ] Mock tokens support configurable decimals - [ ] Mock oracles support price manipulation and staleness simulation - [ ] Protocol fixture deploys complete system in correct order - [ ] All users pre-funded and pre-approved in setUp - [ ] All contract addresses labeled for readable traces - [ ] Fork fixtures pinned to specific blocks - [ ] Fixtures are `abstract` — tests inherit and extend - [ ] Separate mock directory: `test/mocks/` - [ ] Shared helpers in `test/helpers/`
Auf GitHub ansehen