The lock
function in the veRAACToken
contract calculates the number of veTokens minted using integer division, which can result in zero veTokens being issued when small amounts or short durations are used. This occurs because the formula (amount * duration) / MAX_LOCK_DURATION
truncates fractional results, leading to a loss of funds for users locking small amounts.
The issue stem from lock
function in the veRAACToken
contract and the calculateAndUpdatePower
function in the VotingPowerLib
library.
The formula (amount * duration) / MAX_LOCK_DURATION
is used to calculate the initial voting power (bias).
Solidity performs integer division, truncating any fractional result to the nearest lower integer.
For small values of amount
or duration
, the numerator (amount * duration
) may be smaller than MAX_LOCK_DURATION
, resulting in a truncated value of zero.
Example Scenarios :
Lock 1 Token for 1 Year :
amount = 1e18
duration = 31,536,000 seconds
initialPower = (1e18 * 31,536,000) / 126,144,000 ≈ 0.25e18 → 0
(truncated)
Lock 0.1 Token for 1 Year :
amount = 1e17
duration = 31,536,000 seconds
initialPower = (1e17 * 31,536,000) / 126,144,000 ≈ 0.025e18 → 0
(truncated)
Users who lock small amounts or short durations receive no veRAAC tokens, meaning they cannot participate in governance or benefit from boosts.
The issue could lead to frustration among users, as they expect to receive proportional voting power for their locked tokens but instead receive none.
Small holders are disproportionately affected, as they are more likely to lock small amounts. This undermines the inclusivity of the system.
Manual Review
Implement the minimum value fix (newPower = 1
when truncated to 0) for simplicity and user fairness. Scaling is an option but requires careful overflow handling given the large numbers involved
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.