Commit 540030be authored by Maurelian's avatar Maurelian

ctb: Clean up Fuzz Rsrc Metering for readability

- Use bound() instead of custom mod math
- Handle multiple empty blocks
parent 645eecf4
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { ResourceMetering } from "../L1/ResourceMetering.sol"; import { ResourceMetering } from "../L1/ResourceMetering.sol";
import { Arithmetic } from "../libraries/Arithmetic.sol";
import { StdUtils } from "forge-std/Test.sol";
contract EchidnaFuzzResourceMetering is ResourceMetering { contract EchidnaFuzzResourceMetering is ResourceMetering, StdUtils {
bool failedMaxGasPerBlock; bool failedMaxGasPerBlock;
bool failedRaiseBasefee; bool failedRaiseBasefee;
bool failedLowerBasefee; bool failedLowerBasefee;
...@@ -27,7 +29,6 @@ contract EchidnaFuzzResourceMetering is ResourceMetering { ...@@ -27,7 +29,6 @@ contract EchidnaFuzzResourceMetering is ResourceMetering {
uint256 cachedPrevBaseFee = uint256(params.prevBaseFee); uint256 cachedPrevBaseFee = uint256(params.prevBaseFee);
uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas); uint256 cachedPrevBoughtGas = uint256(params.prevBoughtGas);
uint256 cachedPrevBlockNum = uint256(params.prevBlockNum); uint256 cachedPrevBlockNum = uint256(params.prevBlockNum);
uint256 maxBasefeeChange = cachedPrevBaseFee / uint256(BASE_FEE_MAX_CHANGE_DENOMINATOR);
// check that the last block's base fee hasn't dropped below the minimum // check that the last block's base fee hasn't dropped below the minimum
if (cachedPrevBaseFee < uint256(MINIMUM_BASE_FEE)) { if (cachedPrevBaseFee < uint256(MINIMUM_BASE_FEE)) {
...@@ -44,18 +45,23 @@ contract EchidnaFuzzResourceMetering is ResourceMetering { ...@@ -44,18 +45,23 @@ contract EchidnaFuzzResourceMetering is ResourceMetering {
// raise or lower the basefee after this block, respectively // raise or lower the basefee after this block, respectively
uint256 gasToBurn; uint256 gasToBurn;
if (_raiseBaseFee) { if (_raiseBaseFee) {
gasToBurn = gasToBurn = bound(
(_gasToBurn % (uint256(MAX_RESOURCE_LIMIT) - uint256(TARGET_RESOURCE_LIMIT))) + _gasToBurn,
uint256(TARGET_RESOURCE_LIMIT); uint256(TARGET_RESOURCE_LIMIT),
uint256(MAX_RESOURCE_LIMIT)
);
} else { } else {
gasToBurn = _gasToBurn % uint256(TARGET_RESOURCE_LIMIT); gasToBurn = bound(_gasToBurn, 0, uint256(TARGET_RESOURCE_LIMIT));
} }
_burnInternal(uint64(gasToBurn)); _burnInternal(uint64(gasToBurn));
// Part 3: we run checks and modify our invariant flags based on the updated params values // Part 3: we run checks and modify our invariant flags based on the updated params values
// if the last block used more than the target amount of gas (and there were no // Calculate the maximum allowed baseFee change (per block)
uint256 maxBasefeeChange = cachedPrevBaseFee / uint256(BASE_FEE_MAX_CHANGE_DENOMINATOR);
// If the last block used more than the target amount of gas (and there were no
// empty blocks in between), ensure this block's basefee increased, but not by // empty blocks in between), ensure this block's basefee increased, but not by
// more than the max amount per block // more than the max amount per block
if ( if (
...@@ -67,9 +73,9 @@ contract EchidnaFuzzResourceMetering is ResourceMetering { ...@@ -67,9 +73,9 @@ contract EchidnaFuzzResourceMetering is ResourceMetering {
failedMaxRaiseBasefeePerBlock || failedMaxRaiseBasefeePerBlock ||
((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBasefeeChange); ((uint256(params.prevBaseFee) - cachedPrevBaseFee) < maxBasefeeChange);
} }
// if the last blocked used less than the target amount of gas (and currently,
// that there were no empty blocks in between), ensure this block's basefee decreased, // If the last blocked used less than the target amount of gas ensure this block's basefee
// but not by more than the max amount // decreased, but not by more than the max amount
if ( if (
(cachedPrevBoughtGas < uint256(TARGET_RESOURCE_LIMIT)) || (cachedPrevBoughtGas < uint256(TARGET_RESOURCE_LIMIT)) ||
(uint256(params.prevBlockNum) - cachedPrevBlockNum > 1) (uint256(params.prevBlockNum) - cachedPrevBlockNum > 1)
...@@ -77,12 +83,25 @@ contract EchidnaFuzzResourceMetering is ResourceMetering { ...@@ -77,12 +83,25 @@ contract EchidnaFuzzResourceMetering is ResourceMetering {
failedLowerBasefee = failedLowerBasefee =
failedLowerBasefee || failedLowerBasefee ||
(uint256(params.prevBaseFee) > cachedPrevBaseFee); (uint256(params.prevBaseFee) > cachedPrevBaseFee);
// TODO: account for empty blocks
if (params.prevBlockNum - cachedPrevBlockNum == 1) { if (params.prevBlockNum - cachedPrevBlockNum == 1) {
failedMaxLowerBasefeePerBlock = failedMaxLowerBasefeePerBlock =
failedMaxLowerBasefeePerBlock || failedMaxLowerBasefeePerBlock ||
((cachedPrevBaseFee - uint256(params.prevBaseFee)) < maxBasefeeChange); ((cachedPrevBaseFee - uint256(params.prevBaseFee)) < maxBasefeeChange);
} }
// Update the maxBasefeeChange to account for multiple blocks having passed
maxBasefeeChange = uint256(
Arithmetic.cdexp(
int256(cachedPrevBaseFee),
BASE_FEE_MAX_CHANGE_DENOMINATOR,
int256(uint256(params.prevBlockNum) - cachedPrevBlockNum)
)
);
if (params.prevBlockNum - cachedPrevBlockNum > 1) {
failedMaxLowerBasefeePerBlock =
failedMaxLowerBasefeePerBlock ||
((cachedPrevBaseFee - uint256(params.prevBaseFee)) < maxBasefeeChange);
}
} }
} }
......
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