Platform: Code4rena
Start Date: 25/10/2022
Pot Size: $50,000 USDC
Total HM: 18
Participants: 127
Period: 5 days
Judge: 0xean
Total Solo HM: 9
Id: 175
League: ETH
Rank: 110/127
Findings: 1
Award: $19.01
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: pfapostol
Also found by: 0x1f8b, 0xRoxas, 0xSmartContract, Amithuddar, Aymen0909, B2, Bnke0x0, Chandr, CloudX, Deivitto, Diana, Dinesh11G, ElKu, HardlyCodeMan, JC, JrNet, KoKo, Mathieu, Ozy42, Rahoz, RaymondFam, ReyAdmirado, Rolezn, Shinchan, __141345__, adriro, ajtra, aphak5010, ballx, c3phas, carlitox477, ch0bu, chaduke, cryptostellar5, djxploit, durianSausage, enckrish, exolorkistis, fatherOfBlocks, gogo, horsefacts, kaden, karanctf, leosathya, martin, mcwildy, oyc_109, ret2basic, robee, sakman, sakshamguruji, shark, skyle, tnevler
19.0072 USDC - $19.01
Public function used on function like transfer, transferFrom, _burn (state change functions)
uint256 debt = debts[user]; //... uint256 accrued = ((block.timestamp - lastUpdated[user]) * debt) / 365 days;
after:
uint256 accrued = ((block.timestamp - lastUpdated[user]) * debts[user]) / 365 days;
if (dueTokensAccrued[user] + accrued > balances[user]) return 0; return balances[user] - dueTokensAccrued[user] - accrued;
after:
uint256 duTokensAccruedUser = dueTokensAccrued[user]; uint256 balanceUser = balances[user]; if (duTokensAccruedUser + accrued > balanceUser) return 0; return balanceUser - duTokensAccruedUser - accrued;
Public function used on function like onBorrow, onForceReplenish... (state change functions)
Public view function, not used in other functions, so not really important.
if (totalDueTokensAccrued > _totalSupply) return 0; return _totalSupply - totalDueTokensAccrued;
after:
uint256 totalSupply_ = _totalSupply; uint256 totalDueTokensAccrued_ = totalDueTokensAccrued; if (totalDueTokensAccrued_ > totalSupply_) return 0; return totalSupply_ - totalDueTokensAccrued_;
Public function used on function like onBorrow, onRepay, onForceReplenish (state change functions)
uint256 debt = debts[user]; if (lastUpdated[user] == block.timestamp) return; uint256 accrued = ((block.timestamp - lastUpdated[user]) * debt) / 365 days;
after:
uint256 lastUpdatedUser = lastUpdated[user]; if (lastUpdatedUser == block.timestamp) return; uint256 accrued = ((block.timestamp - lastUpdatedUser) * debt) / 365 days;
Public function
uint256 supply = supplies[market]; require(amount <= supply, "AMOUNT TOO BIG");
after:
require(amount <= supplies[market], "AMOUNT TOO BIG");
require( _liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor" );
after:
require(_liquidationFactorBps > 0, "Invalid liquidation factor"); require(_liquidationFactorBps <= 10000, "Invalid liquidation factor");
address deployer = address(this); assembly { //... mstore(add(ptr, 0x38), shl(0x60, deployer)) }
after:
assembly { //... mstore(add(ptr, 0x38), shl(0x60, address())) }
Public function used on function like getCreditLimit, getLiquidatableDebt (view functions)
IEscrow escrow = predictEscrow(user); uint256 collateralBalance = escrow.balance(); return (collateralBalance * oracle.viewPrice(address(collateral), collateralFactorBps)) / 1 ether;
after:
return (IEscrow(predictEscrow(user)).balance() * oracle.viewPrice(address(collateral), collateralFactorBps)) / 1 ether;
Internal function used on function like getCreditLimitInternal, forceReplenish (state change functions)
Public function used on function like getLiquidatableDebt (view functions)
uint256 collateralValue = getCollateralValue(user); return (collateralValue * collateralFactorBps) / 10000;
after:
return (getCollateralValue(user) * collateralFactorBps) / 10000;
Internal function used on function like borrowInternal, liquidate (state change functions)
Internal function used on function like withdrawInternal, withdraw (state change functions)
IEscrow escrow = predictEscrow(user); uint256 collateralBalance = escrow.balance();
after:
uint256 collateralBalance = IEscrow(predictEscrow(user)).balance();
if (collateralFactorBps == 0) return 0; uint256 minimumCollateral = (((debt * 1 ether) / oracle.getPrice(address(collateral), collateralFactorBps)) * 10000) / collateralFactorBps;
after:
uint256 _collateralFactorBps = collateralFactorBps; if (_collateralFactorBps == 0) return 0; uint256 minimumCollateral = (((debt * 1 ether) / oracle.getPrice(address(collateral), _collateralFactorBps)) * 10000) / _collateralFactorBps;
Internal function used on function like borrow, borrowOnBehalf (state change functions)
uint256 credit = getCreditLimitInternal(borrower); debts[borrower] += amount; require( credit >= debts[borrower], "Exceeded credit limit" );
after:
debts[borrower] += amount; require( getCreditLimitInternal(borrower) >= debts[borrower], "Exceeded credit limit" );
Internal function used on function like withdraw (state change functions)
uint256 limit = getWithdrawalLimitInternal(from); require( limit >= amount, "Insufficient withdrawal limit" ); IEscrow escrow = getEscrow(from); escrow.pay(to, amount);
after:
require( getWithdrawalLimitInternal(from) >= amount, "Insufficient withdrawal limit" ); IEscrow(getEscrow(from)).pay(to, amount);
Public function used on function like repayAndWithdraw (state change functions)
uint256 debt = debts[user]; require(debt >= amount, "Insufficient debt");
after:
require(debts[user] >= amount, "Insufficient debt");
Public function (state change functions)
uint256 collateralValue = getCollateralValueInternal(user); require( collateralValue >= debts[user], "Exceeded collateral value" );
after:
require( getCollateralValueInternal(user) >= debts[user], "Exceeded collateral value" );
Public view function
uint256 credit = getCreditLimit(user); if (credit >= debt) return 0;
after:
if (getCreditLimit(user) >= debt) return 0;
Public function (state change function)
if(feeds[token].feed != IChainlinkFeed(address(0))) { // get price from feed uint price = feeds[token].feed.latestAnswer(); require(price > 0, "Invalid feed price"); // normalize price uint8 feedDecimals = feeds[token].feed.decimals(); uint8 tokenDecimals = feeds[token].tokenDecimals;
after:
FeedData memory feedData = feeds[token]; if (feedData.feed != IChainlinkFeed(address(0))) { // get price from feed uint256 price = feedData.feed.latestAnswer(); require(price > 0, "Invalid feed price"); // normalize price uint8 feedDecimals = feedData.feed.decimals(); uint8 tokenDecimals = feedData.tokenDecimals;
if(feeds[token].feed != IChainlinkFeed(address(0))) { // get price from feed uint price = feeds[token].feed.latestAnswer(); require(price > 0, "Invalid feed price"); // normalize price uint8 feedDecimals = feeds[token].feed.decimals(); uint8 tokenDecimals = feeds[token].tokenDecimals; uint8 decimals = 36 - feedDecimals - tokenDecimals; uint normalizedPrice = price * (10 ** decimals);
after:
FeedData memory feedData = feeds[token]; if (feedData.feed != IChainlinkFeed(address(0))) { // get price from feed uint256 price = feedData.feed.latestAnswer(); require(price > 0, "Invalid feed price"); // normalize price uint256 normalizedPrice = price * (10**(36 - feedData.feed.decimals() - feedData.tokenDecimals));
#0 - c4-judge
2022-11-05T23:41:32Z
0xean marked the issue as grade-b