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.