There's a critical issue in the _withdraw()
function of the OperatorStakingPool.sol
contract, where the withdrawal process does not actually transfer tokens back to operators. This leaves operators unable to retrieve their staked tokens after requesting a withdrawal. The missing token transfer results in the function only updating internal accounting without performing the required external action, leading to an incomplete withdrawal process and loss of all LST tokens staked in the contract.
The _withdraw()
function reduces the share balance of the operator and emits a Withdraw event but does not perform the actual transfer of tokens from the contract to the operator. As a result, the operator will see the reduction in their balance but won't receive any tokens, meaning the withdrawal process remains incomplete.
This issue directly affects the contract's functionality, as operators who wish to withdraw their LST will not be able to do so, locking their funds inside the contract indefinitely.
POC
Add the following test in linkStaking/operator-staking-pool.test.ts
The consequences of this issue are severe, as it directly affects operator's ability to withdraw their staked tokens. Operators will see their balances decrease after initiating a withdrawal, but they will never actually receive their tokens. This will lead to funds trapped in the contract, making the staked LST tokens inaccessible. All operator's LST stake will be lost.
Manual analysis
A transfer operation in the _withdraw()
function to move the correct amount of LST tokens from the contract to the operator should be added:
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.