Platform: Code4rena
Start Date: 21/10/2021
Pot Size: $80,000 ETH
Total HM: 28
Participants: 15
Period: 7 days
Judge: ghoulsol
Total Solo HM: 19
Id: 42
League: ETH
Rank: 13/15
Findings: 1
Award: $287.60
🌟 Selected for report: 1
🚀 Solo Findings: 0
0x0x0x
getLiquidity()
should be external
In mochi-cssr/contracts/MochiCSSRv0.sol#126-137
, the function getLiquidity
is declared as a public
function. This function should be defined as external
for gas optimization. Public functions copy the inputs to memory, while external functions read them directly from calldata. Therefore, there is a difference in amount of gas consumed.
Manual analysis
#0 - r2moon
2021-10-29T13:05:47Z
duplicated with https://github.com/code-423n4/2021-10-mochi-findings/issues/164
0.0345 ETH - $143.80
0x0x0x
Gas optimization.
for (uint i = 0; i < arr.length; i++) { //Operations not effecting the length of the array. }
Loading length for storage arrays cost 100 gas and for memory arrays it costs 3 gas. When arr.length is defined as the condition of for loop, at the start of every iteration the length is loaded from memory. If the length doesn't change during the loop, loading the length of arrays repeatedly can be avoided by saving the length to the stack.
uint length = arr.length; for (uint i = 0; i < length; i++) { //Operations not effecting the length of the array. }
By doing so the length is only loaded once rather than loading it as many times as iterations (Therefore, less gas is spent).
./mochi-core/contracts/profile/MochiProfileV0.sol:68: for (uint256 i = 0; i < _asset.length; i++) { ./mochi-core/contracts/profile/MochiProfileV0.sol:86: for (uint256 i = 0; i < _assets.length; i++) { ./mochi-core/contracts/profile/MochiProfileV0.sol:95: for (uint256 i = 0; i < _assets.length; i++) { ./mochi-cssr/contracts/MochiCSSRv0.sol:41: for(uint256 i = 0; i<_assets.length; i++){ ./mochi-cssr/contracts/MochiCSSRv0.sol:47: for(uint256 i = 0; i<_assets.length; i++){ ./mochi-cssr/contracts/MochiCSSRv0.sol:66: for(uint256 i = 0; i<_assets.length; i++){ ./mochi-cssr/contracts/MochiCSSRv0.sol:77: for(uint256 i = 0; i<_assets.length; i++){ ./mochi-cssr/contracts/adapter/ChainlinkAdapter.sol:34: for(uint256 i = 0; i<_assets.length; i++) { ./mochi-cssr/contracts/adapter/UniswapV2TokenAdapter.sol:63: for (uint256 i = 0; i < keyCurrency.length; i++) { ./mochi-cssr/contracts/adapter/UniswapV2TokenAdapter.sol:122: for (uint256 i = 0; i < keyCurrency.length; i++) { ./mochi-cssr/contracts/adapter/UniswapV2TokenAdapter.sol:175: for (uint256 i = 0; i < keyCurrency.length; i++) { ./mochi-library/contracts/MerklePatriciaVerifier.sol:36: for (uint i=0; i<parentNodes.length; i++) { ./mochi-library/contracts/MerklePatriciaVerifier.sol:78: for(uint i=pathPtr; i<pathPtr+partialPath.length; i++) { ./mochi-library/contracts/MerklePatriciaVerifier.sol:108: for(uint i=offset; i<nibbleArray.length; i++) { ./mochi-library/contracts/SushiswapV2Library.sol:66: for (uint i; i < path.length - 1; i++) { ./mochi-library/contracts/SushiswapV2Library.sol:77: for (uint i = path.length - 1; i > 0; i--) { ./mochi-library/contracts/UniswapV2Library.sol:66: for (uint i; i < path.length - 1; i++) { ./mochi-library/contracts/UniswapV2Library.sol:77: for (uint i = path.length - 1; i > 0; i--) {
nibblePath.length is constant but it is read at every iteration for require statement.
./mochi-library/contracts/MerklePatriciaVerifier.sol:36: require(pathPtr <= nibblePath.length, "Path overflow");