Skip to content

Instantly share code, notes, and snippets.

@hrkrshnn
Last active November 16, 2023 20:12
Show Gist options
  • Save hrkrshnn/9bd4d0ee06d66c2f75db5044cb5fd399 to your computer and use it in GitHub Desktop.
Save hrkrshnn/9bd4d0ee06d66c2f75db5044cb5fd399 to your computer and use it in GitHub Desktop.

Report

Gas Optimizations

Issue Instances
GAS-1 For Operations that will not overflow, you could use unchecked 21

[GAS-1] For Operations that will not overflow, you could use unchecked

Instances (21):

File: ERC20PermissionedBase.sol

4: import {IERC20} from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";

4: import {IERC20} from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";

4: import {IERC20} from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";

4: import {IERC20} from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";

6: import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";

6: import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";

6: import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";

6: import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";

6: import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";

7: import {ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

7: import {ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

7: import {ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

7: import {ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

7: import {ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

7: import {ERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

8: import {ERC20Wrapper} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

8: import {ERC20Wrapper} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

8: import {ERC20Wrapper} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

8: import {ERC20Wrapper} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

8: import {ERC20Wrapper} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

8: import {ERC20Wrapper} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

Report

Gas Optimizations

Issue Instances
GAS-1 Using bools for storage incurs overhead 2
GAS-2 Cache array length outside of loop 6
GAS-3 For Operations that will not overflow, you could use unchecked 192
GAS-4 Functions guaranteed to revert when called by normal users can be marked payable 16
GAS-5 Use != 0 instead of > 0 for unsigned integer comparison 6

[GAS-1] Using bools for storage incurs overhead

Use uint256(1) and uint256(2) for true/false to avoid a Gwarmaccess (100 gas), and to avoid Gsset (20000 gas) when changing from ‘false’ to ‘true’, after having been ‘true’ in the past. See source.

Instances (2):

File: MetaMorpho.sol

67:     mapping(address => bool) public isAllocator;
File: MetaMorphoFactory.sol

22:     mapping(address => bool) public isMetaMorpho;

[GAS-2] Cache array length outside of loop

If not cached, the solidity compiler will always read the length of the array during each iteration. That is, if it is a storage array, this is an extra sload operation (100 additional extra gas for each iteration except for the first) and if it is a memory array, this is an extra mload operation (3 additional gas for each iteration except for the first).

Instances (6):

File: MetaMorpho.sol

400:         for (uint256 i; i < allocations.length; ++i) {

614:         for (uint256 i; i < withdrawQueue.length; ++i) {

643:         for (uint256 i; i < supplyQueue.length; ++i) {

798:         for (uint256 i; i < supplyQueue.length; ++i) {

824:         for (uint256 i; i < withdrawQueue.length; ++i) {

849:         for (uint256 i; i < withdrawQueue.length; ++i) {

[GAS-3] For Operations that will not overflow, you could use unchecked

Instances (192):

File: MetaMorpho.sol

4: import {IMorphoMarketParams} from "./interfaces/IMorphoMarketParams.sol";

4: import {IMorphoMarketParams} from "./interfaces/IMorphoMarketParams.sol";

11: } from "./interfaces/IMetaMorpho.sol";

11: } from "./interfaces/IMetaMorpho.sol";

12: import {Id, MarketParams, Market, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

12: import {Id, MarketParams, Market, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

12: import {Id, MarketParams, Market, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

12: import {Id, MarketParams, Market, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

12: import {Id, MarketParams, Market, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

12: import {Id, MarketParams, Market, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

14: import {PendingUint192, PendingAddress, PendingLib} from "./libraries/PendingLib.sol";

14: import {PendingUint192, PendingAddress, PendingLib} from "./libraries/PendingLib.sol";

15: import {ConstantsLib} from "./libraries/ConstantsLib.sol";

15: import {ConstantsLib} from "./libraries/ConstantsLib.sol";

16: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

16: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

17: import {EventsLib} from "./libraries/EventsLib.sol";

17: import {EventsLib} from "./libraries/EventsLib.sol";

18: import {WAD} from "../lib/morpho-blue/src/libraries/MathLib.sol";

18: import {WAD} from "../lib/morpho-blue/src/libraries/MathLib.sol";

18: import {WAD} from "../lib/morpho-blue/src/libraries/MathLib.sol";

18: import {WAD} from "../lib/morpho-blue/src/libraries/MathLib.sol";

18: import {WAD} from "../lib/morpho-blue/src/libraries/MathLib.sol";

18: import {WAD} from "../lib/morpho-blue/src/libraries/MathLib.sol";

19: import {UtilsLib} from "../lib/morpho-blue/src/libraries/UtilsLib.sol";

19: import {UtilsLib} from "../lib/morpho-blue/src/libraries/UtilsLib.sol";

19: import {UtilsLib} from "../lib/morpho-blue/src/libraries/UtilsLib.sol";

19: import {UtilsLib} from "../lib/morpho-blue/src/libraries/UtilsLib.sol";

19: import {UtilsLib} from "../lib/morpho-blue/src/libraries/UtilsLib.sol";

19: import {UtilsLib} from "../lib/morpho-blue/src/libraries/UtilsLib.sol";

20: import {SafeCast} from "../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

20: import {SafeCast} from "../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

20: import {SafeCast} from "../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

20: import {SafeCast} from "../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

20: import {SafeCast} from "../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

20: import {SafeCast} from "../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

20: import {SafeCast} from "../lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

21: import {SharesMathLib} from "../lib/morpho-blue/src/libraries/SharesMathLib.sol";

21: import {SharesMathLib} from "../lib/morpho-blue/src/libraries/SharesMathLib.sol";

21: import {SharesMathLib} from "../lib/morpho-blue/src/libraries/SharesMathLib.sol";

21: import {SharesMathLib} from "../lib/morpho-blue/src/libraries/SharesMathLib.sol";

21: import {SharesMathLib} from "../lib/morpho-blue/src/libraries/SharesMathLib.sol";

21: import {SharesMathLib} from "../lib/morpho-blue/src/libraries/SharesMathLib.sol";

22: import {MorphoLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoLib.sol";

22: import {MorphoLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoLib.sol";

22: import {MorphoLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoLib.sol";

22: import {MorphoLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoLib.sol";

22: import {MorphoLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoLib.sol";

22: import {MorphoLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoLib.sol";

22: import {MorphoLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoLib.sol";

23: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";

23: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";

23: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";

23: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";

23: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";

23: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

24: import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

25: import {MorphoBalancesLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

25: import {MorphoBalancesLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

25: import {MorphoBalancesLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

25: import {MorphoBalancesLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

25: import {MorphoBalancesLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

25: import {MorphoBalancesLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

25: import {MorphoBalancesLib} from "../lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

27: import {Multicall} from "../lib/openzeppelin-contracts/contracts/utils/Multicall.sol";

27: import {Multicall} from "../lib/openzeppelin-contracts/contracts/utils/Multicall.sol";

27: import {Multicall} from "../lib/openzeppelin-contracts/contracts/utils/Multicall.sol";

27: import {Multicall} from "../lib/openzeppelin-contracts/contracts/utils/Multicall.sol";

27: import {Multicall} from "../lib/openzeppelin-contracts/contracts/utils/Multicall.sol";

27: import {Multicall} from "../lib/openzeppelin-contracts/contracts/utils/Multicall.sol";

28: import {Ownable2Step, Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";

28: import {Ownable2Step, Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";

28: import {Ownable2Step, Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";

28: import {Ownable2Step, Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";

28: import {Ownable2Step, Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";

28: import {Ownable2Step, Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

29: import {ERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

37: } from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

315:         config[id].removableAt = uint64(block.timestamp + timelock);

330:         for (uint256 i; i < length; ++i) {

330:         for (uint256 i; i < length; ++i) {

353:         for (uint256 i; i < newLength; ++i) {

353:         for (uint256 i; i < newLength; ++i) {

364:         for (uint256 i; i < currLength; ++i) {

364:         for (uint256 i; i < currLength; ++i) {

400:         for (uint256 i; i < allocations.length; ++i) {

400:         for (uint256 i; i < allocations.length; ++i) {

422:                 totalWithdrawn += withdrawnAssets;

433:                 if (supplyAssets + suppliedAssets > supplyCap) revert ErrorsLib.SupplyCapExceeded(id);

441:                 totalSupplied += suppliedAssets;

614:         for (uint256 i; i < withdrawQueue.length; ++i) {

614:         for (uint256 i; i < withdrawQueue.length; ++i) {

615:             assets += MORPHO.expectedSupplyAssets(_marketParams(withdrawQueue[i]), address(this));

635:         newTotalSupply = totalSupply() + feeShares;

638:         assets -= _simulateWithdrawMorpho(assets);

643:         for (uint256 i; i < supplyQueue.length; ++i) {

643:         for (uint256 i; i < supplyQueue.length; ++i) {

651:             totalSuppliable += supplyCap.zeroFloorSub(supplyAssets);

660:         return _convertToSharesWithTotals(assets, totalSupply() + feeShares, newTotalAssets, rounding);

668:         return _convertToAssetsWithTotals(shares, totalSupply() + feeShares, newTotalAssets, rounding);

679:         return assets.mulDiv(newTotalSupply + 10 ** _decimalsOffset(), newTotalAssets + 1, rounding);

679:         return assets.mulDiv(newTotalSupply + 10 ** _decimalsOffset(), newTotalAssets + 1, rounding);

679:         return assets.mulDiv(newTotalSupply + 10 ** _decimalsOffset(), newTotalAssets + 1, rounding);

679:         return assets.mulDiv(newTotalSupply + 10 ** _decimalsOffset(), newTotalAssets + 1, rounding);

690:         return shares.mulDiv(newTotalAssets + 1, newTotalSupply + 10 ** _decimalsOffset(), rounding);

690:         return shares.mulDiv(newTotalAssets + 1, newTotalSupply + 10 ** _decimalsOffset(), rounding);

690:         return shares.mulDiv(newTotalAssets + 1, newTotalSupply + 10 ** _decimalsOffset(), rounding);

690:         return shares.mulDiv(newTotalAssets + 1, newTotalSupply + 10 ** _decimalsOffset(), rounding);

701:         _updateLastTotalAssets(lastTotalAssets + assets);

798:         for (uint256 i; i < supplyQueue.length; ++i) {

798:         for (uint256 i; i < supplyQueue.length; ++i) {

812:                     assets -= toSupply;

824:         for (uint256 i; i < withdrawQueue.length; ++i) {

824:         for (uint256 i; i < withdrawQueue.length; ++i) {

836:                     assets -= toWithdraw;

849:         for (uint256 i; i < withdrawQueue.length; ++i) {

849:         for (uint256 i; i < withdrawQueue.length; ++i) {

886:             totalSupplyAssets - totalBorrowAssets, ERC20(marketParams.loanToken).balanceOf(address(MORPHO))

923:                 _convertToSharesWithTotals(feeAssets, totalSupply(), newTotalAssets - feeAssets, Math.Rounding.Floor);
File: MetaMorphoFactory.sol

4: import {EventsLib} from "./libraries/EventsLib.sol";

4: import {EventsLib} from "./libraries/EventsLib.sol";

5: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

5: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {MetaMorpho} from "./MetaMorpho.sol";
File: interfaces/IMetaMorpho.sol

4: import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {IMorpho, Id, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

5: import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

5: import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

5: import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

5: import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

5: import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

5: import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

5: import {IERC4626} from "../../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {IERC20Permit} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

8: import {MarketConfig, PendingUint192, PendingAddress} from "../libraries/PendingLib.sol";

8: import {MarketConfig, PendingUint192, PendingAddress} from "../libraries/PendingLib.sol";
File: interfaces/IMorphoMarketParams.sol

4: import {MarketParams, Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {MarketParams, Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {MarketParams, Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {MarketParams, Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {MarketParams, Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {MarketParams, Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {MarketParams, Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";
File: libraries/ErrorsLib.sol

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";
File: libraries/EventsLib.sol

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

4: import {Id} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

6: import {PendingAddress} from "./PendingLib.sol";

[GAS-4] 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.

Instances (16):

File: MetaMorpho.sol

186:     function setCurator(address newCurator) external onlyOwner {

195:     function setIsAllocator(address newAllocator, bool newIsAllocator) external onlyOwner {

204:     function setSkimRecipient(address newSkimRecipient) external onlyOwner {

215:     function submitTimelock(uint256 newTimelock) external onlyOwner {

233:     function setFee(uint256 newFee) external onlyOwner {

248:     function setFeeRecipient(address newFeeRecipient) external onlyOwner {

265:     function submitGuardian(address newGuardian) external onlyOwner {

286:     function submitCap(MarketParams memory marketParams, uint256 newSupplyCap) external onlyCuratorRole {

308:     function submitMarketRemoval(Id id) external onlyCuratorRole {

325:     function setSupplyQueue(Id[] calldata newSupplyQueue) external onlyAllocatorRole {

346:     function updateWithdrawQueue(uint256[] calldata indexes) external onlyAllocatorRole {

397:     function reallocate(MarketAllocation[] calldata allocations) external onlyAllocatorRole {

451:     function revokePendingTimelock() external onlyGuardianRole {

460:     function revokePendingGuardian() external onlyGuardianRole {

469:     function revokePendingCap(Id id) external onlyCuratorOrGuardianRole {

478:     function revokePendingMarketRemoval(Id id) external onlyCuratorOrGuardianRole {

[GAS-5] Use != 0 instead of > 0 for unsigned integer comparison

Instances (6):

File: MetaMorpho.sol

407:             if (withdrawn > 0) {

769:         if (supplyCap > 0) {

809:             if (toSupply > 0) {

833:             if (toWithdraw > 0) {
File: interfaces/IMetaMorpho.sol

2: pragma solidity >=0.5.0;
File: interfaces/IMorphoMarketParams.sol

2: pragma solidity >=0.5.0;

Low Issues

Issue Instances
L-1 Empty Function Body - Consider commenting why 2
L-2 Unspecific compiler version pragma 2

[L-1] Empty Function Body - Consider commenting why

Instances (2):

File: MetaMorpho.sol

813:                 } catch {}

837:                 } catch {}

[L-2] Unspecific compiler version pragma

Instances (2):

File: interfaces/IMetaMorpho.sol

2: pragma solidity >=0.5.0;
File: interfaces/IMorphoMarketParams.sol

2: pragma solidity >=0.5.0;

Medium Issues

Issue Instances
M-1 Centralization Risk for trusted owners 12

[M-1] Centralization Risk for trusted owners

Impact:

Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds.

Instances (12):

File: MetaMorpho.sol

28: import {Ownable2Step, Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";

43: contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorphoStaticTyping {

125:     ) ERC4626(IERC20(_asset)) ERC20Permit(_name) ERC20(_name, _symbol) Ownable(owner) {

186:     function setCurator(address newCurator) external onlyOwner {

195:     function setIsAllocator(address newAllocator, bool newIsAllocator) external onlyOwner {

204:     function setSkimRecipient(address newSkimRecipient) external onlyOwner {

215:     function submitTimelock(uint256 newTimelock) external onlyOwner {

233:     function setFee(uint256 newFee) external onlyOwner {

248:     function setFeeRecipient(address newFeeRecipient) external onlyOwner {

265:     function submitGuardian(address newGuardian) external onlyOwner {
File: interfaces/IMetaMorpho.sol

22: interface IOwnable {

91: interface IMetaMorpho is IMetaMorphoBase, IERC4626, IERC20Permit, IOwnable, IMulticall {

Report

Gas Optimizations

Issue Instances
GAS-1 Cache array length outside of loop 1
GAS-2 For Operations that will not overflow, you could use unchecked 239
GAS-3 Use != 0 instead of > 0 for unsigned integer comparison 17

[GAS-1] Cache array length outside of loop

If not cached, the solidity compiler will always read the length of the array during each iteration. That is, if it is a storage array, this is an extra sload operation (100 additional extra gas for each iteration except for the first) and if it is a memory array, this is an extra mload operation (3 additional gas for each iteration except for the first).

Instances (1):

File: BaseBundler.sol

66:         for (uint256 i; i < data.length; ++i) {

[GAS-2] For Operations that will not overflow, you could use unchecked

Instances (239):

File: BaseBundler.sol

4: import {IMulticall} from "./interfaces/IMulticall.sol";

4: import {IMulticall} from "./interfaces/IMulticall.sol";

6: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

6: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {UNSET_INITIATOR} from "./libraries/ConstantsLib.sol";

7: import {UNSET_INITIATOR} from "./libraries/ConstantsLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

66:         for (uint256 i; i < data.length; ++i) {

66:         for (uint256 i; i < data.length; ++i) {

80:         assembly ("memory-safe") {
File: ERC4626Bundler.sol

4: import {IERC4626} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

4: import {IERC4626} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

4: import {IERC4626} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

4: import {IERC4626} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

4: import {IERC4626} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

4: import {IERC4626} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

10: import {BaseBundler} from "./BaseBundler.sol";
File: MorphoBundler.sol

4: import {IMorphoBundler} from "./interfaces/IMorphoBundler.sol";

4: import {IMorphoBundler} from "./interfaces/IMorphoBundler.sol";

5: import {MarketParams, Signature, Authorization, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

5: import {MarketParams, Signature, Authorization, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

5: import {MarketParams, Signature, Authorization, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

5: import {MarketParams, Signature, Authorization, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

5: import {MarketParams, Signature, Authorization, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

5: import {MarketParams, Signature, Authorization, IMorpho} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

10: import {BaseBundler} from "./BaseBundler.sol";
File: Permit2Bundler.sol

4: import {IAllowanceTransfer} from "../lib/permit2/src/interfaces/IAllowanceTransfer.sol";

4: import {IAllowanceTransfer} from "../lib/permit2/src/interfaces/IAllowanceTransfer.sol";

4: import {IAllowanceTransfer} from "../lib/permit2/src/interfaces/IAllowanceTransfer.sol";

4: import {IAllowanceTransfer} from "../lib/permit2/src/interfaces/IAllowanceTransfer.sol";

4: import {IAllowanceTransfer} from "../lib/permit2/src/interfaces/IAllowanceTransfer.sol";

6: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

6: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

8: import {Permit2Lib} from "../lib/permit2/src/libraries/Permit2Lib.sol";

8: import {Permit2Lib} from "../lib/permit2/src/libraries/Permit2Lib.sol";

8: import {Permit2Lib} from "../lib/permit2/src/libraries/Permit2Lib.sol";

8: import {Permit2Lib} from "../lib/permit2/src/libraries/Permit2Lib.sol";

8: import {Permit2Lib} from "../lib/permit2/src/libraries/Permit2Lib.sol";

9: import {SafeCast160} from "../lib/permit2/src/libraries/SafeCast160.sol";

9: import {SafeCast160} from "../lib/permit2/src/libraries/SafeCast160.sol";

9: import {SafeCast160} from "../lib/permit2/src/libraries/SafeCast160.sol";

9: import {SafeCast160} from "../lib/permit2/src/libraries/SafeCast160.sol";

9: import {SafeCast160} from "../lib/permit2/src/libraries/SafeCast160.sol";

10: import {ERC20} from "../lib/solmate/src/tokens/ERC20.sol";

10: import {ERC20} from "../lib/solmate/src/tokens/ERC20.sol";

10: import {ERC20} from "../lib/solmate/src/tokens/ERC20.sol";

10: import {ERC20} from "../lib/solmate/src/tokens/ERC20.sol";

10: import {ERC20} from "../lib/solmate/src/tokens/ERC20.sol";

12: import {BaseBundler} from "./BaseBundler.sol";
File: PermitBundler.sol

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

4: import {IERC20Permit} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol";

6: import {BaseBundler} from "./BaseBundler.sol";
File: StEthBundler.sol

4: import {IWstEth} from "./interfaces/IWstEth.sol";

4: import {IWstEth} from "./interfaces/IWstEth.sol";

5: import {IStEth} from "./interfaces/IStEth.sol";

5: import {IStEth} from "./interfaces/IStEth.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

8: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

8: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

9: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

9: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

9: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

9: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

9: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

11: import {BaseBundler} from "./BaseBundler.sol";
File: TransferBundler.sol

4: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

4: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

4: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

4: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

4: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

4: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

5: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

5: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

6: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

6: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

6: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

6: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

6: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {BaseBundler} from "./BaseBundler.sol";
File: UrdBundler.sol

5:     "../lib/universal-rewards-distributor/src/interfaces/IUniversalRewardsDistributor.sol";

5:     "../lib/universal-rewards-distributor/src/interfaces/IUniversalRewardsDistributor.sol";

5:     "../lib/universal-rewards-distributor/src/interfaces/IUniversalRewardsDistributor.sol";

5:     "../lib/universal-rewards-distributor/src/interfaces/IUniversalRewardsDistributor.sol";

5:     "../lib/universal-rewards-distributor/src/interfaces/IUniversalRewardsDistributor.sol";

5:     "../lib/universal-rewards-distributor/src/interfaces/IUniversalRewardsDistributor.sol";

5:     "../lib/universal-rewards-distributor/src/interfaces/IUniversalRewardsDistributor.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

9: import {BaseBundler} from "./BaseBundler.sol";
File: WNativeBundler.sol

4: import {IWNative} from "./interfaces/IWNative.sol";

4: import {IWNative} from "./interfaces/IWNative.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../lib/morpho-utils/src/math/Math.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

10: import {BaseBundler} from "./BaseBundler.sol";
File: ethereum/EthereumBundler.sol

4: import {MainnetLib} from "./libraries/MainnetLib.sol";

4: import {MainnetLib} from "./libraries/MainnetLib.sol";

6: import {BaseBundler} from "../BaseBundler.sol";

7: import {TransferBundler} from "../TransferBundler.sol";

8: import {EthereumPermitBundler} from "./EthereumPermitBundler.sol";

9: import {Permit2Bundler} from "../Permit2Bundler.sol";

10: import {ERC4626Bundler} from "../ERC4626Bundler.sol";

11: import {WNativeBundler} from "../WNativeBundler.sol";

12: import {EthereumStEthBundler} from "./EthereumStEthBundler.sol";

13: import {UrdBundler} from "../UrdBundler.sol";

14: import {MorphoBundler} from "../MorphoBundler.sol";

15: import {ERC20WrapperBundler} from "../ERC20WrapperBundler.sol";
File: ethereum/EthereumPermitBundler.sol

4: import {IDaiPermit} from "./interfaces/IDaiPermit.sol";

4: import {IDaiPermit} from "./interfaces/IDaiPermit.sol";

6: import {MainnetLib} from "./libraries/MainnetLib.sol";

6: import {MainnetLib} from "./libraries/MainnetLib.sol";

8: import {PermitBundler} from "../PermitBundler.sol";
File: ethereum/EthereumStEthBundler.sol

4: import {MainnetLib} from "./libraries/MainnetLib.sol";

4: import {MainnetLib} from "./libraries/MainnetLib.sol";

6: import {StEthBundler} from "../StEthBundler.sol";
File: interfaces/IMorphoBundler.sol

9: } from "../../lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol";

9: } from "../../lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol";

9: } from "../../lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol";

9: } from "../../lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol";

9: } from "../../lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol";

9: } from "../../lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol";

9: } from "../../lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol";
File: migration/AaveV2MigrationBundler.sol

4: import {IAaveV2} from "./interfaces/IAaveV2.sol";

4: import {IAaveV2} from "./interfaces/IAaveV2.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

7: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

9: import {BaseBundler} from "../BaseBundler.sol";

10: import {StEthBundler} from "../StEthBundler.sol";

11: import {MigrationBundler, ERC20} from "./MigrationBundler.sol";
File: migration/AaveV3MigrationBundler.sol

4: import {IAaveV3} from "./interfaces/IAaveV3.sol";

4: import {IAaveV3} from "./interfaces/IAaveV3.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

7: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

9: import {MigrationBundler, ERC20} from "./MigrationBundler.sol";
File: migration/CompoundV2MigrationBundler.sol

4: import {ICEth} from "./interfaces/ICEth.sol";

4: import {ICEth} from "./interfaces/ICEth.sol";

5: import {ICToken} from "./interfaces/ICToken.sol";

5: import {ICToken} from "./interfaces/ICToken.sol";

7: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

8: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

8: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

10: import {BaseBundler} from "../BaseBundler.sol";

11: import {WNativeBundler} from "../WNativeBundler.sol";

12: import {MigrationBundler, ERC20} from "./MigrationBundler.sol";
File: migration/CompoundV3MigrationBundler.sol

4: import {ICompoundV3} from "./interfaces/ICompoundV3.sol";

4: import {ICompoundV3} from "./interfaces/ICompoundV3.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

6: import {Math} from "../../lib/morpho-utils/src/math/Math.sol";

7: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

7: import {ErrorsLib} from "../libraries/ErrorsLib.sol";

9: import {MigrationBundler, ERC20} from "./MigrationBundler.sol";
File: migration/MigrationBundler.sol

4: import {SafeTransferLib, ERC20} from "../../lib/solmate/src/utils/SafeTransferLib.sol";

4: import {SafeTransferLib, ERC20} from "../../lib/solmate/src/utils/SafeTransferLib.sol";

4: import {SafeTransferLib, ERC20} from "../../lib/solmate/src/utils/SafeTransferLib.sol";

4: import {SafeTransferLib, ERC20} from "../../lib/solmate/src/utils/SafeTransferLib.sol";

4: import {SafeTransferLib, ERC20} from "../../lib/solmate/src/utils/SafeTransferLib.sol";

4: import {SafeTransferLib, ERC20} from "../../lib/solmate/src/utils/SafeTransferLib.sol";

6: import {BaseBundler} from "../BaseBundler.sol";

7: import {TransferBundler} from "../TransferBundler.sol";

8: import {PermitBundler} from "../PermitBundler.sol";

9: import {Permit2Bundler} from "../Permit2Bundler.sol";

10: import {ERC4626Bundler} from "../ERC4626Bundler.sol";

11: import {MorphoBundler} from "../MorphoBundler.sol";

[GAS-3] Use != 0 instead of > 0 for unsigned integer comparison

Instances (17):

File: BaseBundler.sol

78:         require(length > 0, ErrorsLib.CALL_FAILED);
File: MorphoBundler.sol

109:         if (assets > 0) require(suppliedShares >= slippageAmount, ErrorsLib.SLIPPAGE_EXCEEDED);

159:         if (assets > 0) require(borrowedShares <= slippageAmount, ErrorsLib.SLIPPAGE_EXCEEDED);

193:         if (assets > 0) require(repaidShares >= slippageAmount, ErrorsLib.SLIPPAGE_EXCEEDED);

218:         if (assets > 0) require(withdrawnShares <= slippageAmount, ErrorsLib.SLIPPAGE_EXCEEDED);
File: ethereum/interfaces/IDaiPermit.sol

2: pragma solidity >=0.5.0;
File: interfaces/IMorphoBundler.sol

2: pragma solidity >=0.5.0;
File: interfaces/IMulticall.sol

2: pragma solidity >=0.5.0;
File: interfaces/IStEth.sol

2: pragma solidity >=0.5.0;
File: interfaces/IWNative.sol

2: pragma solidity >=0.5.0;
File: interfaces/IWstEth.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/IAaveV2.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/IAaveV3.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/ICEth.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/ICToken.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/ICompoundV3.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/IComptroller.sol

2: pragma solidity >=0.5.0;

Low Issues

Issue Instances
L-1 Do not use deprecated library functions 2
L-2 Empty Function Body - Consider commenting why 12
L-3 Unsafe ERC20 operation(s) 1
L-4 Unspecific compiler version pragma 12

[L-1] Do not use deprecated library functions

Instances (2):

File: BaseBundler.sol

95:             ERC20(asset).safeApprove(spender, type(uint256).max);
File: StEthBundler.sol

36:         ERC20(ST_ETH).safeApprove(WST_ETH, type(uint256).max);

[L-2] Empty Function Body - Consider commenting why

Instances (12):

File: MorphoBundler.sol

70:         try MORPHO.setAuthorizationWithSig(authorization, signature) {}
File: Permit2Bundler.sol

33:         try Permit2Lib.PERMIT2.permit(initiator(), permitSingle, signature) {}
File: PermitBundler.sol

27:         try IERC20Permit(asset).permit(initiator(), address(this), amount, deadline, v, r, s) {}
File: UrdBundler.sol

35:         try IUniversalRewardsDistributor(distributor).claim(account, reward, amount, proof) {}
File: WNativeBundler.sol

39:     receive() external payable {}
File: ethereum/EthereumBundler.sol

34:     constructor(address morpho) WNativeBundler(MainnetLib.WETH) MorphoBundler(morpho) {}
File: ethereum/EthereumPermitBundler.sol

29:         try IDaiPermit(MainnetLib.DAI).permit(initiator(), address(this), nonce, expiry, allowed, v, r, s) {}
File: ethereum/EthereumStEthBundler.sol

15:     constructor() StEthBundler(MainnetLib.WST_ETH) {}
File: interfaces/IMorphoBundler.sol

20: {}
File: migration/CompoundV3MigrationBundler.sol

19:     constructor(address morpho) MigrationBundler(morpho) {}

84:         try ICompoundV3(instance).allowBySig(initiator(), address(this), isAllowed, nonce, expiry, v, r, s) {}
File: migration/MigrationBundler.sol

22:     constructor(address morpho) MorphoBundler(morpho) {}

[L-3] Unsafe ERC20 operation(s)

Instances (1):

File: Permit2Bundler.sol

49:         Permit2Lib.PERMIT2.transferFrom(_initiator, address(this), amount.toUint160(), asset);

[L-4] Unspecific compiler version pragma

Instances (12):

File: ethereum/interfaces/IDaiPermit.sol

2: pragma solidity >=0.5.0;
File: interfaces/IMorphoBundler.sol

2: pragma solidity >=0.5.0;
File: interfaces/IMulticall.sol

2: pragma solidity >=0.5.0;
File: interfaces/IStEth.sol

2: pragma solidity >=0.5.0;
File: interfaces/IWNative.sol

2: pragma solidity >=0.5.0;
File: interfaces/IWstEth.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/IAaveV2.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/IAaveV3.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/ICEth.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/ICToken.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/ICompoundV3.sol

2: pragma solidity >=0.5.0;
File: migration/interfaces/IComptroller.sol

2: pragma solidity >=0.5.0;

High Issues

Issue Instances
H-1 Using delegatecall inside a loop 1

[H-1] Using delegatecall inside a loop

Impact:

When calling delegatecall the same msg.value amount will be accredited multiple times.

Instances (1):

File: BaseBundler.sol

66:         for (uint256 i; i < data.length; ++i) {
# Report
## Gas Optimizations
| |Issue|Instances|
|-|:-|:-:|
| [GAS-1](#GAS-1) | For Operations that will not overflow, you could use unchecked | 63 |
| [GAS-2](#GAS-2) | Using `private` rather than `public` for constants, saves gas | 2 |
| [GAS-3](#GAS-3) | Use != 0 instead of > 0 for unsigned integer comparison | 2 |
| [GAS-4](#GAS-4) | `internal` functions not called by the contract should be removed | 4 |
### <a name="GAS-1"></a>[GAS-1] For Operations that will not overflow, you could use unchecked
*Instances (63)*:
```solidity
File: SpeedJumpIrm.sol
4: import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol";
4: import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol";
4: import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol";
4: import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol";
4: import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol";
4: import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol";
6: import {MathLib} from "./libraries/MathLib.sol";
6: import {MathLib} from "./libraries/MathLib.sol";
7: import {UtilsLib} from "./libraries/UtilsLib.sol";
7: import {UtilsLib} from "./libraries/UtilsLib.sol";
8: import {ErrorsLib} from "./libraries/ErrorsLib.sol";
8: import {ErrorsLib} from "./libraries/ErrorsLib.sol";
9: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
9: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
9: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
9: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
9: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
9: import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
10: import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";
10: import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";
10: import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";
10: import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";
10: import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";
10: import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";
11: import {WAD, MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
11: import {WAD, MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
11: import {WAD, MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
11: import {WAD, MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
11: import {WAD, MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
11: import {WAD, MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
40: uint256 public constant MAX_RATE = uint256(1e7 ether) / 365 days;
42: uint256 public constant MIN_RATE = uint256(0.001 ether) / 365 days;
117: uint256 errNormFactor = utilization > TARGET_UTILIZATION ? WAD - TARGET_UTILIZATION : TARGET_UTILIZATION;
120: int128 err = int128((int256(utilization) - int256(TARGET_UTILIZATION)).wDivDown(int256(errNormFactor)));
127: int256 errDelta = err - irm.prevErr;
133: uint256 elapsed = block.timestamp - market.lastUpdate;
135: int256 linearVariation = speed * int256(elapsed);
150: else avgBorrowRate = uint256((int256(newBorrowRate) - int256(borrowRateAfterJump)).wDivDown(linearVariation));
```
```solidity
File: libraries/MathLib.sol
4: import {ErrorsLib} from "./ErrorsLib.sol";
5: import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol";
5: import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol";
5: import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol";
5: import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol";
5: import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol";
5: import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol";
5: import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol";
28: require(x >= type(int256).min + LN2_INT / 2, ErrorsLib.WEXP_UNDERFLOW);
28: require(x >= type(int256).min + LN2_INT / 2, ErrorsLib.WEXP_UNDERFLOW);
32: int256 roundingAdjustment = (x < 0) ? -(LN2_INT / 2) : (LN2_INT / 2);
32: int256 roundingAdjustment = (x < 0) ? -(LN2_INT / 2) : (LN2_INT / 2);
32: int256 roundingAdjustment = (x < 0) ? -(LN2_INT / 2) : (LN2_INT / 2);
34: int256 q = (x + roundingAdjustment) / LN2_INT;
34: int256 q = (x + roundingAdjustment) / LN2_INT;
36: int256 r = x - q * LN2_INT;
36: int256 r = x - q * LN2_INT;
40: uint256 expR = uint256(WAD_INT + r + r.wMulDown(r) / 2);
40: uint256 expR = uint256(WAD_INT + r + r.wMulDown(r) / 2);
40: uint256 expR = uint256(WAD_INT + r + r.wMulDown(r) / 2);
44: else return expR >> uint256(-q);
49: return a * b / WAD_INT;
49: return a * b / WAD_INT;
53: return a * WAD_INT / b;
53: return a * WAD_INT / b;
```
### <a name="GAS-2"></a>[GAS-2] Using `private` rather than `public` for constants, saves gas
If needed, the values can be read from the verified contract source code, or if there are multiple values there can be a single getter function that [returns a tuple](https://github.com/code-423n4/2022-08-frax/blob/90f55a9ce4e25bceed3a74290b854341d8de6afa/src/contracts/FraxlendPair.sol#L156-L178) of the values of all currently-public constants. Saves **3406-3606 gas** in deployment gas due to the compiler not having to create non-payable getter functions for deployment calldata, not having to store the bytes of the value outside of where it's used, and not adding another entry to the method ID table
*Instances (2)*:
```solidity
File: SpeedJumpIrm.sol
40: uint256 public constant MAX_RATE = uint256(1e7 ether) / 365 days;
42: uint256 public constant MIN_RATE = uint256(0.001 ether) / 365 days;
```
### <a name="GAS-3"></a>[GAS-3] Use != 0 instead of > 0 for unsigned integer comparison
*Instances (2)*:
```solidity
File: SpeedJumpIrm.sol
79: require(targetUtilization > 0, ErrorsLib.ZERO_INPUT);
115: market.totalSupplyAssets > 0 ? market.totalBorrowAssets.wDivDown(market.totalSupplyAssets) : 0;
```
### <a name="GAS-4"></a>[GAS-4] `internal` functions not called by the contract should be removed
If the functions are required by an interface, the contract should inherit from that interface and use the `override` keyword
*Instances (4)*:
```solidity
File: libraries/MathLib.sol
23: function wExp(int256 x) internal pure returns (uint256) {
48: function wMulDown(int256 a, int256 b) internal pure returns (int256) {
52: function wDivDown(int256 a, int256 b) internal pure returns (int256) {
```
```solidity
File: libraries/UtilsLib.sol
11: function bound(uint256 x, uint256 low, uint256 high) internal pure returns (uint256 z) {
```

Report

Gas Optimizations

Issue Instances
GAS-1 Use assembly to check for address(0) 3
GAS-2 For Operations that will not overflow, you could use unchecked 34
GAS-3 internal functions not called by the contract should be removed 3

[GAS-1] Use assembly to check for address(0)

Saves 6 gas per instance

Instances (3):

File: libraries/ChainlinkDataFeedLib.sol

21:         if (address(feed) == address(0)) return 1;

32:         if (address(feed) == address(0)) return 0;
File: libraries/VaultLib.sol

14:         if (address(vault) == address(0)) return 1;

[GAS-2] For Operations that will not overflow, you could use unchecked

Instances (34):

File: ChainlinkOracle.sol

4: import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";

4: import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";

4: import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";

4: import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";

4: import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";

4: import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";

6: import {AggregatorV3Interface, ChainlinkDataFeedLib} from "./libraries/ChainlinkDataFeedLib.sol";

6: import {AggregatorV3Interface, ChainlinkDataFeedLib} from "./libraries/ChainlinkDataFeedLib.sol";

7: import {IERC4626, VaultLib} from "./libraries/VaultLib.sol";

7: import {IERC4626, VaultLib} from "./libraries/VaultLib.sol";

8: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

8: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

9: import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";

9: import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";

9: import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";

9: import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";

9: import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";

9: import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";

9: import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";

108:                 36 + quoteTokenDecimals + quoteFeed1.getDecimals() + quoteFeed2.getDecimals() - baseTokenDecimals

108:                 36 + quoteTokenDecimals + quoteFeed1.getDecimals() + quoteFeed2.getDecimals() - baseTokenDecimals

108:                 36 + quoteTokenDecimals + quoteFeed1.getDecimals() + quoteFeed2.getDecimals() - baseTokenDecimals

108:                 36 + quoteTokenDecimals + quoteFeed1.getDecimals() + quoteFeed2.getDecimals() - baseTokenDecimals

109:                     - baseFeed1.getDecimals() - baseFeed2.getDecimals()

109:                     - baseFeed1.getDecimals() - baseFeed2.getDecimals()

110:             ) / vaultConversionSample;

118:             VAULT.getAssets(VAULT_CONVERSION_SAMPLE) * BASE_FEED_1.getPrice() * BASE_FEED_2.getPrice(),

118:             VAULT.getAssets(VAULT_CONVERSION_SAMPLE) * BASE_FEED_1.getPrice() * BASE_FEED_2.getPrice(),

119:             QUOTE_FEED_1.getPrice() * QUOTE_FEED_2.getPrice()
File: libraries/ChainlinkDataFeedLib.sol

4: import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol";

4: import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol";

6: import {ErrorsLib} from "./ErrorsLib.sol";
File: libraries/VaultLib.sol

4: import {IERC4626} from "../interfaces/IERC4626.sol";

4: import {IERC4626} from "../interfaces/IERC4626.sol";

[GAS-3] internal functions not called by the contract should be removed

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

Instances (3):

File: libraries/ChainlinkDataFeedLib.sol

20:     function getPrice(AggregatorV3Interface feed) internal view returns (uint256) {

31:     function getDecimals(AggregatorV3Interface feed) internal view returns (uint256) {
File: libraries/VaultLib.sol

13:     function getAssets(IERC4626 vault, uint256 shares) internal view returns (uint256) {

Report

Gas Optimizations

Issue Instances
GAS-1 Using bools for storage incurs overhead 2
GAS-2 Use calldata instead of memory for function arguments that do not get mutated 1
GAS-3 For Operations that will not overflow, you could use unchecked 23
GAS-4 Functions guaranteed to revert when called by normal users can be marked payable 6
GAS-5 Use != 0 instead of > 0 for unsigned integer comparison 1

[GAS-1] Using bools for storage incurs overhead

Use uint256(1) and uint256(2) for true/false to avoid a Gwarmaccess (100 gas), and to avoid Gsset (20000 gas) when changing from ‘false’ to ‘true’, after having been ‘true’ in the past. See source.

Instances (2):

File: UniversalRewardsDistributor.sol

36:     mapping(address => bool) public isUpdater;
File: UrdFactory.sol

15:     mapping(address => bool) public isUrd;

[GAS-2] Use calldata instead of memory for function arguments that do not get mutated

Mark data types as calldata instead of memory where possible. This makes it so that the data is not automatically loaded into memory. If the data passed into the function does not need to be changed (like updating values in an array), it can be passed in as calldata. The one exception to this is if the argument must later be passed into another function that takes an argument that specifies memory storage.

Instances (1):

File: interfaces/IUniversalRewardsDistributor.sol

34:     function claim(address account, address reward, uint256 claimable, bytes32[] memory proof)

[GAS-3] For Operations that will not overflow, you could use unchecked

Instances (23):

File: UniversalRewardsDistributor.sol

4: import {PendingRoot, IUniversalRewardsDistributorStaticTyping} from "./interfaces/IUniversalRewardsDistributor.sol";

4: import {PendingRoot, IUniversalRewardsDistributorStaticTyping} from "./interfaces/IUniversalRewardsDistributor.sol";

6: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

6: import {ErrorsLib} from "./libraries/ErrorsLib.sol";

7: import {EventsLib} from "./libraries/EventsLib.sol";

7: import {EventsLib} from "./libraries/EventsLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

8: import {SafeTransferLib, ERC20} from "../lib/solmate/src/utils/SafeTransferLib.sol";

10: import {MerkleProof} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

10: import {MerkleProof} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

10: import {MerkleProof} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

10: import {MerkleProof} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

10: import {MerkleProof} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

10: import {MerkleProof} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

10: import {MerkleProof} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

83:         pendingRoot = PendingRoot({root: newRoot, ipfsHash: newIpfsHash, validAt: block.timestamp + timelock});

129:         amount = claimable - claimed[account][reward];
File: UrdFactory.sol

4: import {EventsLib} from "./libraries/EventsLib.sol";

4: import {EventsLib} from "./libraries/EventsLib.sol";

6: import {UniversalRewardsDistributor} from "./UniversalRewardsDistributor.sol";

[GAS-4] 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.

Instances (6):

File: UniversalRewardsDistributor.sol

80:     function submitRoot(bytes32 newRoot, bytes32 newIpfsHash) external onlyUpdaterRole {

100:     function revokePendingRoot() external onlyUpdaterRole {

143:     function setRoot(bytes32 newRoot, bytes32 newIpfsHash) external onlyUpdaterRole {

154:     function setTimelock(uint256 newTimelock) external onlyOwner {

163:     function setRootUpdater(address updater, bool active) external onlyOwner {

172:     function setOwner(address newOwner) external onlyOwner {

[GAS-5] Use != 0 instead of > 0 for unsigned integer comparison

Instances (1):

File: interfaces/IUniversalRewardsDistributor.sol

2: pragma solidity >=0.5.0;

Non Critical Issues

Issue Instances
NC-1 Event is missing indexed fields 3

[NC-1] Event is missing indexed fields

Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.

Instances (3):

File: libraries/EventsLib.sol

25:     event TimelockSet(uint256 newTimelock);

30:     event RootUpdaterSet(address indexed rootUpdater, bool active);

36:     event Claimed(address indexed account, address indexed reward, uint256 amount);

Low Issues

Issue Instances
L-1 Unspecific compiler version pragma 1

[L-1] Unspecific compiler version pragma

Instances (1):

File: interfaces/IUniversalRewardsDistributor.sol

2: pragma solidity >=0.5.0;

Medium Issues

Issue Instances
M-1 Centralization Risk for trusted owners 3

[M-1] Centralization Risk for trusted owners

Impact:

Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds.

Instances (3):

File: UniversalRewardsDistributor.sol

154:     function setTimelock(uint256 newTimelock) external onlyOwner {

163:     function setRootUpdater(address updater, bool active) external onlyOwner {

172:     function setOwner(address newOwner) external onlyOwner {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment