The veRAACToken.sol
contract contains a storage inconsistency between two separate state variables that track lock information. The contract uses _lockState
(with the LockManager library) to manage and update lock data, but the getLockEndTime()
function incorrectly reads from a different, non-updated mapping (locks
), causing it to return incorrect values (specifically, returning 0
instead of the actual lock end time).
The contract maintains two separate data structures for tracking lock information:
A direct mapping:
A structured storage variable with the LockManager library:
When a user creates a lock via the lock() function, the contract correctly updates the _lockState variable:
However, the direct locks mapping is never updated. This becomes problematic when the getLockEndTime() function is called:
This function reads from the locks mapping rather than from _lockState, resulting in it always returning 0 (the default value) instead of the actual lock end time.
This inconsistency leads to incorrect data being returned from the getLockEndTime() function, which could mislead users or integrated protocols that rely on this function to determine when locks expire. However, since the getLockPosition().end
works correctly and provides the same information, and the getLockEndTime() function does not appear to be used in critical protocol logic, the practical impact is minimal. This is a low severity issue that represents 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 -vvvv
, NOTE: this is a testFail test so it will "pass"
Output:
Modify the getLockEndTime 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.