BoostController.sol
In BoostController, each call to updateUserBoost overwrites poolBoost.workingSupply with the single user’s new boost rather than accumulating. This leads to incorrect multi-user accounting for the pool’s total boost, effectively ignoring all but the last user who updated. Fixing it requires incremental addition or subtraction based on the user’s delta in boost, ensuring the final workingSupply is the sum of all user boosts.
Overview
In updateUserBoost(...), after the contract calculates the user’s new boost (newBoost), the code does:
Observe that poolBoost.workingSupply is set to newBoost—not incremented or aggregated with other users’ boosts. If multiple users each call updateUserBoost for the same pool:
First user sets poolBoost.workingSupply = newBoostUserA.
Second user sets poolBoost.workingSupply = newBoostUserB, overwriting userA’s contribution.
The final user call overwrites the entire workingSupply with only that user’s portion.
Thus, the pool is only tracking one user’s boost at a time, not a sum. If the protocol design intended to track the combined or accumulated boosts from many users, that is not happening—leading to inaccurate or minimal “working supply.”
Incorrect Multi‑User Summations
A real gauge or multi‑user scenario demands all participants’ boosts be aggregated so the pool’s total “working supply” or “boost power” is the sum of each user’s new boost. Instead, the contract only ends with whichever user last called updateUserBoost.
Under-Rewarding or Over-Rewarding
Because the pool is not tracking the total of all user boosts, any logic (in the protocol or a referencing gauge) that depends on poolBoost.workingSupply or poolBoost.totalBoost can be drastically wrong. Possibly only one user is recognized, or if the code tries to rely on workingSupply for reward distribution, it will be inaccurate.
Expected Behavior Not Realized
The documentation indicates a “shared pool” concept with many users delegating or boosting. This single-user overwrite breaks typical multi-user designs and undermines the entire concept of pooled boosts.
A minimal scenario:
User A has an old boost of 0, calls updateUserBoost(A, pool) → newBoost = 100.
The function sets poolBoost.workingSupply = 100.
User B calls updateUserBoost(B, pool) → newBoost = 200.
The code sets poolBoost.workingSupply = 200, discarding user A’s 100.
The final “workingSupply” is 200, ignoring user A’s contribution.
Hence if the system was supposed to track “300 total” for A+B, it only sees 200. The final user call overwrote the entire working supply.
Aggregate workingSupply
Instead of poolBoost.workingSupply = newBoost, do something like:
This incrementally adjusts the pool’s supply by the user’s difference in boost from the old to new value—accumulating all users’ contributions.
Multi‑User Testing
Thoroughly test with multiple users to confirm that poolBoost.workingSupply accurately sums user boosts (like user A has 100, B has 200 → total 300).
Clarify If “One User Per Pool”
If the design truly intended only one user to boost each pool, then it must be documented. But the code strongly suggests a multi-user model, so the current approach is contradictory.
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.