The _executeQueuedLockUpdates
function in SDLPoolSecondary
has a potential vulnerability that allows withdrawals without explicitly checking if the unlock period has been initiated using the initiateUnlock
function. This omission could lead to unintended behavior and may result in undesired consequences for users interacting with the staking mechanism.
In the withdrawal section of the _executeQueuedLockUpdates
function, the code initiates withdrawals based on the condition that baseAmountDiff
is negative. However, it lacks an explicit check to ensure that the unlock period has been properly initiated using the initiateUnlock
function. This could potentially allow users to withdraw funds without going through the required unlock process.
The impact of this vulnerability is significant, as it may allow users to prematurely withdraw funds from their locks without adhering to the intended unlocking mechanism. This could undermine the logic of the staking contract and result in unexpected financial outcomes for both users and the contract itself.
Proof of Concept (PoC) Steps:
Create a Lock by Staking SDL:
User initiates the creation of a lock by staking SDL tokens.
This process involves calling a function, e.g., createLock
, to establish a staking position with specified parameters like amount and locking duration.
Update the Lock:
After creating the lock, the user decides to update it by increasing the staked amount.
The user calls the update function, e.g., updateLock
, which internally triggers _queueLockUpdate
to queue the updated lock information in the queuedLockUpdates
array.
Execute Queued Operations:
The user decides to execute queued operations by calling the external function executeQueuedOperations
and passing the relevant _lockIds
.
Execute Queued Lock Updates (_executeQueuedLockUpdates
):
The executeQueuedOperations
function calls the internal function _executeQueuedLockUpdates
.
Within _executeQueuedLockUpdates
, the function iterates through the queued updates for the specified lock using the queuedLockUpdates
array.
Withdrawal Without Unlock Initiation Check:
During the iteration, when the condition if (baseAmountDiff < 0)
is satisfied, a withdrawal operation is triggered.
Notably, there is no explicit check to verify whether the lock has been initiated for unlocking using the initiateUnlock
function.
Withdrawal Operation:
The line sdlToken.safeTransfer(_owner, uint256(-1 * baseAmountDiff));
is executed, facilitating the withdrawal of the staked amount to the user.
Proof of Vulnerability:
Since there is no explicit check for unlock initiation, the user is able to withdraw funds from the lock without initiating the unlock process through the initiateUnlock
function.
This constitutes a vulnerability, as withdrawals should ideally be contingent on the proper initiation of the unlock period.
Manual review.
Implement Check for Unlock Initiation:
Modify the withdrawal section of the _executeQueuedLockUpdates
function to include an explicit check for the initiation of the unlock period. Ensure that withdrawals are only allowed if the unlock period has been properly initiated using the initiateUnlock
function.
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.