The veRAACToken.sol contract exhibits a storage inconsistency in the getLockedBalance() function. This function incorrectly reads lock data from a mapping that is never updated during lock operations, causing it to return 0 instead of the actual locked token amount. This creates a discrepancy where getLockPosition() returns the correct locked amount while getLockedBalance() always returns 0.
The veRAACToken.sol contract maintains two separate storage structures for tracking lock information:
A direct mapping defined in the contract:
A structured storage variable that uses the LockManager library:
The issue is that when a user creates a lock through the lock() function, only the _lockState variable is updated:
The getLockedBalance() function incorrectly reads from the direct locks mapping:
Since this mapping is never updated during lock creation, the function always returns 0 regardless of the actual locked amount.
This inconsistency means that any user or protocol relying on the getLockedBalance() function will receive incorrect information (0) about locked token amounts. Since getLockPosition() provides correct information, this is unlikely to cause financial loss, but it could lead to confusion, inaccurate display of locked token amounts in UIs, or integration issues with protocols that rely on getLockedBalance(). As the function does not appear to be used in critical protocol logic, this is assessed as a low severity issue representing a correctness bug rather than a security vulnerability.
Convert the project into a foundry project, ensuring test in foundry.toml points to a designated test directory.
Comment out the forking object from the hardhat.congif.cjs file:
Copy the following code into the test folder:
Run forge test -vv
Output:
Modify the getLockedBalance function to read from _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.