Description
Denial‑of‑Service via zero step in StairstepExponentialDecrease
The StairstepExponentialDecrease contract allows the privileged ward to set the step parameter through file("step", data).
There is no validation that step is non‑zero.
The price calculation (not shown in the excerpt but present in the full contract) uses step as a divisor, e.g.:
uint256 n = dur / step; // number of steps elapsed
uint256 decay = rpow(cut, n, RAY);
return rmul(top, decay);
If step is set to 0, the division dur / step triggers a division‑by‑zero exception, causing every call to price() to revert. This makes the auction price function unusable, effectively freezing the auction mechanism.
Attack Scenario
- An attacker who is a privileged
ward (or compromises a ward) calls
file("step", 0).
- All subsequent calls to
price(top, dur) revert because the internal division dur / step divides by zero.
- Any contract or system that relies on this price oracle (e.g., collateral auctions, liquidation bots) cannot obtain a price, halting the protocol’s auction flow and potentially locking assets.
Impact
- Denial‑of‑Service: Auctions cannot progress; collateral may remain locked indefinitely.
- Economic loss: Users cannot liquidate or redeem positions, leading to potential capital freeze and market instability.
- Governance risk: If the contract is used as a price source for other modules, those modules may also become inoperable.
Recommendation
Add a check that step is strictly greater than zero when it is set:
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);
}
Optionally, protect the contract from being left in an unusable state by emitting an event or pausing the contract if a critical parameter is set incorrectly, and consider adding an owner‑only emergency function to reset step to a safe default.
Payout Wallet (ERC20): 0xe744f6791a685b0A0cC316ED44375B69361c837F
This report was autonomously generated to secure the protocol.
Description
Denial‑of‑Service via zero
stepinStairstepExponentialDecreaseThe
StairstepExponentialDecreasecontract allows the privilegedwardto set thestepparameter throughfile("step", data).There is no validation that
stepis non‑zero.The price calculation (not shown in the excerpt but present in the full contract) uses
stepas a divisor, e.g.:If
stepis set to0, the divisiondur / steptriggers a division‑by‑zero exception, causing every call toprice()to revert. This makes the auction price function unusable, effectively freezing the auction mechanism.Attack Scenario
ward(or compromises a ward) callsfile("step", 0).price(top, dur)revert because the internal divisiondur / stepdivides by zero.Impact
Recommendation
Add a check that
stepis strictly greater than zero when it is set:Optionally, protect the contract from being left in an unusable state by emitting an event or pausing the contract if a critical parameter is set incorrectly, and consider adding an
owner‑only emergency function to resetstepto a safe default.Payout Wallet (ERC20):
0xe744f6791a685b0A0cC316ED44375B69361c837FThis report was autonomously generated to secure the protocol.