stake.link

stake.link
DeFiHardhatBridge
27,500 USDC
View results
Submission Details
Severity: high
Invalid

Secondary sdlPool is vulnerable to re-entrant withdrawals

Summary

A malicious RESDL token holder can queue a withrawal request, then queue any subsequent number of extended lock durations in order to effectively earn receive more withdrawal tokens.

Vulnerability Details

A malicious user of the protocol on the secondary pool can essentially request a withdrawal by call the withdraw() function, which will in turn queue a new lock update.
Then the user proceeds to call the extendLockDuration() function with incremental duration times not exceeding the maximum lock duration, this can be done any number of times before an update.
In turn after the current update batch has been updated then the user proceeds to execute their updates.

The execution of such a call chain will end up in the function _executeQueuedLockUpdates() in which the exploit emanates from the line

int256 baseAmountDiff = int256(updateLockState.amount) - int256(curLockState.amount);

the error in this statement comes from the subtraction of current update state which will be zero and the current lock state which is not updated for the current lockID.

Although this is one exploit the root cause lies in putting the line

Lock memory curLockState = locks[lockId];

outside the loop

while (j < numUpdates) {...}

This in turn will allow a user to re-enter the withdrawal block of the if statement in the while loop, since baseAmountDiff is less than zero.

Impact

Loss of funds.

Tools Used

Manual Review

Recommendations

I would recommend putting the line

Lock memory curLockState = locks[lockId];

inside the while loop to get the updated lock for each lockId subsequent update

Updates

Lead Judging Commences

0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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