Summary
The contract inconsistently updates poolBoosts
across different functions:
Vulnerability Details
Inconsistent Access in removeBoostDelegation()
function removeBoostDelegation(address from) external override nonReentrant {
UserBoost storage delegation = userBoosts[from][msg.sender];
if (delegation.delegatedTo != msg.sender) revert DelegationNotFound();
if (delegation.expiry > block.timestamp) revert InvalidDelegationDuration();
PoolBoost storage poolBoost = poolBoosts[msg.sender];
if (poolBoost.totalBoost >= delegation.amount) {
poolBoost.totalBoost -= delegation.amount;
}
if (poolBoost.workingSupply >= delegation.amount) {
poolBoost.workingSupply -= delegation.amount;
}
poolBoost.lastUpdateTime = block.timestamp;
emit DelegationRemoved(from, msg.sender, delegation.amount);
delete userBoosts[from][msg.sender];
}
Problem:
The function removes boost from poolBoosts[msg.sender]
instead of the actual pool.
If msg.sender
is not the correct pool, boost removal could affect the wrong pool.
This creates governance weight miscalculations, misallocates voting power, and incorrectly adjusts staking rewards.
Correct Behavior in updateUserBoost()
PoolBoost storage poolBoost = poolBoosts[pool];
Impact
-
Boost tracking can be incorrect, leading to voting power miscalculations.
Users may remove boosts from the wrong pool, creating governance imbalances.
Tools Used
Manual Review
Recommendations
Modify removeBoostDelegation()
to correctly reference the delegated pool instead of msg.sender
.
function removeBoostDelegation(address from) external override nonReentrant {
UserBoost storage delegation = userBoosts[from][msg.sender];
if (delegation.delegatedTo != msg.sender) revert DelegationNotFound();
if (delegation.expiry > block.timestamp) revert InvalidDelegationDuration();
address pool = delegation.delegatedTo;
PoolBoost storage poolBoost = poolBoosts[pool];
if (poolBoost.totalBoost >= delegation.amount) {
poolBoost.totalBoost -= delegation.amount;
}
if (poolBoost.workingSupply >= delegation.amount) {
poolBoost.workingSupply -= delegation.amount;
}
poolBoost.lastUpdateTime = block.timestamp;
emit DelegationRemoved(from, pool, delegation.amount);
delete userBoosts[from][msg.sender];
}