/**
* @notice Mapping that stores constants for pooledCredit creditLine against it's id
*/
mapping(uint256 => LenderPoolConstants) public pooledCLConstants;
/**
* @notice Mapping that stores variables for pooledCredit creditLine against it's id
*/
mapping(uint256 => LenderPoolVariables) public pooledCLVariables;
/**
* @notice Mapping that stores total pooledCreditLine token supply against the creditLineId
* @dev Since ERC1155 tokens don't support the totalSupply function it is maintained here
*/
mapping(uint256 => uint256) public totalSupply;
/**
* @notice stores the collateral shares in a pooled credit line per collateral strategy
* @dev creditLineId => collateralShares
**/
mapping(uint256 => uint256) public depositedCollateralInShares;
/**
* @notice stores the variables to maintain a pooled credit line
**/
mapping(uint256 => PooledCreditLineVariables) public pooledCreditLineVariables;
/**
* @notice stores the constants related to a pooled credit line
**/
mapping(uint256 => PooledCreditLineConstants) public pooledCreditLineConstants;
++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
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
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.
Less obvious 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, or having local caches of state variable contracts/addresses.
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.
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.
Multiple mappings can be combined into a single mapping of a value to a struct
File: contracts/PooledCreditLine/PooledCreditLine.sol (lines 184-198)
++i
/i++
should beunchecked{++i}
/unchecked{++i}
when it is not possible for them to overflow, as is the case when used infor
- andwhile
-loops<array>.length
should not be looked up in every loop of afor
-loopEven memory arrays incur the overhead of bit tests and bit shifts to calculate the array length
Using
calldata
instead ofmemory
for read-only arguments inexternal
functions saves gasinternal
functions only called once can be inlined to save gasMultiple
if
-statements with mutually-exclusive conditions should be changed toif
-else
statementsIf two conditions are the same, their blocks should be combined
File: contracts/PooledCreditLine/LenderPool.sol (lines 676-688)
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 thanrevert()/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 valueSplitting
require()
statements that use&&
saves gasSee this issue for an example
require()
orrevert()
statements that check input arguments should be at the top of the functionState 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. Less obvious 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, or having local caches of state variable contracts/addresses.
Usage of
uints
/ints
smaller than 32 bytes (256 bits) incurs overheadhttps://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size then downcast where needed
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 aspayable
will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided.