You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
[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(addressnewCurator) external onlyOwner {
195: function setIsAllocator(addressnewAllocator, boolnewIsAllocator) external onlyOwner {
204: function setSkimRecipient(addressnewSkimRecipient) external onlyOwner {
215: function submitTimelock(uint256newTimelock) external onlyOwner {
233: function setFee(uint256newFee) external onlyOwner {
248: function setFeeRecipient(addressnewFeeRecipient) external onlyOwner {
265: function submitGuardian(addressnewGuardian) external onlyOwner {
286: function submitCap(MarketParams memorymarketParams, uint256newSupplyCap) external onlyCuratorRole {
308: function submitMarketRemoval(Id id) external onlyCuratorRole {
325: function setSupplyQueue(Id[] calldatanewSupplyQueue) external onlyAllocatorRole {
346: function updateWithdrawQueue(uint256[] calldataindexes) external onlyAllocatorRole {
397: function reallocate(MarketAllocation[] calldataallocations) 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) {
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### <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
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(addressaccount, addressreward, uint256claimable, bytes32[] memoryproof)
[GAS-3] For Operations that will not overflow, you could use unchecked
[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(bytes32newRoot, bytes32newIpfsHash) external onlyUpdaterRole {
100: function revokePendingRoot() external onlyUpdaterRole {
143: function setRoot(bytes32newRoot, bytes32newIpfsHash) external onlyUpdaterRole {
154: function setTimelock(uint256newTimelock) external onlyOwner {
163: function setRootUpdater(addressupdater, boolactive) external onlyOwner {
172: function setOwner(addressnewOwner) external onlyOwner {
[GAS-5] Use != 0 instead of > 0 for unsigned integer comparison
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.