Boost delegator might not receive delegate fee in some cases
Description
Participating in Prisma governance requires that a user lock a balance of PRISMA tokens. Once locked, the tokens give the user lock weight, which is used in determining voting power. Anyone with lock weight has the option to make their boost available for use by other users. This is known as boost delegation. When enabling delegation, a user can set
a percentage fee, taken from the claimant and given to the delegate each time the delegate's boost is used (delegate fee), and
an optional smart contract that receives a callback each time a delegate's boost is used.
The issue here is that delegate fee is not updated as a pending reward for the boost delegator if feePct
is set to the maximum value of 10,000 and lockWeeks
is not equal to 0. This happens due to the following issue:
function _transferAllocated(
address account,
address receiver,
address boostDelegate,
uint256 amount
) internal returns (uint256) {
// ...
// apply boost delegation fee
if (fee != 0) {
fee = (adjustedAmount * fee) / 10000;
adjustedAmount -= fee;
}
// transfer or lock tokens
uint256 _lockWeeks = lockWeeks;
if (_lockWeeks == 0) prismaToken.transfer(receiver, adjustedAmount);
else {
// if token lock ratio reduces amount to zero, do nothing
uint256 lockAmount = adjustedAmount / lockToTokenRatio;
if (lockAmount == 0) return 0;
// ...
// apply delegate fee and optionally perform callback
if (fee != 0) pendingRewardFor[boostDelegate] += fee;
// ...
}
If fee
is 10,000, the adjustedAmount
would be 0. For the cases where lockWeeks
is not equal to 0, the function would return early due to the following condition:
if (lockAmount == 0) return 0
Additionally, there is a possibility of lockAmount
becoming 0 due to rounding in the division operation:
uint256 lockAmount = adjustedAmount / lockToTokenRatio;
As a result, the pendingRewardFor[boostDelegate]
mapping may not be updated with the correct fee amount in such cases.
Impact
The impact of this issue is that the boost delegator may not be able to receive their rewards in some cases.
Recommendations
If lockAmount
is 0, the recommended action is to add the fee
to the boost delegator and then perform the delegator call before the function is returned.
Remediation
This issue has been acknowledged by Prisma Finance, and a fix was implemented in commit d85dcadb↗.