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: 112/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
Description: if (var == true) => if (var)
./src/DBR.sol
L350: require(minters[msg.sender] == true || msg.sender == operator, "ONLY MINTERS OR OPERATOR");
Description: Currently storage variables in Market.sol are packed in 15 slots, but could fit in 14
./src/DBR.sol
L171: require(balanceOf(msg.sender) >= amount, "Insufficient balance"); L224: require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); L329: require(deficit >= amount, "Amount > deficit"); L373: require(balanceOf(from) >= amount, "Insufficient balance");
./src/Market.sol
L162: require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor"); L361: if(collateralBalance <= minimumCollateral) return 0; L396: require(credit >= debts[borrower], "Exceeded credit limit"); L423: require(deadline >= block.timestamp, "DEADLINE_EXPIRED"); L462: require(limit >= amount, "Insufficient withdrawal limit"); L487: require(deadline >= block.timestamp, "DEADLINE_EXPIRED"); L562: require(deficit >= amount, "Amount > deficit"); L582: if(credit >= debt) return 0; L607: if(escrow.balance() >= liquidationFee) {
./src/Fed.sol
L93: require(globalSupply <= supplyCeiling); L107: require(amount <= supply, "AMOUNT TOO BIG"); L123: if(supply >= marketValue) return 0;
./src/DBR.sol
L63: require(newReplenishmentPriceBps_ > 0, "replenishment price must be over 0"); L326: require(markets[msg.sender], "Only markets can call onForceReplenish");
./src/Market.sol
L76: require(_replenishmentIncentiveBps < 10000, "Replenishment incentive must be less than 100%"); L214: require(msg.sender == pauseGuardian || msg.sender == gov, "Only pause guardian or governance can pause");
!= 0
comparison is cheaper than > 0
./src/Market.sol
L162: require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor"); L173: require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive"); L195: require(_liquidationFeeBps > 0 && _liquidationFeeBps + liquidationIncentiveBps < 10000, "Invalid liquidation fee"); L561: require(deficit > 0, "No DBR deficit"); L592: require(repaidDebt > 0, "Must repay positive debt");
./src/Fed.sol
L133: if(profit > 0) {
./src/Oracle.sol
L83: require(price > 0, "Invalid feed price"); L97: if(twoDayLow > 0 && newBorrowingPower > twoDayLow) { L117: require(price > 0, "Invalid feed price"); L135: uint twoDayLow = todaysLow > yesterdaysLow && yesterdaysLow > 0 ? yesterdaysLow : todaysLow; L136: if(twoDayLow > 0 && newBorrowingPower > twoDayLow) {
./src/escrows/INVEscrow.sol
L81: if(invBalance > 0) {
./src/DBR.sol
L63: require(newReplenishmentPriceBps_ > 0, "replenishment price must be over 0"); L328: require(deficit > 0, "No deficit");
uint265
for boolean values (e.g. true => 1 and false => 2)./src/Market.sol
L52: bool immutable callOnDepositCallback; L53: bool public borrowPaused;
./src/Market.sol
L560: uint deficit = dbr.deficitOf(user); L563: uint replenishmentCost = amount * dbr.replenishmentPriceBps() / 10000; L569: dbr.onForceReplenish(user, amount);
./src/Oracle.sol
L82: uint price = feeds[token].feed.latestAnswer(); L85: uint8 feedDecimals = feeds[token].feed.decimals(); L86: uint8 tokenDecimals = feeds[token].tokenDecimals; L116: uint price = feeds[token].feed.latestAnswer(); L119: uint8 feedDecimals = feeds[token].feed.decimals(); L120: uint8 tokenDecimals = feeds[token].tokenDecimals;
payable
to save gasDescription: Under the hood the compiler checks if a function is payable. The check is skipped if it is marked as such by the developer
./src/escrows/INVEscrow.sol
L59: function pay(address recipient, uint amount) public { L90: function delegate(address delegatee) public {
./src/Oracle.sol
L66: function claimOperator() public {
./src/escrows/SimpleERC20Escrow.sol
L36: function pay(address recipient, uint amount) public {
./src/Market.sol
L203: function recall(uint amount) public { L212: function pauseBorrows(bool _value) public {
./src/escrows/GovTokenEscrow.sol
L43: function pay(address recipient, uint amount) public { L66: function delegate(address delegatee) public {
./src/Fed.sol
L48: function changeGov(address _gov) public { L66: function changeChair(address _chair) public { L75: function resign() public { L86: function expansion(IMarket market, uint amount) public { L103: function contraction(IMarket market, uint amount) public {
./src/DBR.sol
L70: function claimOperator() public {
require()
conditions to multiple require()
statements to save gas from &&
./src/DBR.sol
L249: require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
./src/Market.sol
L75: require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps < 10000, "Invalid liquidation incentive"); L162: require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor"); L173: require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive"); L448: require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER"); L512: require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER");
./src/escrows/SimpleERC20Escrow.sol
L26: require(market == address(0), "ALREADY INITIALIZED"); L37: require(msg.sender == market, "ONLY MARKET");
./src/Market.sol
L74: require(_collateralFactorBps < 10000, "Invalid collateral factor"); L75: require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps < 10000, "Invalid liquidation incentive"); L76: require(_replenishmentIncentiveBps < 10000, "Replenishment incentive must be less than 100%"); L93: require(msg.sender == gov, "Only gov can call this function"); L150: require(_collateralFactorBps < 10000, "Invalid collateral factor"); L162: require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor"); L173: require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive"); L204: require(msg.sender == lender, "Only lender can recall"); L214: require(msg.sender == pauseGuardian || msg.sender == gov, "Only pause guardian or governance can pause"); L236: require(instance != IEscrow(address(0)), "ERC1167: create2 failed"); L390: require(!borrowPaused, "Borrowing is paused"); L396: require(credit >= debts[borrower], "Exceeded credit limit"); L487: require(deadline >= block.timestamp, "DEADLINE_EXPIRED"); L512: require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER"); L533: require(debt >= amount, "Insufficient debt"); L561: require(deficit > 0, "No DBR deficit"); L562: require(deficit >= amount, "Amount > deficit"); L594: require(getCreditLimitInternal(user) < debt, "User debt is healthy"); L595: require(repaidDebt <= debt * liquidationFactorBps / 10000, "Exceeded liquidation factor");
./src/BorrowController.sol
L18: require(msg.sender == operator, "Only operator");
./src/escrows/GovTokenEscrow.sol
L31: require(market == address(0), "ALREADY INITIALIZED"); L44: require(msg.sender == market, "ONLY MARKET");
./src/escrows/INVEscrow.sol
L45: require(market == address(0), "ALREADY INITIALIZED"); L60: require(msg.sender == market, "ONLY MARKET");
./src/Fed.sol
L58: require(msg.sender == gov, "ONLY GOV"); L67: require(msg.sender == gov, "ONLY GOV"); L76: require(msg.sender == chair, "ONLY CHAIR"); L87: require(msg.sender == chair, "ONLY CHAIR"); L88: require(dbr.markets(address(market)), "UNSUPPORTED MARKET"); L89: require(market.borrowPaused() != true, "CANNOT EXPAND PAUSED MARKETS"); L107: require(amount <= supply, "AMOUNT TOO BIG");
./src/Oracle.sol
L36: require(msg.sender == operator, "ONLY OPERATOR"); L83: require(price > 0, "Invalid feed price"); L104: revert("Price not found"); L117: require(price > 0, "Invalid feed price"); L143: revert("Price not found");
./src/DBR.sol
L63: require(newReplenishmentPriceBps_ > 0, "replenishment price must be over 0"); L71: require(msg.sender == pendingOperator, "ONLY PENDING OPERATOR"); L171: require(balanceOf(msg.sender) >= amount, "Insufficient balance"); L195: require(balanceOf(from) >= amount, "Insufficient balance"); L249: require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); L301: require(markets[msg.sender], "Only markets can call onBorrow"); L303: require(deficitOf(user) == 0, "DBR Deficit"); L314: require(markets[msg.sender], "Only markets can call onRepay"); L328: require(deficit > 0, "No deficit"); L329: require(deficit >= amount, "Amount > deficit"); L373: require(balanceOf(from) >= amount, "Insufficient balance");
./src/Market.sol
L397: totalDebt += amount; L535: totalDebt -= amount; L600: totalDebt -= repaidDebt; L395: debts[borrower] += amount; L534: debts[user] -= amount; L599: debts[user] -= repaidDebt;
./src/Fed.sol
L92: globalSupply += amount; L111: globalSupply -= amount; L110: supplies[market] -= amount;
./src/DBR.sol
L360: _totalSupply += amount; L376: _totalSupply -= amount; L289: totalDueTokensAccrued += accrued; L172: balances[msg.sender] -= amount; L198: balances[to] += amount; L374: balances[from] -= amount; L304: debts[user] += additionalDebt; L316: debts[user] -= repaidDebt; L288: dueTokensAccrued[user] += accrued;
#0 - c4-judge
2022-11-05T23:51:52Z
0xean marked the issue as grade-b