Summary
Incorrect lock amount calculation in veRAACToken::increase(). This will cause that users can get more voting power that expected via the increase().
Vulnerability Details
In veRAACToken::increase(), users can increase their RAAC locking amount and do not change the locking period. We will use the updated locking amount to re-calculate the initial voting power for the locker.
The problem is that we've already updated the userLock.amount
in function increaseLock(). When we calculate the updated initial power, we use the userLock.amount + amount
, this will cause that the additional amount is added twice when we calculate the updated initial power. The users can get more voting power that expected.
function increase(uint256 amount) external nonReentrant whenNotPaused {
@> _lockState.increaseLock(msg.sender, amount);
_updateBoostState(msg.sender, locks[msg.sender].amount);
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
(int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
@> userLock.amount + amount,
userLock.end
);
function increaseLock(
LockState storage state,
address user,
uint256 additionalAmount
) internal {
Lock storage lock = state.locks[user];
if (!lock.exists) revert LockNotFound();
if (lock.end <= block.timestamp) revert LockExpired();
if (lock.amount + additionalAmount > state.maxLockAmount) revert AmountExceedsLimit();
lock.amount += additionalAmount;
state.totalLocked += additionalAmount;
}
Impact
Users can get more voting power than expected via increase().
Tools Used
Manual
Recommendations
@@ -257,7 +267,8 @@ contract veRAACToken is ERC20, Ownable, ReentrancyGuard, IveRAACToken {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
(int128 newBias, int128 newSlope) = _votingState.calculateAndUpdatePower(
msg.sender,
- userLock.amount + amount,
+ userLock.amount,
userLock.end
);