Platform: Code4rena
Start Date: 28/09/2023
Pot Size: $36,500 USDC
Total HM: 5
Participants: 115
Period: 6 days
Judge: 0xDjango
Total Solo HM: 1
Id: 290
League: ETH
Rank: 96/115
Findings: 1
Award: $4.37
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Bauchibred
Also found by: 0x3b, 0xDetermination, 0xMosh, 0xScourgedev, 0xTheC0der, 0xTiwa, 0xWaitress, 0xdice91, 0xfusion, 0xpiken, 0xprinc, 0xweb3boy, ArmedGoose, Aymen0909, Breeje, Brenzee, Daniel526, DavidGiladi, DeFiHackLabs, Flora, Fulum, HChang26, Hama, IceBear, J4X, Krace, KrisApostolov, Maroutis, Mirror, MohammedRizwan, Norah, PwnStars, SPYBOY, TangYuanShen, Testerbot, ThreeSigma, Tricko, al88nsk, alexweb3, ast3ros, berlin-101, bin2chen, blutorque, btk, d3e4, deth, e0d1n, ether_sky, ge6a, gkrastenov, glcanvas, hals, imare, inzinko, jkoppel, jnforja, joaovwfreire, josephdara, kutugu, lotux, lsaudit, mahdirostami, merlin, n1punp, nadin, neumo, nisedo, nobody2018, oakcobalt, orion, peanuts, pep7siup, pina, ptsanev, rokinot, rvierdiiev, said, santipu_, sashik_eth, seerether, squeaky_cactus, terrancrypt, tonisives, twicek, vagrant, xAriextz, y4y
4.3669 USDC - $4.37
Total Low Risk Issues | 3 |
---|
Count | Title | Instances |
---|---|---|
L-01 | The accrueTokens can be abused to reduce the cumulative number of tokens | 1 |
L-02 | Dos in accrueTokens if owner wrongly sweepToken | 1 |
L-03 | Underflow in _calculateScore | 1 |
Total Non-Critical Issues | 1 |
---|
Count | Title | Instances |
---|---|---|
NC-01 | Functions should be a modifier | 2 |
accrueTokens
is used to accumulate the amount of tokens across the block, and it is a public function that could be invoked by anyone.
However, if the balance of this
is less than the accumulated value of the token during the period, the token can only obtain the difference between this
balance and the previously accumulated value. Therefore, a malicious attacker can call this function before the contract has sufficient balance, preventing the token from obtaining the expected accumulated value.
uint256 balanceDiff = balance - tokenAmountAccrued[token_]; if (distributionSpeed > 0 && balanceDiff > 0) { uint256 accruedSinceUpdate = deltaBlocks * distributionSpeed; uint256 tokenAccrued = (balanceDiff <= accruedSinceUpdate ? balanceDiff : accruedSinceUpdate);
Function sweepToken
allows the owner to sweep any tokens from this contract, including the initialzed tokens.
function sweepToken(IERC20Upgradeable token_, address to_, uint256 amount_) external onlyOwner { uint256 balance = token_.balanceOf(address(this)); if (amount_ > balance) { revert InsufficientBalance(amount_, balance); } emit SweepToken(address(token_), to_, amount_); token_.safeTransfer(to_, amount_); }
If the owner accidentally sweeps some of the accumulated tokens, the accrueToken
function might encounter an underflow when calculating the accumulated tokens because the balance at that moment may not be sufficient to cover the originally accumulated tokens. This could lead to temporary denial of service.
uint256 distributionSpeed = tokenDistributionSpeeds[token_]; uint256 balance = IERC20Upgradeable(token_).balanceOf(address(this)); //@audit If balance of this is less than the tokenAmountAccrued due to `sweepToken`, underflow occurs uint256 balanceDiff = balance - tokenAmountAccrued[token_];
_calculateScore
If the decimal of vToken
is larger than 18, then _calculateScore
will always underflow.
function _calculateScore(address market, address user) internal returns (uint256) { uint256 xvsBalanceForScore = _xvsBalanceForScore(_xvsBalanceOfUser(user)); IVToken vToken = IVToken(market); uint256 borrow = vToken.borrowBalanceStored(user); uint256 exchangeRate = vToken.exchangeRateStored(); uint256 balanceOfAccount = vToken.balanceOf(user); uint256 supply = (exchangeRate * balanceOfAccount) / EXP_SCALE; address xvsToken = IXVSVault(xvsVault).xvsAddress(); oracle.updateAssetPrice(xvsToken); oracle.updatePrice(market); (uint256 capital, , ) = _capitalForScore(xvsBalanceForScore, borrow, supply, market); //@audit if vTOken.decimals() is less than 18, underflow occurs capital = capital * (10 ** (18 - vToken.decimals())); return Scores.calculateScore(xvsBalanceForScore, capital, alphaNumerator, alphaDenominator); }
These two functions should be changed to a modifier.
function _ensureTokenInitialized(address token_) internal view { uint256 lastBlockAccrued = lastAccruedBlock[token_]; if (lastBlockAccrued == 0) { revert TokenNotInitialized(token_); } }
function _ensureZeroAddress(address address_) internal pure { if (address_ == address(0)) { revert InvalidArguments(); } }
#0 - 0xRobocop
2023-10-07T03:12:42Z
L-02 Dup of #42
#1 - c4-pre-sort
2023-10-07T03:13:02Z
0xRobocop marked the issue as low quality report
#2 - c4-judge
2023-11-03T02:10:54Z
fatherGoose1 marked the issue as grade-b