The veRAACToken.lock()
function does not check for existing locks before creating a new one. When a user calls lock()
while having tokens already locked, the new lock overwrites the existing lock data but the original locked tokens become permanently locked in the contract.
The root cause of the issue is that the veRAACToken.lock()
function lacks check for user's current active lock position. It overwrites the existing lock data.
contracts/core/tokens/veRAACToken.sol#L212C1-L244C6
The original locked tokens remain in the contract but become inaccessible because:
The new lock's amount only tracks the newly deposited tokens
The withdraw()
function only returns the amount recorded in the current lock
There's no function to reclaim lost tokens
The following PoC demonstrates that a user locks twice but the locked and withdrawable amount will be set as the latest locked amount.
The PoC can be run by appending to the original veRAACToken.test.js
test file.
The impact is high as this issue can lead to permanent loss of user funds.
Manual code review
Add a check in lock()
for existing locks and revert if found.
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.