Severity: Medium
Impact: Medium
Likelihood: Medium
Summary
In the case a user will call lock()
with a dust amout, and a minimum duration
then he will not get a veTokens at all.
Description
The function lock()
can accept a dust amount and the duration
365 days.
2025-02-raac/contracts/core/tokens/veRAACToken.sol at 89ccb062e2b175374d40d824263a4c0b601bcb7f · Cyfrin/2025-02-raac · GitHub
function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
if (amount == 0) revert InvalidAmount();
if (amount > MAX_LOCK_AMOUNT) revert AmountExceedsLimit();
if (totalSupply() + amount > MAX_TOTAL_SUPPLY) revert TotalSupplyLimitExceeded();
if (duration < MIN_LOCK_DURATION || duration > MAX_LOCK_DURATION)
revert InvalidLockDuration();
raacToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 unlockTime = block.timestamp + duration;
_lockState.createLock(msg.sender, amount, duration);
_updateBoostState(msg.sender, amount);
(int128 bias, int128 slope) = _votingState.calculateAndUpdatePower(
msg.sender,
amount,
unlockTime
);
uint256 newPower = uint256(uint128(bias));
_checkpointState.writeCheckpoint(msg.sender, newPower);
_mint(msg.sender, newPower);
emit LockCreated(msg.sender, amount, unlockTime);
}
Then calculateAndUpdatePower()
will calculate values for bias
and slope
as a zero.
2025-02-raac/contracts/libraries/governance/VotingPowerLib.sol at 89ccb062e2b175374d40d824263a4c0b601bcb7f · Cyfrin/2025-02-raac · GitHub
function calculateAndUpdatePower(
VotingPowerState storage state,
address user,
uint256 amount,
uint256 unlockTime
) internal returns (int128 bias, int128 slope) {
if (amount == 0 || unlockTime <= block.timestamp) revert InvalidPowerParameters();
uint256 MAX_LOCK_DURATION = 1460 days;
uint256 duration = unlockTime - block.timestamp;
uint256 initialPower = (amount * duration) / MAX_LOCK_DURATION;
bias = int128(int256(initialPower));
slope = int128(int256(initialPower / duration));
uint256 oldPower = getCurrentPower(state, user, block.timestamp);
state.points[user] = RAACVoting.Point({
bias: bias,
slope: slope,
timestamp: block.timestamp
});
_updateSlopeChanges(state, unlockTime, 0, slope);
emit VotingPowerUpdated(user, oldPower, uint256(uint128(bias)));
return (bias, slope);
}
initialPower
will be calculated as a zero, as well as bias
and slope
. Then in the lock()
a newPower
will be zero and the user will receive no tokens.
_mint(msg.sender, newPower);
Impact
The case when a user can send very small amount is uncommon. But this case must be considered otherwise user lose his funds and this will affect the contract reputation.