The manageUsersInPrivatePool
is an onlyOwner function aimed at balancing out amounts staked by users - if for a given user, the owner provided amount is less than their current deposited amount, the owner stakes the differences to reach amount. If the amount is more than the current deposited, the owner withdraws the differences to reach the amount. The problem occurs due to the wrongly set pool rate.
Both the internally called _stake
and _withdraw
functions, update the current rate (the rate is derived by the deposited amount and lastUpdate time) of the pool and the user:
poolData.rate = currentPoolRate_
userData.rate = currentPoolRate_
But the current rate variable provided to them by the manageUsersInPrivatePool()
function is taken before the beginning of the loop, thus:
On the first iteration the provided rate would be correct, but the stake/withdraw operation would change the rate
The incoming iterations would use an outdated rate, since the first iteration changed it
Most impacted would _getCurrentUserReward
for later users, since they would accumulate less rewards than they should have due to the stale rate.
Less rewards generated for users forcefully receiving/withdrawing tokens
Manual Review
Do not cache currentPoolRate_
before the loop, instead on staking do:
_stake(user_, poolId_, amount_ - deposited_, _getCurrentPoolRate(poolId_))
and on unstaking do:
_withdraw(user_, poolId_, deposited_ - amount_, _getCurrentPoolRate(poolId_))
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.