DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

Gas Exhaustion Risk in Bulk Unstaking

Description:
The unstakeAll function iterates over all active deposits to unstake them, which could lead to gas limit issues if the user has a large number of active deposits. This could cause the transaction to fail due to running out of gas.

Location:

src/FjordStaking.sol

  • unstakeAll function (Line 570)

Issue:
If a user has a large number of active deposits, the unstakeAll function could potentially run out of gas during execution, causing the transaction to revert. This could prevent users from unstaking their tokens, leading to frustration and potential financial losses.

Impact:

  • The inability to unstake tokens due to gas limit issues could lead to a denial of service for users, especially those with a large number of active deposits.

Tools used: Manual Review.

Recommendations:
Consider implementing a batching mechanism to allow users to unstake their deposits in smaller, more manageable chunks, reducing the risk of gas limit issues.

Potential changes:

  • Implement batching for the unstakeAll function to prevent gas limit issues.

Changes needed for which line of code:

  • Implement Batching -

    (Example)

function unstakeAll(uint16 batchSize)
external
checkEpochRollover
redeemPendingRewards
returns (uint256 totalStakedAmount)
{
uint256[] memory activeDeposits = getActiveDeposits(msg.sender);
if (activeDeposits.length == 0) revert NoActiveDeposit();
for (uint16 i = 0; i < activeDeposits.length && i < batchSize; i++) {
uint16 epoch = uint16(activeDeposits[i]);
DepositReceipt storage dr = deposits[msg.sender][epoch];
if (dr.epoch == 0 || currentEpoch - epoch <= lockCycle) continue;
totalStakedAmount += dr.staked;
if (dr.vestedStaked == 0) {
delete deposits[msg.sender][epoch];
_activeDeposits[msg.sender].remove(epoch);
} else {
dr.staked = 0;
}
}
totalStaked -= totalStakedAmount;
userData[msg.sender].totalStaked -= totalStakedAmount;
fjordToken.transfer(msg.sender, totalStakedAmount);
points.onUnstaked(msg.sender, totalStakedAmount);
emit UnstakedAll(msg.sender, totalStakedAmount, activeDeposits, getActiveDeposits(msg.sender));
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago
inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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