The veRAACToken contract maintains lock positions in two separate storage locations - a direct locks
mapping and within the LockManager
library's _lockState
. This dual storage is not properly synchronized, leading to incorrect balance tracking and potential loss of funds.
The veRAACToken contract suffers from a critical design flaw in how it manages locked token positions. There are two parallel storage mechanisms for tracking locks:
First, direct mapping in the contract:
Secondly, storage in LockManager library:
The key issue lies in how these storage locations are used inconsistently:
In the increase() function:
The contract primarily uses _lockState
for lock management but inconsistently refers to the empty locks
mapping. This leads to:
Incorrect boost calculations since _updateBoostState() always receives zero amounts when locked amount is increased.
The issue also occurs when querying the getLockedBalance() and getLockEndTime() as in both cases locks
is used instead of lockState.locks
which means the values returned are always zero.
This isn't just a case of redundant storage - it's an active conflict between two sources of truth that leads to incorrect system behavior.
Alice locks 100 RAAC tokens using lock()
Lock is correctly recorded in _lockState
Alice calls increase(50)
to add more tokens
_updateBoostState()
reads from empty locks
mapping, receives 0 instead of 100
Boost calculations are performed with incorrect amounts
Incorrect boost calculations affecting reward distribution
Manual code review
Remove the redundant locks
mapping and exclusively use _lockState
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.