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: 98/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
DBR.sol, 172, b' balances[msg.sender] -= amount;' DBR.sol, 174, b' balances[to] += amount;' DBR.sol, 196, b' balances[from] -= amount;' DBR.sol, 198, b' balances[to] += amount;' DBR.sol, 288, b' dueTokensAccrued[user] += accrued;' DBR.sol, 289, b' totalDueTokensAccrued += accrued;' DBR.sol, 304, b' debts[user] += additionalDebt;' DBR.sol, 316, b' debts[user] -= repaidDebt;' DBR.sol, 332, b' debts[user] += replenishmentCost;' DBR.sol, 360, b' _totalSupply += amount;' DBR.sol, 362, b' balances[to] += amount;' DBR.sol, 374, b' balances[from] -= amount;' DBR.sol, 376, b' _totalSupply -= amount;' Fed.sol, 91, b' supplies[market] += amount;' Fed.sol, 92, b' globalSupply += amount;' Fed.sol, 110, b' supplies[market] -= amount;' Fed.sol, 111, b' globalSupply -= amount;' Market.sol, 395, b' debts[borrower] += amount;' Market.sol, 397, b' totalDebt += amount;' Market.sol, 534, b' debts[user] -= amount;' Market.sol, 535, b' totalDebt -= amount;' Market.sol, 565, b' debts[user] += replenishmentCost;' Market.sol, 568, b' totalDebt += replenishmentCost;' Market.sol, 599, b' debts[user] -= repaidDebt;' Market.sol, 600, b' totalDebt -= repaidDebt;'
The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas per loop
BR.sol, 239, b' nonces[owner]++,' DBR.sol, 259, b' nonces[msg.sender]++;' Market.sol, 438, b' nonces[from]++,' Market.sol, 502, b' nonces[from]++,' Market.sol, 521, b' nonces[msg.sender]++;'
DBR.sol, 232, b' abi.encode(' DBR.sol, 269, b' abi.encode(' Market.sol, 104, b' abi.encode(' Market.sol, 431, b' abi.encode(' Market.sol, 495, b' abi.encode('
See this issue(https://github.com/code-423n4/2022-01-xdefi-findings/issues/128) which describes the fact that there is a larger deployment gas cost, but with enough runtime calls, the change ends up being cheaper
DBR.sol, 249, b' require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");' DBR.sol, 350, b' require(minters[msg.sender] == true || msg.sender == operator, "ONLY MINTERS OR OPERATOR");' Market.sol, 75, b' require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps < 10000, "Invalid liquidation incentive");' Market.sol, 162, b' require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor");' Market.sol, 173, b' require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive");' Market.sol, 184, b' require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps + liquidationFeeBps < 10000, "Invalid liquidation incentive");' Market.sol, 195, b' require(_liquidationFeeBps > 0 && _liquidationFeeBps + liquidationIncentiveBps < 10000, "Invalid liquidation fee");' Market.sol, 214, b' require(msg.sender == pauseGuardian || msg.sender == gov, "Only pause guardian or governance can pause");' Market.sol, 448, b' require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER");' Market.sol, 512, b' require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER");'
We can save getter function of public constants.
DBR.sol, 13, b' uint8 public constant decimals = 18;' Fed.sol, 28, b' IDBR public immutable dbr;' Fed.sol, 29, b' IDola public immutable dola;' escrows/INVEscrow.sol, 32, b' IXINV public immutable xINV;' Market.sol, 41, b' address public immutable escrowImplementation;' Market.sol, 42, b' IDolaBorrowingRights public immutable dbr;' Market.sol, 44, b' IERC20 public immutable dola = IERC20(0x865377367054516e17014CcdED1e7d814EDC9ce4);' Market.sol, 45, b' IERC20 public immutable collateral;'
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
DBR.sol, 13, b' uint8 public constant decimals = 18;' DBR.sol, 63, b' require(newReplenishmentPriceBps_ > 0, "replenishment price must be over 0");' DBR.sol, 110, b' if(totalDueTokensAccrued > _totalSupply) return 0;' DBR.sol, 122, b' uint accrued = (block.timestamp - lastUpdated[user]) * debt / 365 days;' DBR.sol, 123, b' if(dueTokensAccrued[user] + accrued > balances[user]) return 0;' DBR.sol, 135, b' uint accrued = (block.timestamp - lastUpdated[user]) * debt / 365 days;' DBR.sol, 136, b' if(dueTokensAccrued[user] + accrued < balances[user]) return 0;' DBR.sol, 148, b' uint accrued = (block.timestamp - lastUpdated[user]) * debt / 365 days;' DBR.sol, 226, b' address recoveredAddress = ecrecover(' DBR.sol, 245, b' v,' DBR.sol, 249, b' require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");' DBR.sol, 271, b' keccak256(bytes(name)),' DBR.sol, 271, b' keccak256(bytes(name)),' DBR.sol, 287, b' uint accrued = (block.timestamp - lastUpdated[user]) * debt / 365 days;' DBR.sol, 303, b' require(deficitOf(user) == 0, "DBR Deficit");' DBR.sol, 328, b' require(deficit > 0, "No deficit");' DBR.sol, 330, b' uint replenishmentCost = amount * replenishmentPriceBps / 10000;' escrows/SimpleERC20Escrow.sol, 26, b' require(market == address(0), "ALREADY INITIALIZED");' escrows/GovTokenEscrow.sol, 31, b' require(market == address(0), "ALREADY INITIALIZED");' Fed.sol, 123, b' if(supply >= marketValue) return 0;' Fed.sol, 133, b' if(profit > 0) {' Oracle.sol, 79, b' if(fixedPrices[token] > 0) return fixedPrices[token];' Oracle.sol, 80, b' if(feeds[token].feed != IChainlinkFeed(address(0))) {' Oracle.sol, 83, b' require(price > 0, "Invalid feed price");' Oracle.sol, 85, b' uint8 feedDecimals = feeds[token].feed.decimals();' Oracle.sol, 85, b' uint8 feedDecimals = feeds[token].feed.decimals();' Oracle.sol, 85, b' uint8 feedDecimals = feeds[token].feed.decimals();' Oracle.sol, 86, b' uint8 tokenDecimals = feeds[token].tokenDecimals;' Oracle.sol, 86, b' uint8 tokenDecimals = feeds[token].tokenDecimals;' Oracle.sol, 87, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 87, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 87, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 87, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 87, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 87, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 89, b' uint day = block.timestamp / 1 days;' Oracle.sol, 95, b' uint newBorrowingPower = normalizedPrice * collateralFactorBps / 10000;' Oracle.sol, 96, b' uint twoDayLow = todaysLow > yesterdaysLow && yesterdaysLow > 0 ? yesterdaysLow : todaysLow;' Oracle.sol, 97, b' if(twoDayLow > 0 && newBorrowingPower > twoDayLow) {' Oracle.sol, 98, b' uint dampenedPrice = twoDayLow * 10000 / collateralFactorBps;' Oracle.sol, 113, b' if(fixedPrices[token] > 0) return fixedPrices[token];' Oracle.sol, 114, b' if(feeds[token].feed != IChainlinkFeed(address(0))) {' Oracle.sol, 117, b' require(price > 0, "Invalid feed price");' Oracle.sol, 119, b' uint8 feedDecimals = feeds[token].feed.decimals();' Oracle.sol, 119, b' uint8 feedDecimals = feeds[token].feed.decimals();' Oracle.sol, 119, b' uint8 feedDecimals = feeds[token].feed.decimals();' Oracle.sol, 120, b' uint8 tokenDecimals = feeds[token].tokenDecimals;' Oracle.sol, 120, b' uint8 tokenDecimals = feeds[token].tokenDecimals;' Oracle.sol, 121, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 121, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 121, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 121, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 121, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 121, b' uint8 decimals = 36 - feedDecimals - tokenDecimals;' Oracle.sol, 124, b' uint day = block.timestamp / 1 days;' Oracle.sol, 126, b' if(todaysLow == 0 || normalizedPrice < todaysLow) {' Oracle.sol, 134, b' uint newBorrowingPower = normalizedPrice * collateralFactorBps / 10000;' Oracle.sol, 135, b' uint twoDayLow = todaysLow > yesterdaysLow && yesterdaysLow > 0 ? yesterdaysLow : todaysLow;' Oracle.sol, 136, b' if(twoDayLow > 0 && newBorrowingPower > twoDayLow) {' Oracle.sol, 137, b' uint dampenedPrice = twoDayLow * 10000 / collateralFactorBps;' escrows/INVEscrow.sol, 45, b' require(market == address(0), "ALREADY INITIALIZED");' escrows/INVEscrow.sol, 72, b' uint invBalanceInXInv = xINV.balanceOf(address(this)) * xINV.exchangeRateStored() / 1 ether;' escrows/INVEscrow.sol, 81, b' if(invBalance > 0) {' Market.sol, 74, b' require(_collateralFactorBps < 10000, "Invalid collateral factor");' Market.sol, 75, b' require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps < 10000, "Invalid liquidation incentive");' Market.sol, 75, b' require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps < 10000, "Invalid liquidation incentive");' Market.sol, 76, b' require(_replenishmentIncentiveBps < 10000, "Replenishment incentive must be less than 100%");' Market.sol, 106, b' keccak256(bytes("DBR MARKET")),' Market.sol, 150, b' require(_collateralFactorBps < 10000, "Invalid collateral factor");' Market.sol, 162, b' require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor");' Market.sol, 162, b' require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor");' Market.sol, 173, b' require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive");' Market.sol, 173, b' require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive");' Market.sol, 184, b' require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps + liquidationFeeBps < 10000, "Invalid liquidation incentive");' Market.sol, 184, b' require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps + liquidationFeeBps < 10000, "Invalid liquidation incentive");' Market.sol, 195, b' require(_liquidationFeeBps > 0 && _liquidationFeeBps + liquidationIncentiveBps < 10000, "Invalid liquidation fee");' Market.sol, 195, b' require(_liquidationFeeBps > 0 && _liquidationFeeBps + liquidationIncentiveBps < 10000, "Invalid liquidation fee");' Market.sol, 236, b' require(instance != IEscrow(address(0)), "ERC1167: create2 failed");' Market.sol, 246, b' if(escrows[user] != IEscrow(address(0))) return escrows[user];' Market.sol, 315, b' return collateralBalance * oracle.viewPrice(address(collateral), collateralFactorBps) / 1 ether;' Market.sol, 326, b' return collateralBalance * oracle.getPrice(address(collateral), collateralFactorBps) / 1 ether;' Market.sol, 336, b' return collateralValue * collateralFactorBps / 10000;' Market.sol, 346, b' return collateralValue * collateralFactorBps / 10000;' Market.sol, 356, b' if(collateralBalance == 0) return 0;' Market.sol, 356, b' if(collateralBalance == 0) return 0;' Market.sol, 358, b' if(debt == 0) return collateralBalance;' Market.sol, 359, b' if(collateralFactorBps == 0) return 0;' Market.sol, 359, b' if(collateralFactorBps == 0) return 0;' Market.sol, 360, b' uint minimumCollateral = debt * 1 ether / oracle.getPrice(address(collateral), collateralFactorBps) * 10000 / collateralFactorBps;' Market.sol, 360, b' uint minimumCollateral = debt * 1 ether / oracle.getPrice(address(collateral), collateralFactorBps) * 10000 / collateralFactorBps;' Market.sol, 361, b' if(collateralBalance <= minimumCollateral) return 0;' Market.sol, 373, b' if(collateralBalance == 0) return 0;' Market.sol, 373, b' if(collateralBalance == 0) return 0;' Market.sol, 375, b' if(debt == 0) return collateralBalance;' Market.sol, 376, b' if(collateralFactorBps == 0) return 0;' Market.sol, 376, b' if(collateralFactorBps == 0) return 0;' Market.sol, 377, b' uint minimumCollateral = debt * 1 ether / oracle.viewPrice(address(collateral), collateralFactorBps) * 10000 / collateralFactorBps;' Market.sol, 377, b' uint minimumCollateral = debt * 1 ether / oracle.viewPrice(address(collateral), collateralFactorBps) * 10000 / collateralFactorBps;' Market.sol, 378, b' if(collateralBalance <= minimumCollateral) return 0;' Market.sol, 391, b' if(borrowController != IBorrowController(address(0))) {' Market.sol, 425, b' address recoveredAddress = ecrecover(' Market.sol, 444, b' v,' Market.sol, 448, b' require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER");' Market.sol, 489, b' address recoveredAddress = ecrecover(' Market.sol, 508, b' v,' Market.sol, 512, b' require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER");' Market.sol, 561, b' require(deficit > 0, "No DBR deficit");' Market.sol, 563, b' uint replenishmentCost = amount * dbr.replenishmentPriceBps() / 10000;' Market.sol, 564, b' uint replenisherReward = replenishmentCost * replenishmentIncentiveBps / 10000;' Market.sol, 580, b' if (debt == 0) return 0;' Market.sol, 580, b' if (debt == 0) return 0;' Market.sol, 582, b' if(credit >= debt) return 0;' Market.sol, 583, b' return debt * liquidationFactorBps / 10000;' Market.sol, 592, b' require(repaidDebt > 0, "Must repay positive debt");' Market.sol, 595, b' require(repaidDebt <= debt * liquidationFactorBps / 10000, "Exceeded liquidation factor");' Market.sol, 597, b' uint liquidatorReward = repaidDebt * 1 ether / price;' Market.sol, 605, b' if(liquidationFeeBps > 0) {' Market.sol, 606, b' uint liquidationFee = repaidDebt * 1 ether / price * liquidationFeeBps / 10000;' Market.sol, 606, b' uint liquidationFee = repaidDebt * 1 ether / price * liquidationFeeBps / 10000;'
#0 - c4-judge
2022-11-05T23:39:51Z
0xean marked the issue as grade-b