The _updateBoostState function called from within the veRAACToken::increase function is intended to update the boost parameters such as votingPower, totalVotingPower, and totalWeight when a user increases their lock position. The contract's storage is inconsistent when tracking the Lock struct.
The contract has a public mapping mapping(address => Lock) public locks; that is never updated while all the functions that create, increase, extend, or withdraw a Lock call library functions that work on the internal state variable _lockState.locks[msg.sender].
The problem is that the _updateBoostState function uses the locks mapping that is never updated. This means that if a user calls the increase function, their current boost multiplier and the current boosted amount will be zero and it will be out of sync with the global BoostState. This can have a direct impact on their reward calculation.
Root cause
The _updateBoostState function updates a user's boost multiplier and boosted amount based on an empty mapping that is never updated.
Users that call the increase function will have their current boost multiplier and the current boosted amount be zero and it will be out of sync with the global BoostState. The view function getCurrentBoost will return undefined for users that called increase and it will be out of sync with what the getBoostState function returns. This can lead to incorrect computation of rewards for the users, which would be a direct loss of funds for them.
Side note: since I didn't find any logic that computes the rewards on-chain in the codebase, it means that for now, this is just a view function that returns wrong values, and according to CodeHawks' rules it defaults to Low severity. If the sponsor has some off-chain mechanisms that relies on the accuracy of these view functions when computing user rewards, then this issue should be elevated to High severity during the judging phase. Since off-chain computation of rewards is not specifically mentioned anywhere in the contest's docs, I submitted this as Low instead of High.
Put this test into the veRAACToken.test.js file
Test output
You can see that the boost basis points and boosted amount have been reset to undefined.
Manual review
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.