Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: low
Invalid

Unlimited Withdrawal Requests Enable Storage Bloat and DoS

Summary

The initiateWithdrawal function allows users to create an unlimited number of withdrawal requests, leading to potential storage bloat and increased gas costs.

Vulnerability Details

The initiateWithdrawal function in the vault management system permits users to initiate withdrawal requests without any restrictions on the number of active requests per user. This lack of limitation can result in storage bloat, as each request consumes storage space. Additionally, an attacker could exploit this by creating a large number of withdrawal requests, potentially causing a Denial of Service by exhausting the contract's storage or making subsequent transactions prohibitively expensive.

Impact

I'm rating this as LOW because it doesn't have significant impact on the protocol but could lead to storage bloat and increased gas costs, affecting the contract's operational efficiency and financial sustainability.

Tools Used

Manual Review

Recommendations

Implement a limit on the number of active withdrawal requests a user can have at any given time to prevent storage bloat and potential DoS attacks.

function initiateWithdrawal(uint128 vaultId, uint128 shares) external {
if (shares == 0) {
revert Errors.ZeroInput("sharesAmount");
}
// fetch storage slot for vault by id, vault must exist with valid collateral
Vault.Data storage vault = Vault.loadLive(vaultId);
if (!vault.collateral.isEnabled) revert Errors.VaultDoesNotExist(vaultId);
// Check if the user has reached the maximum number of active withdrawal requests
uint128 maxWithdrawalRequests = 5; // Example limit
require(vault.withdrawalRequestIdCounter[msg.sender] < maxWithdrawalRequests, "Too many active withdrawal requests");
// increment vault/user withdrawal request counter and set withdrawal request id
uint128 withdrawalRequestId = ++vault.withdrawalRequestIdCounter[msg.sender];
// load storage slot for withdrawal request
WithdrawalRequest.Data storage withdrawalRequest =
WithdrawalRequest.load(vaultId, msg.sender, withdrawalRequestId);
// update withdrawal request create time
withdrawalRequest.timestamp = block.timestamp.toUint128();
// update withdrawal request shares
withdrawalRequest.shares = shares;
// transfer shares to the contract to be later redeemed
IERC20(vault.indexToken).safeTransferFrom(msg.sender, address(this), shares);
// emit an event
emit LogInitiateWithdrawal(vaultId, msg.sender, shares);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!