Handler Stateful Fuzz Tests #1892
Answered
by
ArnaudBand
ArnaudBand
asked this question in
Q&A
-
Hello Devs, I'm making my first fuzz test. I'm testing the function Here is my test function invariant_protocolMustHaveMoreValueThanTotalSupply() public view {
uint256 totalSupply = dsc.totalSupply();
uint256 totalWethDeposited = ERC20Mock(weth).balanceOf(address(engine));
uint256 totalWbtcDeposited = ERC20Mock(wbtc).balanceOf(address(engine));
uint256 wethValue = engine.getUsdValue(weth, totalWethDeposited);
uint256 wbtcValue = engine.getUsdValue(wbtc, totalWbtcDeposited);
console.log("wethValue: %d", wethValue);
console.log("wbtcValue: %d", wbtcValue);
console.log("totalSupply: %d", totalSupply);
assert(wethValue + wbtcValue >= totalSupply);
} Here is the handler contract // SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.26;
import {Test} from "forge-std/Test.sol";
import {DSCEngine} from "../../src/DSCEngine.sol";
import {DecentralizedStableCoin} from "../../src/DecentralizedStableCoin.sol";
import {ERC20Mock} from "../mocks/ERC20Mock.sol";
contract Handler is Test {
DSCEngine engine;
DecentralizedStableCoin dsc;
ERC20Mock weth;
ERC20Mock wbtc;
uint256 MAX_DEPOSIT_SIZE = type(uint96).max; // The max uint96 value
constructor(DSCEngine _engine, DecentralizedStableCoin _dsc) {
engine = _engine;
dsc = _dsc;
address[] memory collateralTokens = engine.getCollateralTokens();
weth = ERC20Mock(collateralTokens[0]);
wbtc = ERC20Mock(collateralTokens[1]);
}
// redeem collateral <-
function depositCollateral(uint256 collateralSeed, uint256 amountCollateral) public {
amountCollateral = bound(amountCollateral, 1, MAX_DEPOSIT_SIZE);
ERC20Mock collateral = _getCollateralFromSeed(collateralSeed);
vm.startPrank(msg.sender);
collateral.mint(msg.sender, amountCollateral);
collateral.approve(address(engine), amountCollateral);
engine.depositCollateral(address(collateral), amountCollateral);
vm.stopPrank();
}
function _getCollateralFromSeed(uint256 seed) private view returns(ERC20Mock) {
return seed % 2 == 0 ? weth : wbtc;
}
}
Here is the error Failing tests:
Encountered 1 failing test in test/fuzz/InvariantsTest.t.sol:InvariantsTest
[FAIL. Reason: invariant_protocolMustHaveMoreValueThanTotalSupply persisted failure revert]
[Sequence]
sender=0x00000000000000000000000000000000E90db8A3 addr=[src/DSCEngine.sol:DSCEngine]0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 calldata=redeemCollateralForDsc(address,uint256,uint256) args=[0xf6493b3CA2C716E6B5e40E233534CC237c56dDd6, 61583321711932284334241230493870068036402704009442828937579480699 [6.158e64], 76945 [7.694e4]]
invariant_protocolMustHaveMoreValueThanTotalSupply() (runs: 1, calls: 1, reverts: 1)
Encountered a total of 1 failing tests, 0 tests succeeded
@ArnaudBand ➜ /workspaces/cyfrin_updraft_course/foundry_defi_protocol (tst_test_get_func) $ forge test --match-test invariant_protocolMustHaveMoreValueThanTotalSupply -vvvv
[⠊] Compiling...
[⠘] Compiling 4 files with Solc 0.8.26
[⠃] Solc 0.8.26 finished in 1.63s
Compiler run successful!
Ran 1 test for test/fuzz/InvariantsTest.t.sol:InvariantsTest
[FAIL. Reason: invariant_protocolMustHaveMoreValueThanTotalSupply persisted failure revert]
[Sequence]
sender=0x00000000000000000000000000000000E90db8A3 addr=[src/DSCEngine.sol:DSCEngine]0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 calldata=redeemCollateralForDsc(address,uint256,uint256) args=[0xf6493b3CA2C716E6B5e40E233534CC237c56dDd6, 61583321711932284334241230493870068036402704009442828937579480699 [6.158e64], 76945 [7.694e4]]
invariant_protocolMustHaveMoreValueThanTotalSupply() (runs: 1, calls: 1, reverts: 1)
Logs:
wethValue: 0
wbtcValue: 0
totalSupply: 0
Traces:
[10933380] InvariantsTest::setUp()
├─ [4456062] → new DeployDSC@0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
│ └─ ← [Return] 22144 bytes of code
├─ [5157217] DeployDSC::run()
│ ├─ [3339508] → new HelperConfig@0x104fBc016F4bb334D775a19E8A6510109AC63E00
│ │ ├─ [0] VM::startBroadcast()
│ │ │ └─ ← [Return]
│ │ ├─ [372255] → new MockV3Aggregator@0x90193C961A926261B756D1E5bb255e67ff9498A1
│ │ │ └─ ← [Return] 1082 bytes of code
│ │ ├─ [516505] → new ERC20Mock@0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496
│ │ │ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: DeployDSC: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], value: 100000000000 [1e11])
│ │ │ └─ ← [Return] 2117 bytes of code
│ │ ├─ [372255] → new MockV3Aggregator@0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3
│ │ │ └─ ← [Return] 1082 bytes of code
│ │ ├─ [516505] → new ERC20Mock@0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76
│ │ │ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: DeployDSC: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], value: 100000000000 [1e11])
│ │ │ └─ ← [Return] 2117 bytes of code
│ │ ├─ [0] VM::stopBroadcast()
│ │ │ └─ ← [Return]
│ │ └─ ← [Return] 6360 bytes of code
│ ├─ [912] HelperConfig::activeNetworkConfig() [staticcall]
│ │ └─ ← [Return] MockV3Aggregator: [0x90193C961A926261B756D1E5bb255e67ff9498A1], MockV3Aggregator: [0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3], ERC20Mock: [0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496], ERC20Mock: [0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76], 77814517325470205911140941194401928579557062014761831930645393041380819009408 [7.781e76]
│ ├─ [0] VM::startBroadcast(<pk>)
│ │ └─ ← [Return]
│ ├─ [591455] → new DecentralizedStableCoin@0x5FbDB2315678afecb367f032d93F642f64180aa3
│ │ ├─ emit OwnershipTransferred(previousOwner: 0x0000000000000000000000000000000000000000, newOwner: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)
│ │ └─ ← [Return] 2610 bytes of code
│ ├─ [985796] → new DSCEngine@0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
│ │ └─ ← [Return] 4246 bytes of code
│ ├─ [2424] DecentralizedStableCoin::transferOwnership(DSCEngine: [0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512])
│ │ ├─ emit OwnershipTransferred(previousOwner: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, newOwner: DSCEngine: [0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512])
│ │ └─ ← [Stop]
│ ├─ [0] VM::stopBroadcast()
│ │ └─ ← [Return]
│ └─ ← [Return] DecentralizedStableCoin: [0x5FbDB2315678afecb367f032d93F642f64180aa3], DSCEngine: [0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512], HelperConfig: [0x104fBc016F4bb334D775a19E8A6510109AC63E00]
├─ [912] HelperConfig::activeNetworkConfig() [staticcall]
│ └─ ← [Return] MockV3Aggregator: [0x90193C961A926261B756D1E5bb255e67ff9498A1], MockV3Aggregator: [0xBb2180ebd78ce97360503434eD37fcf4a1Df61c3], ERC20Mock: [0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496], ERC20Mock: [0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76], 77814517325470205911140941194401928579557062014761831930645393041380819009408 [7.781e76]
├─ [1065237] → new Handler@0x2e234DAe75C793f67A35089C9d99245E1C58470b
│ ├─ [1378] DSCEngine::getCollateralTokens() [staticcall]
│ │ └─ ← [Return] [0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496, 0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76]
│ └─ ← [Return] 4641 bytes of code
└─ ← [Stop]
[2793] DSCEngine::redeemCollateralForDsc(0xf6493b3CA2C716E6B5e40E233534CC237c56dDd6, 61583321711932284334241230493870068036402704009442828937579480699 [6.158e64], 76945 [7.694e4])
└─ ← [Revert] panic: arithmetic underflow or overflow (0x11)
[63620] InvariantsTest::invariant_protocolMustHaveMoreValueThanTotalSupply()
├─ [2349] DecentralizedStableCoin::totalSupply() [staticcall]
│ └─ ← [Return] 0
├─ [2607] ERC20Mock::balanceOf(DSCEngine: [0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512]) [staticcall]
│ └─ ← [Return] 0
├─ [2607] ERC20Mock::balanceOf(DSCEngine: [0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512]) [staticcall]
│ └─ ← [Return] 0
├─ [15140] DSCEngine::getUsdValue(ERC20Mock: [0xA8452Ec99ce0C64f20701dB7dD3abDb607c00496], 0) [staticcall]
│ ├─ [8993] MockV3Aggregator::latestRoundData() [staticcall]
│ │ └─ ← [Return] 1, 200000000000 [2e11], 1, 1, 1
│ └─ ← [Return] 0
├─ [15140] DSCEngine::getUsdValue(ERC20Mock: [0xDB8cFf278adCCF9E9b5da745B44E754fC4EE3C76], 0) [staticcall]
│ ├─ [8993] MockV3Aggregator::latestRoundData() [staticcall]
│ │ └─ ← [Return] 1, 4000000000000 [4e12], 1, 1, 1
│ └─ ← [Return] 0
├─ [0] console::log("wethValue: %d", 0) [staticcall]
│ └─ ← [Stop]
├─ [0] console::log("wbtcValue: %d", 0) [staticcall]
│ └─ ← [Stop]
├─ [0] console::log("totalSupply: %d", 0) [staticcall]
│ └─ ← [Stop]
└─ ← [Stop]
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 2.57ms (773.69µs CPU time)
Ran 1 test suite in 805.13ms (2.57ms CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/fuzz/InvariantsTest.t.sol:InvariantsTest
[FAIL. Reason: invariant_protocolMustHaveMoreValueThanTotalSupply persisted failure revert]
[Sequence]
sender=0x00000000000000000000000000000000E90db8A3 addr=[src/DSCEngine.sol:DSCEngine]0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 calldata=redeemCollateralForDsc(address,uint256,uint256) args=[0xf6493b3CA2C716E6B5e40E233534CC237c56dDd6, 61583321711932284334241230493870068036402704009442828937579480699 [6.158e64], 76945 [7.694e4]]
invariant_protocolMustHaveMoreValueThanTotalSupply() (runs: 1, calls: 1, reverts: 1)
Encountered a total of 1 failing tests, 0 tests succeeded If you can help me, I will appreciate |
Beta Was this translation helpful? Give feedback.
Answered by
ArnaudBand
Jun 28, 2024
Replies: 1 comment 9 replies
-
@ArnaudBand Please show your setup function. |
Beta Was this translation helpful? Give feedback.
9 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you @EngrPips for your support, I managed to fix the error.