Commit ba5742b5 authored by Maurelian's avatar Maurelian

ctb: Make FuzzBurn more robust against overflows

parent 0f8fc58a
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Burn } from "../libraries/Burn.sol"; import { Burn } from "../libraries/Burn.sol";
import { StdUtils } from "forge-std/Test.sol";
contract EchidnaFuzzBurn { contract EchidnaFuzzBurn is StdUtils {
bool failedEthBurn; bool failedEthBurn;
bool failedGasBurn; bool failedGasBurn;
...@@ -13,16 +14,18 @@ contract EchidnaFuzzBurn { ...@@ -13,16 +14,18 @@ contract EchidnaFuzzBurn {
function testBurn(uint256 _value) public { function testBurn(uint256 _value) public {
// cache the contract's eth balance // cache the contract's eth balance
uint256 preBurnBalance = address(this).balance; uint256 preBurnBalance = address(this).balance;
uint256 value = bound(_value, 0, preBurnBalance);
// execute a burn of _value eth // execute a burn of _value eth
// (may way to add guardrails to this value rather than a truly unbounded uint256) Burn.eth(value);
Burn.eth(_value);
// check that exactly _value eth was transfered from the contract // check that exactly value eth was transfered from the contract
if (address(this).balance != preBurnBalance - _value) { unchecked {
if (address(this).balance != preBurnBalance - value) {
failedEthBurn = true; failedEthBurn = true;
} }
} }
}
/** /**
* @notice Takes an integer amount of gas to burn through the Burn library and * @notice Takes an integer amount of gas to burn through the Burn library and
...@@ -30,20 +33,26 @@ contract EchidnaFuzzBurn { ...@@ -30,20 +33,26 @@ contract EchidnaFuzzBurn {
* by the library * by the library
*/ */
function testGas(uint256 _value) public { function testGas(uint256 _value) public {
// cap the value to the max resource limit
uint256 MAX_RESOURCE_LIMIT = 8_000_000;
uint256 value = bound(_value, 0, MAX_RESOURCE_LIMIT);
// cache the contract's current remaining gas // cache the contract's current remaining gas
uint256 preBurnGas = gasleft(); uint256 preBurnGas = gasleft();
// execute the gas burn // execute the gas burn
Burn.gas(_value); Burn.gas(value);
// cache the remaining gas post burn // cache the remaining gas post burn
uint256 postBurnGas = gasleft(); uint256 postBurnGas = gasleft();
// check that at least _value gas was burnt // check that at least value gas was burnt (and that there was no underflow)
if (postBurnGas > preBurnGas - _value) { unchecked {
if (postBurnGas - preBurnGas > value || preBurnGas - value > preBurnGas) {
failedGasBurn = true; failedGasBurn = true;
} }
} }
}
function echidna_burn_eth() public view returns (bool) { function echidna_burn_eth() public view returns (bool) {
// ASSERTION: The amount burned should always match the amount passed exactly // ASSERTION: The amount burned should always match the amount passed exactly
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment