In BoostController
contract, users can delegate boosts to other users by calling delegateBoost
function. However, there’s no deduction from the caller’s side, which leads to incorrect state and double spending.
UserBoost
is a complicated struct, because it attempts to track user boost data for both a specific pool, or delegation.
Now, say Alice delegates her boost to Bob via delegateBoost
. This code block will be fired:
But there’s nothing taken from Alice’s boosting power. She did give some power to Bob, but did not lose anything herself. An example of how a user’s boosts for a pool is captured and changed is seen in updateUserBoost
function.
This is how you get a user’s boost for a pool: UserBoost storage userBoost = userBoosts[user][pool];
And this is how you get for boost for a user (in delegateBoost): UserBoost storage delegation = userBoosts[msg.sender][to];
Back in updateUserBoost
we also see how the pool totals are updated:
Now now, Alice is using the amount she has for this pool, and also she has given some to Bob, but her boosting power for this pool has not been deducted. So, Alice can spend her power freely, without using it up. She can give the same boost to Bob, Emily, Candice, and Louie. This can’t be good.
Double spending let’s the user to boost as much users as they want without losing boosting power themselves.
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.