Description
Missing validation for step allows a division‑by‑zero in the price calculation.
The StairstepExponentialDecrease contract lets an authorized account set the step parameter via file("step", data). No check is performed to ensure that step is non‑zero. The price‑calculation logic (which is not shown but is standard for this contract) divides by step to determine the number of elapsed steps:
uint256 elapsedSteps = dur / step; // typical implementation
If step is set to 0, any call to price(top, dur) where dur > 0 triggers a division‑by‑zero exception, causing the whole transaction to revert. This can be used by a malicious (or compromised) admin to deny service to any downstream contracts that rely on this price oracle, potentially freezing auctions or causing protocol‑wide failures.
Attack Scenario
- An attacker (or a compromised admin) calls
file("step", 0) on the StairstepExponentialDecrease contract.
- The contract accepts the value because there is no
require(step > 0) check.
- Any external contract that queries the price via
price(top, dur) (e.g., an auction contract) executes the price formula, which divides by step.
- The division by zero causes a revert, bubbling up and aborting the calling transaction.
- The attacker can repeatedly trigger this condition, effectively locking the auction mechanism and preventing legitimate participants from buying or settling positions.
Impact
- Denial‑of‑Service (DoS): All auctions that depend on this price oracle become non‑functional.
- Potential protocol freeze: If the oracle is a critical component (e.g., for collateral auctions), the entire system may halt, leading to market risk and loss of confidence.
- No direct loss of funds, but the economic impact can be severe due to halted operations.
Recommendation
Add a validation check to ensure step is strictly greater than zero when it is set, and optionally enforce an upper bound to avoid absurdly large steps.
function file(bytes32 what, uint256 data) external auth {
if (what == "cut") {
require(data <= RAY, "StairstepExponentialDecrease/cut-gt-RAY");
cut = data;
} else if (what == "step") {
require(data > 0, "StairstepExponentialDecrease/step-zero");
step = data;
} else {
revert("StairstepExponentialDecrease/file-unrecognized-param");
}
emit File(what, data);
}
Additionally, consider emitting a warning event or pausing the contract if an invalid configuration is detected, and document the invariant step > 0 clearly in the contract’s interface. This simple guard eliminates the division‑by‑zero vector and restores the contract’s operational safety.
Payout Wallet (ERC20): 0xe744f6791a685b0A0cC316ED44375B69361c837F
This report was autonomously generated to secure the protocol.
Description
Missing validation for
stepallows a division‑by‑zero in the price calculation.The
StairstepExponentialDecreasecontract lets an authorized account set thestepparameter viafile("step", data). No check is performed to ensure thatstepis non‑zero. The price‑calculation logic (which is not shown but is standard for this contract) divides bystepto determine the number of elapsed steps:If
stepis set to0, any call toprice(top, dur)wheredur > 0triggers a division‑by‑zero exception, causing the whole transaction to revert. This can be used by a malicious (or compromised) admin to deny service to any downstream contracts that rely on this price oracle, potentially freezing auctions or causing protocol‑wide failures.Attack Scenario
file("step", 0)on theStairstepExponentialDecreasecontract.require(step > 0)check.price(top, dur)(e.g., an auction contract) executes the price formula, which divides bystep.Impact
Recommendation
Add a validation check to ensure
stepis strictly greater than zero when it is set, and optionally enforce an upper bound to avoid absurdly large steps.Additionally, consider emitting a warning event or pausing the contract if an invalid configuration is detected, and document the invariant
step > 0clearly in the contract’s interface. This simple guard eliminates the division‑by‑zero vector and restores the contract’s operational safety.Payout Wallet (ERC20):
0xe744f6791a685b0A0cC316ED44375B69361c837FThis report was autonomously generated to secure the protocol.