Canto contest - rfa's results

Execution layer for original work.

General Information

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

Canto

Findings Distribution

Researcher Performance

Rank: 52/59

Findings: 1

Award: $105.36

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

41.2642 USDC - $41.26

396.9199 CANTO - $64.10

Labels

bug
G (Gas Optimization)

External Links

GAS

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

https://github.com/Plex-Engineer/manifest/blob/688e9b4e7835854c22ef44b045d6d226b784b4b8/contracts/Proposal-Store.sol#L56

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

https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L123

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

https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L218-L234

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

https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L181-L185

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

https://github.com/Plex-Engineer/stableswap/blob/489d010eb99a0885139b2d5ed5a2d826838cc5f9/contracts/BaseV1-core.sol#L232

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

Title: Using calldata to store read only string and array arguments

Would like to see math on this

Rest will save less than 500 gas

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter