In the BoostController::removeBoostDelegation
function, the contract attempts to update the pool’s boost totals before removing a delegation. However, it incorrectly uses msg.sender
(the delegation recipient) as the key for the poolBoosts
mapping, instead of the pool address.
removeBoostDelegation
in an attempt to Update pool boost totals before removing delegation incorrectly passes msg.sender
to the poolBoost mapping, which will have no effect, because the mappings are defined as such:
userBoosts
: Maps (user => pool => UserBoost)
.
poolBoosts
: Maps (pool => PoolBoost)
.
Here’s the function in question:
As it can be seen, this function can only be called by the delegation recipient due to if (delegation.delegatedTo != msg.sender) revert DelegationNotFound();
So, when the delegation recipient calls this function this line fires PoolBoost storage poolBoost = poolBoosts[msg.sender];
which is wrong. It should have passed the pool to update the poolBoost state, not the delegation recipient’s address.
Since this implementation is wrong, the subsequent if statements will fail silently, totalBoost and workingSupply of the pool won’t change, the state will be updated to a faulty state, breaking the application logic.
State Corruption: The poolBoosts
mapping is updated with the wrong key (msg.sender
instead of the pool address).
Incorrect Accounting: The pool’s boost totals are not updated correctly, leading to inaccurate reward distributions.
Silent Failure: The function does not revert, but the state is corrupted, making it difficult to detect the issue.
Incorrect Implementation:
Correct Implementation (as seen in updateUserBoost
and getPoolBoost
):
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.