This report highlights a lack of rate limiting vulnerability in the staking pool contract. The absence of rate-limiting mechanisms allows malicious users to repeatedly interact with sensitive contract functions, leading to potential disruption or abuse of system resources.
Rate limiting is crucial to prevent repeated, rapid interactions with smart contract functions that could strain resources or enable Denial of Service (DoS) attacks. In the staking pool contract, there is no limit on how frequently users can invoke critical functions such as depositQueuedTokens, performUpkeep, and withdraw. Without rate-limiting, an attacker can flood the contract with transactions, consuming gas, filling block space, and potentially causing the contract to enter a non-functional or unusable state for other users.
Affected functions:
depositQueuedTokens(uint256 _queueDepositMin, uint256 _queueDepositMax, bytes[] calldata _data): Without rate limiting, a malicious actor could repeatedly call this function to deposit tokens in rapid succession, leading to a disruption in normal deposit operations.
withdraw(address _account, uint256 _amount): Similarly, attackers could spam the withdraw function to repeatedly withdraw small amounts or invoke costly gas operations, congesting the network and contract.
performUpkeep(bytes calldata _performData): This function could also be abused by triggering upkeep operations too frequently, potentially overloading the contract and consuming unnecessary gas.
Proof of Concept (PoC):
Scenario:
An attacker, Eve, discovers that the depositQueuedTokens and withdraw functions do not have any rate limiting. Eve writes a script that submits multiple transactions per second, filling up the blockchain's capacity, consuming contract gas, and preventing legitimate users from interacting with the contract effectively.
Steps for PoC:
Deploy the Contract: The contract is deployed in a local Hardhat environment.
Simulate an Attack: Eve spams the contract with thousands of deposit or withdrawal requests in quick succession.
Result: Other users are unable to interact with the contract as Eve’s rapid transactions consume all available gas and block space. The contract becomes less responsive and fails to handle legitimate user requests.
Hardhat test case for lack of rate limiting:
This test simulates an attacker spamming the depositQueuedTokens function in rapid succession.
Attackers can flood the contract with a high volume of transactions, consuming block space and gas. This can prevent legitimate users from depositing or withdrawing tokens.
The attacker could potentially drain contract resources or lock them up in pending transactions, degrading contract performance.
Network congestion caused by repeated spam transactions can drive up gas prices, making it more expensive for other users to interact with the contract.
Manual review.
Implement a cooldown period for sensitive functions like depositQueuedTokens and withdraw. Users would need to wait a fixed time before calling these functions again.
Example:
Implement checks to ensure that transactions are processed at reasonable gas prices, reducing the incentive for attackers to spam the contract with high-priority transactions.
Limit the number of transactions a user can submit in a certain time frame or batch multiple deposit or withdrawal requests into a single transaction to reduce the frequency of function calls.
Users should only be able to interact with the contract in proportion to the amount they have staked. Higher stakers can call the functions more frequently, while smaller stakers are limited.
Implement logic to ensure that users cannot submit back-to-back transactions without a delay or a unique identifier to prevent rapid sequential execution.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.