The removeBoostDelegation function tries to update boost totals using the wrong address—it uses the person removing the delegation (msg.sender) instead of an actual pool. This mixes up the data meant for pools and could mess up how the system tracks boosts.
This problem happens in the removeBoostDelegation function, which is supposed to clean up an expired delegation.
The main issue is that the function thinks the person calling it (msg.sender) is a pool, when really it’s just a regular user. Here’s the code:
Who’s Who:
from is the user who gave the boost (the delegator).
msg.sender is the user who got the boost (the recipient) and is now removing it because it expired.
It finds the delegation in userBoosts[from][msg.sender]—this part is fine and shows msg.sender is a user, not a pool. The line PoolBoost storage poolBoost = poolBoosts[msg.sender]; says, “Let’s update the boost totals for msg.sender.” Then it takes away the delegated amount:
But poolBoosts is a special list (mapping(address => PoolBoost) private poolBoosts;) meant to hold boost info for pools—like Pool X or Pool Y—not regular users.
How Pools Are Normally Used
Look at how the contract usually handles pools:
In updateUserBoost:
Here, poolBoosts[pool] uses a pool address—like a specific staking pool where boosts are applied. The pool comes from supportedPools, a list of real pool addresses.
In getPoolBoost:
Again, it’s poolBoosts[pool]—always a pool address.
Everywhere else, poolBoosts is for pools, not users. But in removeBoostDelegation, it uses poolBoosts[msg.sender], the recipient’s address as if they’re a pool.
msg.sender is the person who got the delegated boost, not a pool where boosts are used. Pools are separate things tracked in supportedPools.
When someone delegates boost (in delegateBoost), it’s saved as userBoosts[from][to], but it doesn’t say which pool it’s for. So when it’s removed, the contract doesn’t know which pool to update—it just guesses msg.sender is the pool
The delegated boost should’ve affected a real pool (like Pool X), but since the contract doesn’t know which one, it doesn’t update the right place when removing it. Pool totals stay wrong.
The boost totals (totalBoost and workingSupply) get changed for poolBoosts[msg.sender]—a user’s address that’s not even a pool. This puts junk data in the poolBoosts list where pool info should be.
Track Pools in Delegation: When boost is delegated (in delegateBoost), save which pool it’s for
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.