Closed c4-bot-10 closed 8 months ago
18 decimals is a usable assumption for us
141345 marked the issue as insufficient quality report
invalid
it has nothing to do with reward token decimal, notifyRewardAmount()
, any amount as reward will work with rewardRate
thereksfour marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2024-03-abracadabra-money/blob/1f4693fdbf33e9ad28132643e2d6f7635834c6c6/src/staking/LockingMultiRewards.sol#L277-L286 https://github.com/code-423n4/2024-03-abracadabra-money/blob/1f4693fdbf33e9ad28132643e2d6f7635834c6c6/src/staking/LockingMultiRewards.sol#L292-L295
Vulnerability details
Impact
notifyRewardAmount()
function enables operator to add rewards for whitelisted tokens by the owner (the owner sets the whitelisted rewards tokens viaaddReward()
function):as can be noticed; the
reward.rewardRate
will have the same decimals of the rewards token.Whenever the global rewards are updated via
_updateRewardsGlobal()
; the_rewardData[token_].rewardPerTokenStored
is calculated by_rewardPerToken()
funtion:So as can be noticed; the
pendingRewardsPerToken
is calculated assuming that thetotalSupply_
(that represents the total locked and unlocked amounts of staked token) is of 18 decimals (as it multiplies by 1e18 to get rid of the totalSupply decimals).But this assumption will not be always true as the staking tokens can be of any decimal.
Same assumption is made when user's rewards are updated, the
rewards[user_][token_]
is updated via_earned()
function:and as can be noticed, the
pendingUserRewardsPerToken
will have the same decimals of the rewards token, while thebalance_
will have the decimals of the staking tokens, so when dividing by 1e18; we are assuming that the staking decimals are 18.So if the contract is deployed with a staking token of decimals != 18; the rewards calculation will be incorrect, resulting in lower rewards amounts if the staking token decimals are < 18, and resulting in higher rewards amounts (draining the contract rewards) if the staking token decimals are > 18.
Proof of Concept
LockingMultiRewards._rewardPerToken function
LockingMultiRewards._earned function
Tools Used
Manual Review.
Recommended Mitigation Steps
Instead of using a magic number to normalize the totalSupply and user balance (1e18); use an immutable variable to save this value based on the staking token decimals upon deployment:
Assessed type
Decimal