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: 104/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
Breaking apart require and if statements saves gas.
/src/Oracle.sol Line(s): 97, 136
97: if(twoDayLow > 0 && newBorrowingPower > twoDayLow) { 136: if(twoDayLow > 0 && newBorrowingPower > twoDayLow) {
Breaking apart require and if statements saves gas.
/src/Market.sol Line(s): 75, 162, 173, 184, 195, 448, 512
75: require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps < 10000, "Invalid liquidation incentive"); 162: require(_liquidationFactorBps > 0 && _liquidationFactorBps <= 10000, "Invalid liquidation factor"); 173: require(_replenishmentIncentiveBps > 0 && _replenishmentIncentiveBps < 10000, "Invalid replenishment incentive"); 184: require(_liquidationIncentiveBps > 0 && _liquidationIncentiveBps + liquidationFeeBps < 10000, "Invalid liquidation incentive"); 195: require(_liquidationFeeBps > 0 && _liquidationFeeBps + liquidationIncentiveBps < 10000, "Invalid liquidation fee"); 448: require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER"); 512: require(recoveredAddress != address(0) && recoveredAddress == from, "INVALID_SIGNER");
Same as bool's uint8 data causes uneeded overhead.
/src/Oracle.sol Line(s): 20, 85, 86, 87, 119, 120, 121
20: uint8 tokenDecimals; 85: uint8 feedDecimals = feeds[token].feed.decimals(); 86: uint8 tokenDecimals = feeds[token].tokenDecimals; 87: uint8 decimals = 36 - feedDecimals - tokenDecimals; 119: uint8 feedDecimals = feeds[token].feed.decimals(); 120: uint8 tokenDecimals = feeds[token].tokenDecimals; 121: uint8 decimals = 36 - feedDecimals - tokenDecimals;
/src/Market.sol Line(s): 422, 486
422: function borrowOnBehalf(address from, uint amount, uint deadline, uint8 v, bytes32 r, bytes32 s) public { 486: function withdrawOnBehalf(address from, uint amount, uint deadline, uint8 v, bytes32 r, bytes32 s) public {
13: uint8 public constant decimals = 18; 220: uint8 v,
immutable
variables never initialized in the constructor can be made constant
to save gasdola
is made immutable
even though it is never set in the constructor and is always the same value. Consider changing dola
to a constant
data type to save gas.
src/market.sol Line(s): 44
44: IERC20 public immutable dola = IERC20(0x865377367054516e17014CcdED1e7d814EDC9ce4);
Suggested change:
44: IERC20 public constant dola = IERC20(0x865377367054516e17014CcdED1e7d814EDC9ce4);
unchecked
when arithmetic cannot overflow saves gasThere are mutliple occurances where arithmetic is performed that cannot overflow / underflow based on a previous require. Adding an unchecked
brace around these occurances will save gas (Solidity will not force an underflow / overflow).
NOTE: Findings show the check before each line that allows the second line to be unchecked
. Only the line following the check should be unchecked (NOT the check itself).
unchecked { //Code }
src/Market.sol Line(s): 261-362, 378-379, 533-534
361: if(collateralBalance <= minimumCollateral) return 0; 362: return collateralBalance - minimumCollateral;
378: if(collateralBalance <= minimumCollateral) return 0; 379: return collateralBalance - minimumCollateral;
533: require(debt >= amount, "Insufficient debt"); 534: debts[user] -= amount;
src/Fed.sol Line(s): 123-124
123: if(supply >= marketValue) return 0; 124: return marketValue - supply;
src/DBR.sol Line(s): 110-111, 123-124, 136-137
110: if(totalDueTokensAccrued > _totalSupply) return 0; 111: return _totalSupply - totalDueTokensAccrued;
123: if(dueTokensAccrued[user] + accrued > balances[user]) return 0; 124: return balances[user] - dueTokensAccrued[user] - accrued;
136: if(dueTokensAccrued[user] + accrued < balances[user]) return 0; 137: return dueTokensAccrued[user] + accrued - balances[user];
#0 - c4-judge
2022-11-05T23:50:13Z
0xean marked the issue as grade-b