bunker.finance contest - IllIllI's results

The easiest way to borrow against your NFTs.

General Information

Platform: Code4rena

Start Date: 03/05/2022

Pot Size: $50,000 USDC

Total HM: 4

Participants: 46

Period: 5 days

Judge: gzeon

Total Solo HM: 2

Id: 117

League: ETH

bunker.finance

Findings Distribution

Researcher Performance

Rank: 5/46

Findings: 3

Award: $1,029.73

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: cccz

Also found by: 0x1f8b, 0xNazgul, GimelSec, IllIllI, Ruhum, hake, kebabsec, oyc_109, sorrynotsorry, throttle, tintin

Labels

bug
duplicate
2 (Med Risk)

Awards

298.5767 USDC - $298.58

External Links

Judge has assessed an item in Issue #26 as Medium risk. The relevant finding follows:

#0 - gzeoneth

2022-05-29T14:05:03Z

Duplicate of #1

Awards

543.0279 USDC - $543.03

Labels

bug
QA (Quality Assurance)

External Links

Low Risk Issues

1. latestAnswer() is deprecated

Use latestRoundData() instead so that you can tell whether the answer is stale or not. The function returns zero if it is unable to fetch data, which may be the case if ChainLink stops supporting this API. The API and its deprecation message no longer even appear on the ChainLink website.

File: /contracts/PriceOracleImplementation.sol   #1

29           int256 usdcPrice = ChainlinkFeed(0x986b5E1e1755e3C2440e960477f25201B0a8bbD4).latestAnswer();

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L29

2. Missing checks for address(0x0) when assigning values to address state variables

File: /contracts/Oracles/CNftPriceOracle.sol   #1

48           admin = _admin;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L48

File: /contracts/Oracles/CNftPriceOracle.sol   #2

50           uniswapV2Factory = _uniswapV2Factory;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L50

File: /contracts/Oracles/CNftPriceOracle.sol   #3

51           baseToken = _baseToken;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L51

File: /contracts/Oracles/CNftPriceOracle.sol   #4

55           admin = newAdmin;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L55

File: /contracts/PriceOracleImplementation.sol   #5

13           cEtherAddress = _cEtherAddress;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L13

3. Upgradeable contract is missing a __gap[50] storage variable to allow for new storage variables in later versions

See this link for a description of this storage variable. While some contracts may not currently be sub-classed, adding the variable now protects against forgetting to add it in the future.

File: /contracts/CNft.sol   #1

16   contract CNft is CNftInterface, ERC1155Enumerable, IERC1155Receiver, IERC721Receiver, ReentrancyGuardUpgradeable, OwnableUpgradeable {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L16

4. require() should be used instead of assert()

Prior to solidity version 0.8.0, hitting an assert() consumes the remainder of the transaction's available gas rather than returning it, as require()/revert() do

File: /contracts/Comptroller.sol   #1

207           assert(assetIndex < len);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L207

File: /contracts/Comptroller.sol   #2

333               assert(markets[cToken].accountMembership[borrower]);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L333

Non-critical Issues

1. override function arguments that are unused should have the variable name removed or commented out to avoid compiler warnings

File: /contracts/CNft.sol   #1

215           address from,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L215

File: /contracts/CNft.sol   #2

216           uint256 tokenId,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L216

File: /contracts/CNft.sol   #3

217           bytes calldata data

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L217

File: /contracts/CNft.sol   #4

224           address from,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L224

File: /contracts/CNft.sol   #5

225           uint256 id,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L225

File: /contracts/CNft.sol   #6

226           uint256 value,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L226

File: /contracts/CNft.sol   #7

227           bytes calldata data

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L227

File: /contracts/CNft.sol   #8

234           address from,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L234

File: /contracts/CNft.sol   #9

235           uint256[] calldata ids,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L235

File: /contracts/CNft.sol   #10

236           uint256[] calldata values,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L236

File: /contracts/CNft.sol   #11

237           bytes calldata data

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L237

2. require()/revert() statements should have descriptive reason strings

File: /contracts/CEther.sol   #1

148           require(err == MathError.NO_ERROR);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L148

3. public functions not called by the contract should be declared external instead

Contracts are allowed to override their parents' functions and change the visibility from external to public.

File: /contracts/Comptroller.sol   #1

115       function enterMarkets(address[] memory cTokens) public returns (uint[] memory) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L115

File: /contracts/Comptroller.sol   #2

533       function getAccountLiquidity(address account) public view returns (uint, uint, uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L533

File: /contracts/Comptroller.sol   #3

559       function getHypotheticalAccountLiquidity(
560           address account,
561           address cAssetModify,
562           uint redeemTokens,
563           uint borrowAmount) public view returns (uint, uint, uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L559-L563

File: /contracts/Comptroller.sol   #4

741       function _setPriceOracle(PriceOracle newOracle) public returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L741

File: /contracts/Comptroller.sol   #5

764       function _setNftPriceOracle(NftPriceOracle newOracle) public returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L764

File: /contracts/Comptroller.sol   #6

977       function _setPauseGuardian(address newPauseGuardian) public returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L977

File: /contracts/Comptroller.sol   #7

994       function _setMintPaused(address cAsset, bool state) public returns (bool) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L994

File: /contracts/Comptroller.sol   #8

1008       function _setBorrowPaused(CToken cToken, bool state) public returns (bool) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1008

File: /contracts/Comptroller.sol   #9

1018       function _setTransferPaused(bool state) public returns (bool) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1018

File: /contracts/Comptroller.sol   #10

1027       function _setSeizePaused(bool state) public returns (bool) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1027

File: /contracts/Comptroller.sol   #11

1036       function _become(Unitroller unitroller) public {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1036

File: /contracts/Comptroller.sol   #12

1270       function _grantComp(address recipient, uint amount) public {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1270

File: /contracts/Comptroller.sol   #13

1282       function _setCompSpeed(CToken cToken, uint compSpeed) public {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1282

File: /contracts/Comptroller.sol   #14

1292       function _setContributorCompSpeed(address contributor, uint compSpeed) public {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1292

File: /contracts/Comptroller.sol   #15

1313       function getAllMarkets() public view returns (CToken[] memory) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1313

File: /contracts/CToken.sol   #16

1452       function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1452

4. constants should be defined rather than using magic numbers

File: /contracts/CEther.sol   #1

175           bytes memory fullMessage = new bytes(bytes(message).length + 5);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L175

File: /contracts/CEther.sol   #2

182           fullMessage[i+0] = byte(uint8(32));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L182

File: /contracts/CEther.sol   #3

183           fullMessage[i+1] = byte(uint8(40));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L183

File: /contracts/CEther.sol   #4

184           fullMessage[i+2] = byte(uint8(48 + ( errCode / 10 )));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L184

File: /contracts/CEther.sol   #5

185           fullMessage[i+3] = byte(uint8(48 + ( errCode % 10 )));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L185

File: /contracts/CEther.sol   #6

185           fullMessage[i+3] = byte(uint8(48 + ( errCode % 10 )));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L185

File: /contracts/CEther.sol   #7

186           fullMessage[i+4] = byte(uint8(41));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L186

File: /contracts/CEther.sol   #8

186           fullMessage[i+4] = byte(uint8(41));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L186

File: /contracts/Comptroller.sol   #9

1326               cToken.reserveFactorMantissa() == 1e18

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1326

File: /contracts/Oracles/CNftPriceOracle.sol   #10

99           return FullMath.mulDiv(pricePerToken, 10**18 - mintFee, 10**18);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L99

File: /contracts/Oracles/CNftPriceOracle.sol   #11

99           return FullMath.mulDiv(pricePerToken, 10**18 - mintFee, 10**18);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L99

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #12

64               uint32 timeElapsed = uint32(block.timestamp % (2**32)) - blockTimestampLast;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L64

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #13

71                   px0Cumulative += uint256((uint224(reserve1) << 112) / reserve0) * timeElapsed;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L71

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #14

72                   px1Cumulative += uint256((uint224(reserve0) << 112) / reserve1) * timeElapsed;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L72

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #15

88               uint32 timeElapsed = uint32(block.timestamp % (2**32)) - blockTimestampLast;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L88

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #16

95                   px0Cumulative += uint256((uint224(reserve1) << 112) / reserve0) * timeElapsed;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L95

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #17

112               uint32 timeElapsed = uint32(block.timestamp % (2**32)) - blockTimestampLast;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L112

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #18

119                   px1Cumulative += uint256((uint224(reserve0) << 112) / reserve1) * timeElapsed;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L119

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #19

177           return FullMath.mulDiv(token < baseToken ? price0(pair) : price1(pair), baseUnit, 2**112);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L177

File: /contracts/PriceOracleImplementation.sol   #20

25               return 1e18;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L25

File: /contracts/PriceOracleImplementation.sol   #21

29           int256 usdcPrice = ChainlinkFeed(0x986b5E1e1755e3C2440e960477f25201B0a8bbD4).latestAnswer();

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L29

File: /contracts/PriceOracleImplementation.sol   #22

35           uint256 result = uint256(usdcPrice) * 1e12;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L35

File: /contracts/PriceOracleImplementation.sol   #23

36           if (result / uint256(usdcPrice) != 1e12) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L36

5. Use a more recent version of solidity

Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions

File: /contracts/ERC1155Enumerable.sol   #1

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L2

6. Use scientific notation (e.g. 1e18) rather than exponentiation (e.g. 10**18)

File: /contracts/Oracles/CNftPriceOracle.sol   #1

99           return FullMath.mulDiv(pricePerToken, 10**18 - mintFee, 10**18);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L99

File: /contracts/Oracles/CNftPriceOracle.sol   #2

99           return FullMath.mulDiv(pricePerToken, 10**18 - mintFee, 10**18);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L99

7. Non-library/interface files should use fixed compiler versions, not floating ones

File: /contracts/CErc20.sol   #1

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L1

File: /contracts/CEther.sol   #2

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L1

File: /contracts/CNft.sol   #3

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L2

File: /contracts/Comptroller.sol   #4

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1

File: /contracts/CToken.sol   #5

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1

File: /contracts/Oracles/CNftPriceOracle.sol   #6

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L2

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #7

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L2

File: /contracts/PriceOracleImplementation.sol   #8

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L1

8. Typos

File: /contracts/CErc20.sol   #1

143        * @param addAmount The amount fo underlying token to add as reserves

fo https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L143

File: /contracts/CNft.sol   #2

106           // We call the internal function instad of the public one because in liquidation, we

instad https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L106

File: /contracts/Comptroller.sol   #3

696        * @dev Used in liquidation (called in cToken.liquidateBorrowFreshNft)

liquidateBorrowFreshNft https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L696

File: /contracts/CToken.sol   #4

839        * @param repayAmount the amount of undelrying tokens being returned

undelrying https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L839

File: /contracts/CToken.sol   #5

1374           /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */

NewReserves https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1374

File: /contracts/CToken.sol   #6

1514        * @dev Performs a transfer out, ideally returning an explanatory error code upon failure tather than reverting.

tather https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1514

File: /contracts/PriceOracleImplementation.sol   #7

34           // Checck for overflow.

Checck https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L34

9. File does not contain an SPDX Identifier

File: /contracts/CErc20.sol   #1

0   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L0

File: /contracts/CEther.sol   #2

0   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L0

File: /contracts/Comptroller.sol   #3

0   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L0

File: /contracts/CToken.sol   #4

0   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L0

File: /contracts/PriceOracleImplementation.sol   #5

0   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L0

10. NatSpec is incomplete

File: /contracts/CNft.sol   #1

272        * @param data Encoded data to send
273        */
274       function call(
275           address to,
276           uint256 value,
277           bytes calldata data
278       ) external payable nonReentrant onlyOwner returns (bool success) {

Missing: @return https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L272-L278

File: /contracts/Comptroller.sol   #2

401        * @param repayAmount The amount of underlying being repaid
402        */
403       function liquidateBorrowAllowed(
404           address cTokenBorrowed,
405           address cTokenCollateral,
406           address liquidator,
407           address borrower,
408           uint repayAmount) external returns (uint) {

Missing: @return https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L401-L408

File: /contracts/Comptroller.sol   #3

447        * @param seizeTokens The number of collateral tokens to seize
448        */
449       function seizeAllowed(
450           address cTokenCollateral,
451           address cTokenBorrowed,
452           address liquidator,
453           address borrower,
454           uint seizeTokens) external returns (uint) {

Missing: @return https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L447-L454

File: /contracts/Comptroller.sol   #4

527       /**
528        * @notice Determine the current account liquidity wrt collateral requirements
529        * @return (possible error code (semi-opaque),
530                   account liquidity in excess of collateral requirements,
531        *          account shortfall below collateral requirements)
532        */
533       function getAccountLiquidity(address account) public view returns (uint, uint, uint) {

Missing: @param account https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L527-L533

File: /contracts/Comptroller.sol   #5

539       /**
540        * @notice Determine the current account liquidity wrt collateral requirements
541        * @return (possible error code,
542                   account liquidity in excess of collateral requirements,
543        *          account shortfall below collateral requirements)
544        */
545       function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) {

Missing: @param account https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L539-L545

File: /contracts/Comptroller.sol   #6

694       /**
695        * @notice Calculate number of cNFT tokens to seize given an underlying amount
696        * @dev Used in liquidation (called in cToken.liquidateBorrowFreshNft)
697        * @param cTokenBorrowed The address of the borrowed cToken
698        * @param actualRepayAmount The amount of cTokenBorrowed underlying to convert into NFTs
699        * @return (errorCode, number of cNft tokens to be seized in a liquidation)
700        */
701       function liquidateCalculateSeizeNfts(address cTokenBorrowed, address cNftCollateral, uint actualRepayAmount) external view returns (uint, uint) {

Missing: @param cNftCollateral https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L694-L701

File: /contracts/Comptroller.sol   #7

736       /**
737         * @notice Sets a new price oracle for the comptroller
738         * @dev Admin function to set a new price oracle
739         * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
740         */
741       function _setPriceOracle(PriceOracle newOracle) public returns (uint) {

Missing: @param newOracle https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L736-L741

File: /contracts/Comptroller.sol   #8

759       /**
760         * @notice Sets a new price oracle for the comptroller
761         * @dev Admin function to set a new price oracle
762         * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
763         */
764       function _setNftPriceOracle(NftPriceOracle newOracle) public returns (uint) {

Missing: @param newOracle https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L759-L764

File: /contracts/Comptroller.sol   #9

1111       /**
1112        * @notice Accrue COMP to the market by updating the borrow index
1113        * @param cToken The market whose borrow index to update
1114        */
1115       function updateCompBorrowIndex(address cToken, Exp memory marketBorrowIndex) internal {

Missing: @param marketBorrowIndex https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1111-L1115

File: /contracts/Comptroller.sol   #10

1157       /**
1158        * @notice Calculate COMP accrued by a borrower and possibly transfer it to them
1159        * @dev Borrowers will not begin to accrue until after the first interaction with the protocol.
1160        * @param cToken The market in which the borrower is interacting
1161        * @param borrower The address of the borrower to distribute COMP to
1162        */
1163       function distributeBorrowerComp(address cToken, address borrower, Exp memory marketBorrowIndex) internal {

Missing: @param marketBorrowIndex https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1157-L1163

File: /contracts/Comptroller.sol   #11

1320        * @param cToken The market to check if deprecated
1321        */
1322       function isDeprecated(CToken cToken) public view returns (bool) {

Missing: @return https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1320-L1322

File: /contracts/CToken.sol   #12

726       /**
727         * @notice Users borrow assets from the protocol to their own address
728         * @param borrowAmount The amount of the underlying asset to borrow
729         * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
730         */
731       function borrowFresh(address payable borrower, uint borrowAmount) internal returns (uint) {

Missing: @param borrower https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L726-L731

File: /contracts/CToken.sol   #13

1251       /**
1252         * @notice Sets a new comptroller for the market
1253         * @dev Admin function to set a new comptroller
1254         * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
1255         */
1256       function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {

Missing: @param newComptroller https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1251-L1256

File: /contracts/CToken.sol   #14

1275       /**
1276         * @notice accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh
1277         * @dev Admin function to accrue interest and set a new reserve factor
1278         * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
1279         */
1280       function _setReserveFactor(uint newReserveFactorMantissa) external nonReentrant returns (uint) {

Missing: @param newReserveFactorMantissa https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1275-L1280

File: /contracts/CToken.sol   #15

1290       /**
1291         * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)
1292         * @dev Admin function to set a new reserve factor
1293         * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
1294         */
1295       function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {

Missing: @param newReserveFactorMantissa https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1290-L1295

11. Event is missing indexed fields

Each event should use three indexed fields if there are three or more fields

File: /contracts/Comptroller.sol   #1

18       event MarketListed(CToken cToken);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L18

File: /contracts/Comptroller.sol   #2

21       event MarketEntered(CToken cToken, address account);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L21

File: /contracts/Comptroller.sol   #3

24       event MarketExited(CToken cToken, address account);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L24

File: /contracts/Comptroller.sol   #4

27       event NewCloseFactor(uint oldCloseFactorMantissa, uint newCloseFactorMantissa);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L27

File: /contracts/Comptroller.sol   #5

30       event NewCollateralFactor(CToken cToken, uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L30

File: /contracts/Comptroller.sol   #6

33       event NewNftCollateralFactor(uint oldCollateralFactorMantissa, uint newCollateralFactorMantissa);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L33

File: /contracts/Comptroller.sol   #7

36       event NewLiquidationIncentive(uint oldLiquidationIncentiveMantissa, uint newLiquidationIncentiveMantissa);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L36

File: /contracts/Comptroller.sol   #8

39       event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L39

File: /contracts/Comptroller.sol   #9

42       event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L42

File: /contracts/Comptroller.sol   #10

45       event ActionPaused(string action, bool pauseState);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L45

File: /contracts/Comptroller.sol   #11

48       event ActionPaused(CToken cToken, string action, bool pauseState);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L48

File: /contracts/Comptroller.sol   #12

51       event CompSpeedUpdated(CToken indexed cToken, uint newSpeed);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L51

File: /contracts/Comptroller.sol   #13

54       event ContributorCompSpeedUpdated(address indexed contributor, uint newSpeed);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L54

File: /contracts/Comptroller.sol   #14

57       event DistributedSupplierComp(CToken indexed cToken, address indexed supplier, uint compDelta, uint compSupplyIndex);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L57

File: /contracts/Comptroller.sol   #15

60       event DistributedBorrowerComp(CToken indexed cToken, address indexed borrower, uint compDelta, uint compBorrowIndex);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L60

File: /contracts/Comptroller.sol   #16

63       event NewBorrowCap(CToken indexed cToken, uint newBorrowCap);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L63

File: /contracts/Comptroller.sol   #17

66       event NewBorrowCapGuardian(address oldBorrowCapGuardian, address newBorrowCapGuardian);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L66

File: /contracts/Comptroller.sol   #18

69       event CompGranted(address recipient, uint amount);

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L69

Awards

188.119 USDC - $188.12

Labels

bug
G (Gas Optimization)

External Links

1. Multiple address mappings can be combined into a single mapping of an address to a struct, where appropriate

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #1

20       mapping(address => Observation[OBSERVATION_BUFFER_SIZE]) public pairObservations;
21       mapping(address => uint256) public numPairObservations;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L20-L21

2. State variables only set in the constructor should be declared immutable

Avoids a Gsset (20000 gas) in the constructor, and replaces each Gwarmacces (100 gas) with a PUSH32 (3 gas)

File: /contracts/PriceOracleImplementation.sol   #1

10       address public cEtherAddress;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L10

3. State variables should be cached in stack variables rather than re-reading them from storage

The instances below point to the second+ access of a state variable within a function. Caching will replace each Gwarmaccess (100 gas) with a much cheaper stack read. Less obvious fixes/optimizations include having local storage variables of mappings within state variable mappings or mappings within state variable structs, having local storage variables of structs within mappings, having local memory caches of state variable structs, or having local caches of state variable contracts/addresses.

File: /contracts/ERC1155Enumerable.sol   #1

49           EnumerableSet.UintSet storage toTokens = _tokensByAccount[to];

_tokensByAccount https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L49

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #2

132               lastObservation = pairObservations[pair][(length - 2) % OBSERVATION_BUFFER_SIZE];

pairObservations https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L132

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #3

153               lastObservation = pairObservations[pair][(length - 2) % OBSERVATION_BUFFER_SIZE];

pairObservations https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L153

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #4

27               (block.timestamp - pairObservations[pair][(numPairObservations[pair] - 1) % OBSERVATION_BUFFER_SIZE].timestamp) <= MIN_TWAP_TIME

numPairObservations https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L27

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #5

32           pairObservations[pair][numPairObservations[pair]++ % OBSERVATION_BUFFER_SIZE] = Observation(

numPairObservations https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L32

4. <x> += <y> costs more gas than <x> = <x> + <y> for state variables

File: /contracts/ERC1155Enumerable.sol   #1

59                   totalSupply += amount;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L59

File: /contracts/ERC1155Enumerable.sol   #2

65                   totalSupply -= amount;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L65

5. internal functions only called once can be inlined to save gas

Not inlining costs 20 to 40 gas because of two extra JUMP instructions and additional stack operations needed for function calls.

File: /contracts/CNft.sol   #1

248       function executeCall(
249           address to,
250           uint256 value,
251           bytes memory data,
252           uint256 txGas
253       ) internal returns (bool success) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L248-L253

File: /contracts/Comptroller.sol   #2

545       function getAccountLiquidityInternal(address account) internal view returns (Error, uint, uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L545

File: /contracts/Comptroller.sol   #3

927       function _addMarketInternal(address cToken) internal {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L927

File: /contracts/Comptroller.sol   #4

1055       function setCompSpeedInternal(CToken cToken, uint compSpeed) internal {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1055

File: /contracts/Comptroller.sol   #5

1139       function distributeSupplierComp(address cToken, address supplier) internal {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1139

File: /contracts/CToken.sol   #6

495       function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L495

File: /contracts/CToken.sol   #7

731       function borrowFresh(address payable borrower, uint borrowAmount) internal returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L731

File: /contracts/CToken.sol   #8

941       function liquidateBorrowFresh(address liquidator, address borrower, uint repayAmount, CTokenInterface cTokenCollateral) internal returns (uint, uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L941

File: /contracts/CToken.sol   #9

1041       function liquidateBorrowNftFresh(address liquidator, address borrower, uint repayAmount, CNftInterface cNftCollateral, uint[] memory seizeIds, uint[] memory seizeAmounts) internal returns (uint, uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1041

File: /contracts/CToken.sol   #10

1295       function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1295

File: /contracts/CToken.sol   #11

1342       function _addReservesFresh(uint addAmount) internal returns (uint, uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1342

File: /contracts/CToken.sol   #12

1403       function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1403

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #13

24       function update(address pair) internal returns (bool) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L24

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #14

52       function cumulativePrices(
53           address pair
54       ) internal view returns (uint256 px0Cumulative, uint256 px1Cumulative) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L52-L54

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #15

78       function price0Cumulative(address pair) internal view returns (uint256) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L78

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #16

102       function price1Cumulative(address pair) internal view returns (uint256) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L102

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #17

126       function price0(address pair) internal view returns (uint256) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L126

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #18

147       function price1(address pair) internal view returns (uint256) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L147

6. <array>.length should not be looked up in every loop of a for-loop

The overheads outlined below are PER LOOP, excluding the first loop

  • storage arrays incur a Gwarmaccess (100 gas)
  • memory arrays use MLOAD (3 gas)
  • calldata arrays use CALLDATALOAD (3 gas)

Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset

File: /contracts/CEther.sol   #1

178           for (i = 0; i < bytes(message).length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L178

File: /contracts/CNft.sol   #2

176           for (uint256 i; i < vars.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L176

File: /contracts/Comptroller.sol   #3

591           for (uint i = 0; i < assets.length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L591

File: /contracts/Comptroller.sol   #4

928           for (uint i = 0; i < allMarkets.length; i ++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L928

File: /contracts/Comptroller.sol   #5

1223           for (uint i = 0; i < cTokens.length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1223

File: /contracts/Comptroller.sol   #6

1229                   for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1229

File: /contracts/Comptroller.sol   #7

1235                   for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1235

File: /contracts/Comptroller.sol   #8

1240           for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1240

File: /contracts/ERC1155Enumerable.sol   #9

51           for (uint256 i; i < ids.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L51

File: /contracts/Oracles/CNftPriceOracle.sol   #10

66           for (uint256 i = 0; i < cNfts.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L66

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #11

42           for (uint256 i = 0; i < pairs.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L42

7. ++i/i++ should be unchecked{++i}/unchecked{++i} when it is not possible for them to overflow, as is the case when used in for- and while-loops

This saves 30-40 gas PER LOOP

File: /contracts/CNft.sol   #1

50           for (uint256 i; i < length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L50

File: /contracts/CNft.sol   #2

62                   for (uint256 i; i < length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L62

File: /contracts/CNft.sol   #3

72                   for (uint256 i; i < length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L72

File: /contracts/CNft.sol   #4

98           for (uint256 i; i < length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L98

File: /contracts/CNft.sol   #5

122           for (uint256 i; i < length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L122

File: /contracts/CNft.sol   #6

145                   for (uint256 i; i < length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L145

File: /contracts/CNft.sol   #7

151                   for (uint256 i; i < length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L151

File: /contracts/CNft.sol   #8

176           for (uint256 i; i < vars.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L176

File: /contracts/ERC1155Enumerable.sol   #9

51           for (uint256 i; i < ids.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L51

File: /contracts/Oracles/CNftPriceOracle.sol   #10

66           for (uint256 i = 0; i < cNfts.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L66

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #11

42           for (uint256 i = 0; i < pairs.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L42

8. require()/revert() strings longer than 32 bytes cost extra gas

File: /contracts/CErc20.sol   #1

136       	require(address(token) != underlying, "CErc20::sweepToken: can not sweep underlying token");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L136

File: /contracts/CErc20.sol   #2

234           require(msg.sender == admin, "only the admin may set the comp-like delegate");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L234

File: /contracts/CNft.sol   #3

24           require(_underlying != address(0), "CNFT: Asset should not be address(0)");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L24

File: /contracts/CNft.sol   #4

25           require(ComptrollerInterface(_comptroller).isComptroller(), "_comptroller is not a Comptroller contract");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L25

File: /contracts/CNft.sol   #5

52                   require(amounts[i] == 1, "CNFT: Amounts must be all 1s for non-ERC1155s.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L52

File: /contracts/CNft.sol   #6

69                       require(buyPunkSuccess, "CNFT: Calling buyPunk was unsuccessful");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L69

File: /contracts/CNft.sol   #7

93           require(borrower != liquidator, "CNFT: Liquidator cannot be borrower");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L93

File: /contracts/CNft.sol   #8

100                   require(seizeAmounts[i] == 1, "CNFT: Amounts must be all 1s for non-ERC1155s.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L100

File: /contracts/CNft.sol   #9

124                   require(amounts[i] == 1, "CNFT: Amounts must be all 1s for non-ERC1155s.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L124

File: /contracts/CNft.sol   #10

148                       require(transferPunkSuccess, "CNFT: Calling transferPunk was unsuccessful");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L148

File: /contracts/CNft.sol   #11

204               revert("CNFT: Use safeBatchTransferFrom instead");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L204

File: /contracts/CNft.sol   #12

208           require(msg.sender == underlying, "CNFT: This contract can only receive the underlying NFT");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L208

File: /contracts/CNft.sol   #13

209           require(operator == address(this), "CNFT: Only the CNFT contract can be the operator");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L209

File: /contracts/CNft.sol   #14

279           require(to != underlying, "CNFT: Cannot make an arbitrary call to underlying NFT");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L279

File: /contracts/Comptroller.sol   #15

171           require(oErr == 0, "exitMarket: getAccountSnapshot failed"); // semi-opaque error code

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L171

File: /contracts/Comptroller.sol   #16

420               require(borrowBalance >= repayAmount, "Can not repay more than the total borrow");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L420

File: /contracts/Comptroller.sol   #17

702           require(cNftCollateral == address(nftMarket), "cNFT is from the wrong comptroller");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L702

File: /contracts/Comptroller.sol   #18

942       	require(msg.sender == admin || msg.sender == borrowCapGuardian, "only admin or borrow cap guardian can set borrow caps");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L942

File: /contracts/Comptroller.sol   #19

960           require(msg.sender == admin, "only admin can set borrow cap guardian");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L960

File: /contracts/Comptroller.sol   #20

995           require(markets[cAsset].isListed, "cannot pause a market that is not listed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L995

File: /contracts/Comptroller.sol   #21

996           require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L996

File: /contracts/Comptroller.sol   #22

1009           require(markets[address(cToken)].isListed, "cannot pause a market that is not listed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1009

File: /contracts/Comptroller.sol   #23

1010           require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1010

File: /contracts/Comptroller.sol   #24

1019           require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1019

File: /contracts/Comptroller.sol   #25

1028           require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1028

File: /contracts/Comptroller.sol   #26

1037           require(msg.sender == unitroller.admin(), "only unitroller admin can change brains");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1037

File: /contracts/Comptroller.sol   #27

1338           require(address(nftMarket) == address(0), "nft collateral already initialized");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1338

File: /contracts/Comptroller.sol   #28

1339           require(address(cNft) != address(0), "cannot initialize nft market to the 0 address");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1339

File: /contracts/CToken.sol   #29

32           require(msg.sender == admin, "only admin may initialize the market");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L32

File: /contracts/CToken.sol   #30

33           require(accrualBlockNumber == 0 && borrowIndex == 0, "market may only be initialized once");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L33

File: /contracts/CToken.sol   #31

37           require(initialExchangeRateMantissa > 0, "initial exchange rate must be greater than zero.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L37

File: /contracts/CToken.sol   #32

49           require(err == uint(Error.NO_ERROR), "setting interest rate model failed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L49

File: /contracts/CToken.sol   #33

271           require(err == MathError.NO_ERROR, "borrowBalanceStored: borrowBalanceStoredInternal failed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L271

File: /contracts/CToken.sol   #34

328           require(err == MathError.NO_ERROR, "exchangeRateStored: exchangeRateStoredInternal failed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L328

File: /contracts/CToken.sol   #35

542           require(vars.mathErr == MathError.NO_ERROR, "MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L542

File: /contracts/CToken.sol   #36

545           require(vars.mathErr == MathError.NO_ERROR, "MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L545

File: /contracts/CToken.sol   #37

609           require(redeemTokensIn == 0 || redeemAmountIn == 0, "one of redeemTokensIn or redeemAmountIn must be zero");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L609

File: /contracts/CToken.sol   #38

891           require(vars.mathErr == MathError.NO_ERROR, "REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L891

File: /contracts/CToken.sol   #39

894           require(vars.mathErr == MathError.NO_ERROR, "REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L894

File: /contracts/CToken.sol   #40

986           require(amountSeizeError == uint(Error.NO_ERROR), "LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L986

File: /contracts/CToken.sol   #41

1083           require(amountSeizeError == uint(Error.NO_ERROR), "LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1083

File: /contracts/CToken.sol   #42

1093           require(seizeTokens == 0, "LIQUIDATE_SEIZE_INCORRECT_NUM_NFTS");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1093

File: /contracts/CToken.sol   #43

1433           require(totalReservesNew <= totalReserves, "reduce reserves unexpected underflow");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1433

File: /contracts/Oracles/CNftPriceOracle.sol   #44

62           require(
63               cNfts.length > 0 && cNfts.length == nftxTokens.length,
64               "CNftPriceOracle: `cNfts` and `nftxTokens` must have nonzero, equal lengths."
65           );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L62-L65

File: /contracts/Oracles/CNftPriceOracle.sol   #45

68               require(
69                   underlyingNftxTokenAddress[underlying] == address(0),
70                   "CNftPriceOracle: Cannot overwrite existing address mappings."
71               );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L68-L71

File: /contracts/Oracles/CNftPriceOracle.sol   #46

88           require(
89               nftxToken != address(0),
90               "CNftPriceOracle: No NFTX token for cNFT."
91           );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L88-L91

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #47

66                   require(
67                       reserve0 > 0 && reserve1 > 0,
68                       "UniswapV2PriceOracle: Division by zero."
69                   );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L66-L69

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #48

90                   require(
91                       reserve0 > 0,
92                       "UniswapV2PriceOracle: Division by zero."
93                   );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L90-L93

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #49

114                   require(
115                       reserve1 > 0,
116                       "UniswapV2PriceOracle: Division by zero."
117                   );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L114-L117

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #50

128           require(length > 0, "UniswapV2PriceOracle: No observations.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L128

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #51

131               require(length > 1, "UniswapV2PriceOracle: Only one observation.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L131

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #52

135           require(
136               block.timestamp - lastObservation.timestamp >= MIN_TWAP_TIME,
137               "UniswapV2PriceOracle: Bad TWAP time."
138           );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L135-L138

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #53

149           require(length > 0, "UniswapV2PriceOracle: No observations.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L149

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #54

152               require(length > 1, "UniswapV2PriceOracle: Only one observation.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L152

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #55

156           require(
157               block.timestamp - lastObservation.timestamp >= MIN_TWAP_TIME,
158               "UniswapV2PriceOracle: Bad TWAP time."
159           );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L156-L159

9. Using bools for storage incurs overhead

    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/contracts/security/ReentrancyGuard.sol#L23-L27 Use uint256(1) and uint256(2) for true/false

File: /contracts/Oracles/CNftPriceOracle.sol   #1

12       bool public constant isNftPriceOracle = true;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L12

10. Use a more recent version of solidity

Use a solidity version of at least 0.8.0 to get overflow protection without SafeMath Use a solidity version of at least 0.8.2 to get compiler automatic inlining Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value

File: /contracts/CErc20.sol   #1

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L1

File: /contracts/CEther.sol   #2

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L1

File: /contracts/Comptroller.sol   #3

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1

File: /contracts/CToken.sol   #4

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1

File: /contracts/PriceOracleImplementation.sol   #5

1   pragma solidity ^0.5.16;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/PriceOracleImplementation.sol#L1

11. Use a more recent version of solidity

Use a solidity version of at least 0.8.2 to get compiler automatic inlining Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value

File: /contracts/CNft.sol   #1

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L2

File: /contracts/ERC1155Enumerable.sol   #2

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L2

File: /contracts/Oracles/CNftPriceOracle.sol   #3

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L2

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #4

2   pragma solidity ^0.8.0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L2

12. Using > 0 costs more gas than != 0 when used on a uint in a require() statement

This change saves 6 gas per instance

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #1

90                   require(
91                       reserve0 > 0,
92                       "UniswapV2PriceOracle: Division by zero."
93                   );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L90-L93

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #2

114                   require(
115                       reserve1 > 0,
116                       "UniswapV2PriceOracle: Division by zero."
117                   );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L114-L117

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #3

128           require(length > 0, "UniswapV2PriceOracle: No observations.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L128

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #4

149           require(length > 0, "UniswapV2PriceOracle: No observations.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L149

13. It costs more gas to initialize variables to zero than to let the default of zero be applied

File: /contracts/CNft.sol   #1

49           uint256 totalAmount = 0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L49

File: /contracts/CNft.sol   #2

97           uint256 totalAmount = 0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L97

File: /contracts/CNft.sol   #3

119           uint256 totalAmount = 0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L119

File: /contracts/Comptroller.sol   #4

119           for (uint i = 0; i < len; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L119

File: /contracts/Comptroller.sol   #5

199           for (uint i = 0; i < len; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L199

File: /contracts/Comptroller.sol   #6

591           for (uint i = 0; i < assets.length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L591

File: /contracts/Comptroller.sol   #7

928           for (uint i = 0; i < allMarkets.length; i ++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L928

File: /contracts/Comptroller.sol   #8

949           for(uint i = 0; i < numMarkets; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L949

File: /contracts/Comptroller.sol   #9

1223           for (uint i = 0; i < cTokens.length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1223

File: /contracts/Comptroller.sol   #10

1229                   for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1229

File: /contracts/Comptroller.sol   #11

1235                   for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1235

File: /contracts/Comptroller.sol   #12

1240           for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1240

File: /contracts/CToken.sol   #13

81           uint startingAllowance = 0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L81

File: /contracts/Oracles/CNftPriceOracle.sol   #14

66           for (uint256 i = 0; i < cNfts.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L66

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #15

41           uint256 numberUpdated = 0;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L41

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #16

42           for (uint256 i = 0; i < pairs.length; ++i) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L42

14. internal functions not called by the contract should be removed to save deployment gas

If the functions are required by an interface, the contract should inherit from that interface and use the override keyword

File: /contracts/CErc20.sol   #1

157       function getCashPrior() internal view returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L157

File: /contracts/CErc20.sol   #2

171       function doTransferIn(address from, uint amount) internal returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L171

File: /contracts/CErc20.sol   #3

207       function doTransferOut(address payable to, uint amount) internal {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L207

File: /contracts/CEther.sol   #4

146       function getCashPrior() internal view returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L146

File: /contracts/CEther.sol   #5

158       function doTransferIn(address from, uint amount) internal returns (uint) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L158

File: /contracts/CEther.sol   #6

165       function doTransferOut(address payable to, uint amount) internal {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L165

15. ++i costs less gas than ++i, especially when it's used in for-loops (--i/i-- too)

Saves 6 gas PER LOOP

File: /contracts/CEther.sol   #1

178           for (i = 0; i < bytes(message).length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L178

File: /contracts/Comptroller.sol   #2

119           for (uint i = 0; i < len; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L119

File: /contracts/Comptroller.sol   #3

199           for (uint i = 0; i < len; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L199

File: /contracts/Comptroller.sol   #4

591           for (uint i = 0; i < assets.length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L591

File: /contracts/Comptroller.sol   #5

928           for (uint i = 0; i < allMarkets.length; i ++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L928

File: /contracts/Comptroller.sol   #6

949           for(uint i = 0; i < numMarkets; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L949

File: /contracts/Comptroller.sol   #7

1223           for (uint i = 0; i < cTokens.length; i++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1223

File: /contracts/Comptroller.sol   #8

1229                   for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1229

File: /contracts/Comptroller.sol   #9

1235                   for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1235

File: /contracts/Comptroller.sol   #10

1240           for (uint j = 0; j < holders.length; j++) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1240

16. Splitting require() statements that use && saves gas

See this issue for an example

File: /contracts/CNft.sol   #1

66                       require(checkSuccess && nftOwner == msg.sender, "Not the NFT owner");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L66

File: /contracts/Comptroller.sol   #2

947           require(numMarkets != 0 && numMarkets == numBorrowCaps, "invalid input");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L947

File: /contracts/CToken.sol   #3

33           require(accrualBlockNumber == 0 && borrowIndex == 0, "market may only be initialized once");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L33

File: /contracts/Oracles/CNftPriceOracle.sol   #4

62           require(
63               cNfts.length > 0 && cNfts.length == nftxTokens.length,
64               "CNftPriceOracle: `cNfts` and `nftxTokens` must have nonzero, equal lengths."
65           );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L62-L65

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #5

66                   require(
67                       reserve0 > 0 && reserve1 > 0,
68                       "UniswapV2PriceOracle: Division by zero."
69                   );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L66-L69

17. Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead

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.

https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size then downcast where needed

File: /contracts/CErc20.sol   #1

31                           uint8 decimals_) public {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CErc20.sol#L31

File: /contracts/CEther.sol   #2

26                   uint8 decimals_,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L26

File: /contracts/Comptroller.sol   #3

72       uint224 public constant compInitialIndex = 1e36;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L72

File: /contracts/CToken.sol   #4

31                           uint8 decimals_) public {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L31

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #5

59               uint112 reserve0,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L59

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #6

60               uint112 reserve1,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L60

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #7

61               uint32 blockTimestampLast

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L61

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #8

64               uint32 timeElapsed = uint32(block.timestamp % (2**32)) - blockTimestampLast;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L64

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #9

82               uint112 reserve0,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L82

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #10

83               uint112 reserve1,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L83

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #11

84               uint32 blockTimestampLast

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L84

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #12

88               uint32 timeElapsed = uint32(block.timestamp % (2**32)) - blockTimestampLast;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L88

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #13

106               uint112 reserve0,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L106

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #14

107               uint112 reserve1,

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L107

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #15

108               uint32 blockTimestampLast

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L108

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #16

112               uint32 timeElapsed = uint32(block.timestamp % (2**32)) - blockTimestampLast;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L112

18. Using private rather than public for constants, saves gas

If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table

File: /contracts/Comptroller.sol   #1

72       uint224 public constant compInitialIndex = 1e36;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L72

File: /contracts/Oracles/CNftPriceOracle.sol   #2

12       bool public constant isNftPriceOracle = true;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L12

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #3

17       uint256 public constant OBSERVATION_BUFFER_SIZE = 8;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L17

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #4

18       uint256 public constant MIN_TWAP_TIME = 30 minutes;

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L18

19. Don't compare boolean expressions to boolean literals

if (<x> == true) => if (<x>), if (<x> == false) => if (!<x>)

File: /contracts/Comptroller.sol   #1

142           if (marketToJoin.accountMembership[borrower] == true) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L142

File: /contracts/Comptroller.sol   #2

997           require(msg.sender == admin || state == true, "only admin can unpause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L997

File: /contracts/Comptroller.sol   #3

1011           require(msg.sender == admin || state == true, "only admin can unpause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1011

File: /contracts/Comptroller.sol   #4

1020           require(msg.sender == admin || state == true, "only admin can unpause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1020

File: /contracts/Comptroller.sol   #5

1029           require(msg.sender == admin || state == true, "only admin can unpause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1029

File: /contracts/Comptroller.sol   #6

1065               require(market.isListed == true, "comp market is not listed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1065

File: /contracts/Comptroller.sol   #7

1226               if (borrowers == true) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1226

File: /contracts/Comptroller.sol   #8

1233               if (suppliers == true) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1233

File: /contracts/Comptroller.sol   #9

1325               borrowGuardianPaused[address(cToken)] == true &&

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1325

20. Duplicated require()/revert() checks should be refactored to a modifier or function

Saves deployment costs

File: /contracts/CNft.sol   #1

116           require(tokenIds.length == amounts.length, "CNFT: id/amounts length mismatch");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L116

File: /contracts/CNft.sol   #2

124                   require(amounts[i] == 1, "CNFT: Amounts must be all 1s for non-ERC1155s.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L124

File: /contracts/Comptroller.sol   #3

1010           require(msg.sender == pauseGuardian || msg.sender == admin, "only pause guardian and admin can pause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1010

File: /contracts/Comptroller.sol   #4

1011           require(msg.sender == admin || state == true, "only admin can unpause");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1011

File: /contracts/Comptroller.sol   #5

1293           require(adminOrInitializing(), "only admin can set comp speed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L1293

File: /contracts/CToken.sol   #6

260           require(accrueInterest() == uint(Error.NO_ERROR), "accrue interest failed");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L260

File: /contracts/CToken.sol   #7

1083           require(amountSeizeError == uint(Error.NO_ERROR), "LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CToken.sol#L1083

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #8

149           require(length > 0, "UniswapV2PriceOracle: No observations.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L149

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #9

152               require(length > 1, "UniswapV2PriceOracle: Only one observation.");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L152

File: /contracts/Oracles/UniswapV2PriceOracle.sol   #10

156           require(
157               block.timestamp - lastObservation.timestamp >= MIN_TWAP_TIME,
158               "UniswapV2PriceOracle: Bad TWAP time."
159           );

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/UniswapV2PriceOracle.sol#L156-L159

21. require() or revert() statements that check input arguments should be at the top of the function

Checks that involve constants should come before checks that involve state variables

File: /contracts/CEther.sol   #1

188           require(errCode == uint(Error.NO_ERROR), string(fullMessage));

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CEther.sol#L188

File: /contracts/CNft.sol   #2

93           require(borrower != liquidator, "CNFT: Liquidator cannot be borrower");

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L93

22. Functions guaranteed to revert when called by normal users can be marked payable

If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are CALLVALUE(2),DUP1(3),ISZERO(3),PUSH2(3),JUMPI(10),PUSH1(3),DUP1(3),REVERT(0),JUMPDEST(1),POP(2), which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost

File: /contracts/CNft.sol   #1

274       function call(
275           address to,
276           uint256 value,
277           bytes calldata data
278       ) external payable nonReentrant onlyOwner returns (bool success) {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L274-L278

File: /contracts/ERC1155Enumerable.sol   #2

26       function __ERC1155Enumerable_init(string memory uri_) public onlyInitializing {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/ERC1155Enumerable.sol#L26

File: /contracts/Oracles/CNftPriceOracle.sol   #3

54       function changeAdmin(address newAdmin) external onlyAdmin {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L54

File: /contracts/Oracles/CNftPriceOracle.sol   #4

58       function addAddressMapping(
59           CNftInterface[] calldata cNfts,
60           address[] calldata nftxTokens
61       ) external onlyAdmin {

https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Oracles/CNftPriceOracle.sol#L58-L61

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter