Platform: Code4rena
Start Date: 26/05/2022
Pot Size: $75,000 USDT
Total HM: 31
Participants: 71
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 18
Id: 126
League: ETH
Rank: 37/71
Findings: 2
Award: $199.53
π Selected for report: 0
π Solo Findings: 0
π Selected for report: xiaoming90
Also found by: 0xNazgul, FSchmoede, Funen, Kumpa, VAD37, berndartmueller, cccz, kirk-baird
The setFeeInfo function of the Booster contract is used to set the lockFeesIncentive and stakerLockFeesIncentive variables. In the earmarkFees function, the feeToken in the contract will be transferred to lockFees and stakerLockRewards according to the proportion. If lockFeesIncentive + stakerLockFeesIncentive > FEE_DENOMINATOR, the number of tokens to be transferred by the earmarkFees function will be greater than the balance, causing the earmarkFees call to fail.
https://github.com/code-423n4/2022-05-vetoken/blob/2d7cd1f6780a9bcc8387dea8fecfbd758462c152/contracts/Booster.sol#L193-L197 https://github.com/code-423n4/2022-05-vetoken/blob/2d7cd1f6780a9bcc8387dea8fecfbd758462c152/contracts/Booster.sol#L575-L595
None
function setFeeInfo(uint256 _lockFeesIncentive, uint256 _stakerLockFeesIncentive) external { require(msg.sender == feeManager, "!auth"); + require(_lockFeesIncentive + _stakerLockFeesIncentive <= FEE_DENOMINATOR) lockFeesIncentive = _lockFeesIncentive; stakerLockFeesIncentive = _stakerLockFeesIncentive;
#0 - jetbrain10
2022-06-15T15:17:14Z
same as issues #215
#1 - GalloDaSballo
2022-07-24T23:47:30Z
Dup of #215
π Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xDjango, 0xNazgul, 0xf15ers, BouSalman, Chom, Deivitto, Dravee, ElKu, FSchmoede, Funen, GimelSec, Hawkeye, MiloTruck, Picodes, SecureZeroX, SmartSek, TerrierLover, WatchPug, _Adam, asutorufos, berndartmueller, c3phas, catchup, cccz, cogitoergosumsw, cryptphi, csanuragjain, delfin454000, dipp, ellahi, gzeon, hansfriese, horsefacts, hyh, kirk-baird, minhquanym, oyc_109, pauliax, reassor, robee, sashik_eth, shenwilly, simon135, sorrynotsorry, sseefried, unforgiven, xiaoming90, z3s
99.9237 USDT - $99.92
In the getAPY function, rewardRate * BLOCKS_PER_YEAR is used to calculate APY, but rewardRate is the reward per second, and BLOCKS_PER_YEAR is the number of blocks in the year, which will result in a lower APY.
None
- uint256 constant BLOCKS_PER_DAY = 6450; - uint256 constant BLOCKS_PER_YEAR = BLOCKS_PER_DAY * 365; + uint256 constant SECONDS_PER_DAY = 86400; + uint256 constant SECONDS_PER_YEAR = SECONDS_PER_DAY * 365; function getAPY() external view returns (uint256) { - return rewardRate.mul(BLOCKS_PER_YEAR).mul(1e18).div(totalSupply()); + return rewardRate.mul(SECONDS_PER_YEAR).mul(1e18).div(totalSupply()); }
#0 - jetbrain10
2022-06-15T16:44:11Z
will remove this function
#1 - GalloDaSballo
2022-07-24T23:50:14Z
Finding is valid, the math is incorrect.
Notice that even the corrected math would not be APY, but APR (technically vAPR as it's based on totalSupply which can change at any moment)
Question is whether this is a valid Medium or QA.
Because the function is never used in the codebase, not even in tests, I'll downgrade to QA.
I may change my mind