The veRAACToken contract contains a redundant locks mapping that is never updated, causing the getLockedBalance function to always return zero. This issue arises because the contract uses the LockManager.LockState library for managing locks, but the locks mapping in the main contract is not synchronized with the library's state.
The issue stem from locks mapping in the veRAACToken contract and the getLockedBalance function.
Two Mappings:
locks (public, at contract level): mapping(address => Lock) public locks
_lockState.locks (private, within LockManager.LockState): mapping(address => Lock) locks
Updates:
All lock-related operations (lock, increase, extend, withdraw, emergencyWithdraw) use _lockState.locks via LockManager functions:
createLock updates _lockState.locks[user]
increaseLock modifies _lockState.locks[user].amount
extendLock updates _lockState.locks[user].end
withdraw and emergencyWithdraw delete _lockState.locks[msg.sender]
The contract-level locks mapping is never updated in any function. It remains in its default state (all fields zeroed: amount = 0, end = 0, exists = false).
Behaviour
getLockedBalance reads from locks[account].amount, not _lockState.locks[account].amount.
Since locks is never written to, getLockedBalance will always return 0 for any account, regardless of actual locked balances managed by _lockState.
The locks mapping duplicates the structure of _lockState.locks but serves no functional purpose beyond getLockedBalance, which is broken due to lack of updates.
Example Scenario :
A user locks 100 RAAC tokens for 1 year using the lock function.
The LockManager.LockState library updates its internal locks mapping correctly.
However, the locks mapping in the veRAACToken contract remains unchanged.
When the user calls getLockedBalance, it returns 0 instead of the expected 100.
Users querying getLockedBalance will receive incorrect data, leading to confusion about their locked balances.
Manual Review
Remove redundant mapping to eliminate locks and update getLockedBalance to use _lockState.locks.
Sync mappings to update locks alongside _lockState.locks (might cost more gas).
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.