Platform: Code4rena
Start Date: 14/06/2022
Pot Size: $100,000 USDC
Total HM: 26
Participants: 59
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 9
Id: 133
League: ETH
Rank: 52/59
Findings: 1
Award: $105.36
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: _Adam
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xmint, Chom, Dravee, Fitraldys, Funen, JC, Limbooo, MadWookie, Picodes, Ruhum, TerrierLover, TomJ, Tomio, Waze, ak1, c3phas, catchup, defsec, fatherOfBlocks, gzeon, hake, hansfriese, joestakey, k, oyc_109, rfa, robee, sach1r0, saian, simon135, ynnad
41.2642 USDC - $41.26
396.9199 CANTO - $64.10
Title: Using calldata to store read only string and array arguments
Occurrences: https://github.com/Plex-Engineer/manifest/blob/cf88a30070689b71c2678642dc0fdfa1740f666c/contracts/Proposal-Store.sol#L46-L47 https://github.com/Plex-Engineer/manifest/blob/cf88a30070689b71c2678642dc0fdfa1740f666c/contracts/Proposal-Store.sol#L39-L40
Using calldata can save execution gas fee:
function AddProposal(uint propId, string calldata title, string calldata desc, address[] memory targets, uint[] calldata values, string[] calldata signatures, bytes[] calldata calldatas) public
Title: Function visibility can set to external
Occurrences: https://github.com/Plex-Engineer/manifest/blob/cf88a30070689b71c2678642dc0fdfa1740f666c/contracts/Proposal-Store.sol#L47 https://github.com/Plex-Engineer/manifest/blob/cf88a30070689b71c2678642dc0fdfa1740f666c/contracts/Proposal-Store.sol#L52
The function is never called in the same contract. Changing the visibility to external is more effective
Title: Returning default value
Returning default value is unnecessary, we can just remove L56 and let the function returning the 0 value by default. It can save 614 gas in case propId is not exist (and the function called from other contract)
Title: Use uint8 for _unlocked
Max value of _unlocked
is 2. We can change uint (uint256) with just smaller size uint (uint8)
Title: Using prefix increment and unchecked for i
inside for()
Using prefix increment and unchecked for i is the most effective way for doing iteration:
for (uint i = 0; i < _prices.length;) { priceAverageCumulative += _prices[i]; unchecked{++i;} }
Title: Effective way to return in sample()
function
By naming the returns() var with _prices
, we don't need to return _prices
in the last of function (which quite expensive because beside we declare new var at L219, we MSTORE all the _prices value into returns var).
Change to:
function sample(address tokenIn, uint amountIn, uint points, uint window) public view returns (uint[] memory _prices) { //@audit-info: Give the returns() name // @audit-info: remove L219 uint length = observations.length-1; uint i = length - (points * window); uint nextIndex = 0; uint index = 0; for (; i < length; i+=window) { nextIndex = i + window; uint timeElapsed = observations[nextIndex].timestamp - observations[i].timestamp; uint _reserve0 = (observations[nextIndex].reserve0Cumulative - observations[i].reserve0Cumulative) / timeElapsed; uint _reserve1 = (observations[nextIndex].reserve1Cumulative - observations[i].reserve1Cumulative) / timeElapsed; _prices[index] = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); index = index + 1; } //@audit-info: remove return statement }
By doing this way, we can save 119 gas (if length
== 1)
Title: Reading block.timestamp
blockTimestamp
var is used to return the value of current block.timestamp in currentCumulativePrices
function. We can just use block.timestamp to get current timestamp instead of calling blockTimestamp
var. it can save 2 gas
Change to:
if (_blockTimestampLast != block.timestamp) { // subtraction overflow is desired uint timeElapsed = block.timestamp - _blockTimestampLast; reserve0Cumulative += _reserve0 * timeElapsed; reserve1Cumulative += _reserve1 * timeElapsed; }
Title: Use ++index to do increment
By using ++index compared to the current implementation can save 65 gas per loop
Title: Using && in require()
https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L272 https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L294
For every function which will be called quite often times, we can use multiple require() than && operator. Despite it will increase deployment gas fee. It will reduce execution gas fee by 15 Change to:
require(amount0 > 0, 'ILB'); require(amount1 > 0, 'ILB');
#0 - GalloDaSballo
2022-08-04T00:36:45Z
Would like to see math on this
Rest will save less than 500 gas