DeFiLayer 1Layer 2
14,723 OP
View results
Submission Details
Severity: medium
Invalid

Price Update Denial of Service via Unrestricted Sequential Updates

Summary

The update_price function in the contract allows the PRICE_PARAMETERS_VERIFIER role to submit price updates without restriction on frequency. This means an attacker with this role can spam multiple updates in a single block, effectively preventing other valid updates from being processed in a timely manner. This creates a Denial of Service (DoS) vulnerability, which can lead to disruption in price-dependent calculations

Vulnerability Details

Affected Functions:

function update_price(uint256 new_price) external onlyRole(PRICE_PARAMETERS_VERIFIER) {
price = new_price;
emit PriceUpdated(new_price);

Issue:

  • The function does not enforce any rate-limiting mechanism (e.g., time-based restrictions or cooldowns).

  • A privileged attacker can submit multiple updates in a single block, making it difficult for others to submit their own updates.

  • This could be used maliciously to block legitimate updates or manipulate price-based calculations in the protocol.

Scenario:

  1. An attacker with PRICE_PARAMETERS_VERIFIER role calls update_price(new_price) multiple times within a single block.

  2. This floods the mempool and prevents other legitimate transactions from being mined efficiently.

  3. If external protocols rely on this price, they might be fed misleading or stale data due to this disruption

Impact

  • Funds are indirectly at risk: If other smart contracts rely on this price feed for calculations (e.g., lending, liquidation, or swaps), incorrect or delayed price updates could lead to financial losses.

  • Protocol availability is disrupted: The price mechanism can be monopolized by a single entity, preventing fair updates.

  • Potential market manipulation: Attackers could strategically spam price updates to control external protocol reactions.

Tools Used

  • Manual Review of the contract code.

  • Hardhat/Foundry (optional) for testing spam transactions.

Recommendations

Solution 1: Implement Rate Limiting

Enforce a cooldown period between successive updates:

mapping(address => uint256) public lastUpdateTime;
uint256 public updateCooldown = 1 minutes;

function update_price(uint256 new_price) external onlyRole(PRICE_PARAMETERS_VERIFIER) {
require(block.timestamp >= lastUpdateTime[msg.sender] + updateCooldown, "Cooldown active");
lastUpdateTime[msg.sender] = block.timestamp;
price = new_price;
emit PriceUpdated(new_price);
}

Solution 2: Limit Updates per Block

Restrict how many times an address can update the price in a single block:

mapping(uint256 => mapping(address => bool)) public hasUpdated;

function update_price(uint256 new_price) external onlyRole(PRICE_PARAMETERS_VERIFIER) {
require(!hasUpdated[block.number][msg.sender], "Only one update per block");
hasUpdated[block.number][msg.sender] = true;
price = new_price;
emit PriceUpdated(new_price);
}

By implementing these fixes, the risk of denial-of-service attacks is mitigated, ensuring fair price updates for all participants.

Updates

Lead Judging Commences

0xnevi Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[invalid] finding-centralization-risk

- Per [codehawks documentation](https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity#findings-that-may-be-invalid) - Parameter change is executed via the Dao per docs > Also, it is worth noting that the oracle is controlled by a DAO and its parameters can be changed by a vote.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.