Due to a flaw in the update execution of the Secondary Pool, users can inadvertently lose ownership of their lock IDs, resulting in their staked SDL tokens being irretrievably locked within the pool. This occurs when queued full withdrawals followed by additional stakes on the same lock ID, are not processed in a manner that preserves ownership continuity.
Actions that affect a user's effective reSDL balance in the Secondary Pool, such as staking, locking, withdrawing, or initiating a withdrawal, are queued for later execution rather than being applied immediately. Users may queue multiple updates to a single lock within a batch. When an update from the primary pool arrives, these queued updates are executed in the order they were requested. If updates for a lock are not processed in the correct sequence, it can lead to a state where the owner a lock id is lost and the funds remain locked in the secondary pool .
consider a scenario where :
bob owns lockId 10 with amount: 1000 sdl .
bob decides to withdraw his staked 1000 sdl from this lockId, which will be queued.
bob decides to add another 1000 sdl tokens to the same lockId(10) , this resulting in another queued action after the withdraw one.
After the CCIPController relays the update to the primary chain and it's confirmed:
bob invokes the executeQueuedOperations function to process her pending updates.
The internal function _executeQueuedLockUpdates iterates through the updates of this lockId(10):
The first update processes which is bob's withdrawal removes the ownership of his lockId(10) and decreases his balance balance and send him the sdl tokens .
The second update, which adds more tokens, is processed next. Since baseAmountDiff is positive, it will updating the locks[lockId] with the new state and adjusting bob's effective and total balances. However, the ownership of lockId 10 is not restored since it was removed in the first update.
As a result, lockId 10 holds valid staking data but lacks an associated owner because lockOwners[10] was cleared during the withdrawal update. Consequently, the staked SDL tokens become permanently locked in the contract, and bob is unable to access his funds due to the loss of ownership. The system does not provide a way to rectify this situation and recover the locked SDL tokens.
the permanent loss of user funds and lock ownership within the Secondary Pool.
vs code
manual review
add a check to _queueLockUpdate that revert in case a full withdraw is the last update :
User trying to update a fully withdrawn lock in same batch id on secondary pool
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.