The withdraw and emergencyWithdraw functions in the veRAACToken contract do not correctly decrement the _lockState.totalLocked counter when users withdraw their locked tokens. While the individual user lock information is deleted, the totalLocked counter, which tracks the total amount of locked tokens in the system, is not updated. This inconsistency leads to an inaccurate totalLocked value, potentially affecting calculations and functionalities that rely on this metric.
Both the withdraw and emergencyWithdraw functions delete the user's lock information from the _lockState.locks mapping:
However, neither of these functions decrements the _lockState.totalLocked counter, which is crucial for maintaining an accurate record of the total locked tokens.
This means that after a user withdraws, _lockState.totalLocked will still reflect the withdrawn amount, leading to an overestimation of the actual total locked tokens.
The inaccurate totalLocked value can have several negative consequences:
Incorrect Boost Calculations: The BoostCalculator likely uses _lockState.totalLocked to calculate boost multipliers. An inflated totalLocked value could lead to incorrect boost calculations, potentially granting users higher or lower boosts than they should receive.
Inaccurate APR/APY Calculations: If the protocol calculates APR/APY based on the total locked amount, the inflated totalLocked value will result in incorrect APR/APY representations.
Potential Governance Issues: If governance decisions or voting power are related to the total locked amount, the inaccurate totalLocked value could skew the results.
UI/UX Issues: User interfaces that display the total locked amount will show an incorrect value, potentially confusing users.
Scenario: Alice locks 100 tokens. Bob then locks 200 tokens. The _lockState.totalLocked counter is correctly updated to 300. Alice then withdraws her 100 tokens.
Alice Locks: Alice calls lock(100, 365 days). _lockState.totalLocked becomes 100.
Bob Locks: Bob calls lock(200, 365 days). _lockState.totalLocked becomes 300.
Alice Withdraws: Alice calls withdraw(). Her lock information is deleted from _lockState.locks, but _lockState.totalLocked remains at 300.
The _lockState.totalLocked counter should now be 200, but it is incorrectly still 300.
Decrement _lockState.totalLocked in both the withdraw and emergencyWithdraw functions after deleting the user's lock information. Retrieve the amount to be decremented from the user's lock struct before it is deleted.
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.