Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas Optimizations #30

Open
code423n4 opened this issue Jun 10, 2022 · 1 comment
Open

Gas Optimizations #30

code423n4 opened this issue Jun 10, 2022 · 1 comment
Labels
bug Something isn't working G (Gas Optimization)

Comments

@code423n4
Copy link
Contributor

[G-01] Use prefix not postfix in loops

Using a prefix increment (++i) instead of a postfix increment (i++) saves gas for each loop cycle and so can have a big gas impact when the loop executes on a large number of elements.

There are many examples of this in for loops
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/relayer-fee/libraries/RelayerFeeMessage.sol#L85
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L81
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/Multicall.sol#L16
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L176
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L415
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/DiamondLoupeFacet.sol#L31
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L144
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L168
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L613
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L684
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L799
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L104
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L129
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L134
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L147
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L153
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L162
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L205
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L254
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L268
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L289
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L300
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L302
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L344
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L405
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L425
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L558
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L591
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L844
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L869
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L924
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1014
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1019
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1039
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1055

Recommended Mitigation Steps

Use prefix not postfix to increment in a loop

[G-02] Redundant zero initialization

Solidity does not recognize null as a value, so uint variables are initialized to zero. Setting a uint variable to zero is redundant and can waste gas.

There were many places where an int is initialized to zero
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/relayer-fee/libraries/RelayerFeeMessage.sol#L81
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L81
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/Multicall.sol#L16
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L176
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L415
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/VersionFacet.sol#L16
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L68
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L205
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L254
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L268
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L289
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L300
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L302
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L344
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L405
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L425
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L558
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L591
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L844
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L869
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L924
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1014
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1019
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1039
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1055
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/Encoding.sol#L22
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/Version.sol#L9

Recommended Mitigation Steps

Remove the redundant zero initialization
uint256 i; instead of uint256 i = 0;

[G-03] Split up require statements instead of &&

Combining require statement conditions with && logic uses unnecessary gas. It is better to split up each part of the logical statement into a separate require statements

One example is

require(_bathAssetAddress != address(0) && _bathQuoteAddress != address(0), "tokenToBathToken error");

This can be improved to

require(_bathAssetAddress != address(0));
require(_bathQuoteAddress != address(0));

Several places had require statements with many logical "and"s. Instead, split into two to save gas
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L397
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L493
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L524
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1007
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AmplificationUtils.sol#L86

Recommended Mitigation Steps

Use separate require statements instead of concatenating with &&

[G-04] Cache array length before loop

Caching the array length outside a loop saves reading it on each iteration, as long as the array's length is not changed during the loop. This saves gas.

This was found in many places
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L81
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/Multicall.sol#L16
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L176
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L415
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L140
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L164
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L104
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L129
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L147
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L162
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L205
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L558
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L591
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L844
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L869
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L924
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1014
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1019
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1039
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1055

Recommended Mitigation Steps

Cache the array length before the for loop

[G-05] Use != 0 instead of > 0

Using > 0 uses slightly more gas than using != 0. Use != 0 when comparing uint variables to zero, which cannot hold values below zero

Locations where this was found include
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L82
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L276
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L150
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L217
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L416
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L240
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L293
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L499
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L665
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L121
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L139
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L158
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L226
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L232
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L247
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L369
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L670
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L711
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L765
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L799
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L845
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L965
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AmplificationUtils.sol#L86
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/PromiseRouter.sol#L259
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/libraries/PromiseMessage.sol#L142
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/ProposedOwnable.sol#L146

Recommended Mitigation Steps

Replace > 0 with != 0 to save gas

[G-06] Short require strings save gas

Strings in solidity are handled in 32 byte chunks. A require string longer than 32 bytes uses more gas. Shortening these strings will save gas.

Several places for this improvement was found
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L121
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L123
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L132
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L139
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L141
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L150
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L158
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L161
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L191
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L193
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L224
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L226
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OZERC20.sol#L185
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OZERC20.sol#L186
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OZERC20.sol#L205
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OZERC20.sol#L226
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OZERC20.sol#L253
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OZERC20.sol#L254

Recommended Mitigation Steps

Shorten all require strings to less than 32 characters

[G-07] For loop incrementing can be unsafe

For loops that use i++ do not need to use safemath for this operation because the loop would run out of gas long before this point. Making this addition operation unsafe using unchecked saves gas.

Sample code to make the for loop increment unsafe

for (uint i = 0; i < length; i = unchecked_inc(i)) {
    // do something that doesn't change the value of i
}

function unchecked_inc(uint i) returns (uint) {
    unchecked {
        return i + 1;
    }
}

Idea borrowed from
https://gist.github.com/hrkrshnn/ee8fabd532058307229d65dcd5836ddc#the-increment-in-for-loop-post-condition-can-be-made-unchecked

There are many for loops and that can use this change
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L81
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/Multicall.sol#L16
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L176
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L415
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L140
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L164
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L104
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L129
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L147
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L162
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L205
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L558
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L591
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L844
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L869
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L924
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1014
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1019
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1039
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L1055
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/Encoding.sol#L22

Recommended Mitigation Steps

Make the increment in for loops unsafe to save gas

[G-08] Use iszero assembly for zero checks

Comparing a value to zero can be done using the iszero EVM opcode. This can save gas

Source from t11s https://twitter.com/transmissions11/status/1474465495243898885

There are many places where a value is compared to zero
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/relayer-fee/RelayerFeeRouter.sol#L107
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/relayer-fee/libraries/RelayerFeeMessage.sol#L99
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L85
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L175
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L217
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L255
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L87
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L90
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L93
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L128
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/BridgeToken.sol#L90
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/TokenRegistry.sol#L178
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L148
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L332
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L537
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L583
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L137
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L148
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L181
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L219
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/PortalFacet.sol#L141
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L435
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L126
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L144
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L208
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibDiamond.sol#L224
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L292
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L884
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AssetLogic.sol#L129
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AssetLogic.sol#L171
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AssetLogic.sol#L210
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/PromiseRouter.sol#L177
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/PromiseRouter.sol#L269
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/PromiseRouter.sol#L281
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/ProposedOwnable.sol#L125

Recommended Mitigation Steps

Use the assembly iszero evm opcode to compare values to zero

[G-09] Unnecessary Import

SafeMath is imported in contracts that are using solidity 0.8.X. This version of solidity already applies safemath to math operations. The SafeMath import can be removed to save gas.

Places with SafeMath imports:
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L4
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OZERC20.sol#L10
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L4
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AmplificationUtils.sol#L5

Recommended Mitigation Steps

Remove SafeMath import from solidity 0.8.X files.

[G-10] Add payable to functions that won't receive ETH

Identifying a function as payable saves gas. Functions that have a modifier like onlyOwner or auth cannot be called by normal users and will not mistakenly receive ETH. These functions can be payable to save gas.

There are many functions that have the auth modifier in the contracts. Some examples are
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/relayer-fee/RelayerFeeRouter.sol#L89
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/LPToken.sol#L34
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L440
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L448
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L456
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L467
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L474
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L155
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L169
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L197
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L211
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L239
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L253
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/BridgeToken.sol#L54
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/BridgeToken.sol#L66
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/BridgeToken.sol#L73
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/BridgeToken.sol#L202
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OwnerPausableUpgradeable.sol#L23
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/OwnerPausableUpgradeable.sol#L30
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L138
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L147
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L159
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L168
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/AssetFacet.sol#L100
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/AssetFacet.sol#L112
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/AssetFacet.sol#L162
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/AssetFacet.sol#L171
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L460
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L469
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L478
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L502
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/NomadFacet.sol#L25
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/NomadFacet.sol#L34
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L293
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L331
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L345
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L361
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L375
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L88
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L101
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L112
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L128
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L142
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L162
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L175
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L203
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L217
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L253
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/ProposedOwnableFacet.sol#L258
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/PortalFacet.sol#L57
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/PortalFacet.sol#L65
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L233
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L242
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L250
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/PromiseRouter.sol#L155
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/Router.sol#L34
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/ProposedOwnable.sol#L109
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/ProposedOwnable.sol#L123
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/XAppConnectionClient.sol#L39

Recommended Mitigation Steps

Add payable to these functions for gas savings

[G-11] Use internal function in place of modifier

An internal function can save gas vs. a modifier. A modifier inlines the code of the original function but an internal function does not.

Source https://blog.polymath.network/solidity-tips-and-tricks-to-save-gas-and-reduce-bytecode-size-c44580b218e6#dde7

Many modifiers can use this change
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/relayer-fee/RelayerFeeRouter.sol#L73
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/relayer-fee/libraries/RelayerFeeMessage.sol#L43
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/StableSwap.sol#L124
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/Executor.sol#L56
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L130
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ProposedOwnableUpgradeable.sol#L138
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L71
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L120
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L57
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BaseConnextFacet.sol#L36
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BaseConnextFacet.sol#L55
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BaseConnextFacet.sol#L63
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BaseConnextFacet.sol#L71
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BaseConnextFacet.sol#L79
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BaseConnextFacet.sol#L87
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L156
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RoutersFacet.sol#L167
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/RelayerFacet.sol#L63
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibCrossDomainProperty.sol#L47
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/ConnextMessage.sol#L48
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/PromiseRouter.sol#L139
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/promise/libraries/PromiseMessage.sol#L40
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/Router.sol#L22
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/ProposedOwnable.sol#L82
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/ProposedOwnable.sol#L90
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/XAppConnectionClient.sol#L21

Recommended Mitigation Steps

Use internal functions in place of modifiers to save gas.

[G-12] Use simple comparison in trinary logic

The comparison operators >= and <= use more gas than >, <, or ==. Replacing the >= and ≤ operators with a comparison operator that has an opcode in the EVM saves gas

The existing code is
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/SponsorVault.sol#L208

amountIn = currentBalance >= amountIn ? amountIn : currentBalance;

A simple comparison can be used for gas savings by reversing the logic

amountIn = currentBalance < amountIn ? currentBalance : amountIn;

Recommended Mitigation Steps

Replace the comparison operator and reverse the logic to save gas using the suggestions above

[G-13] Unnecessary require statements

There is a require statement that is not necessary because the transaction will still revert without it. This can be removed for gas savings because they don't provide any additional protection.

The unnecessary line
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L649

Recommended Mitigation Steps

Remove unnecessary require statements to save gas

[G-14] Use type(uint256).max

The value ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff is used for some variables but using type(uint232).max uses less gas than this constant value.
Source https://forum.openzeppelin.com/t/using-the-maximum-integer-in-solidity/3000/13

There are two places where this change can save gas
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibCrossDomainProperty.sol#L37
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibCrossDomainProperty.sol#L38

Recommended Mitigation Steps

Use type(uint232).max instead

[G-15] Non-public variables save gas

Many constant variables are public, but changing the visibility of these variables to private or internal can save gas.

https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/PriceOracle.sol#L6
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/facets/BridgeFacet.sol#L68
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AmplificationUtils.sol#L21
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/AmplificationUtils.sol#L22
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibCrossDomainProperty.sol#L37
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/LibCrossDomainProperty.sol#L38
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/shared/Version.sol#L9
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/helpers/BridgeToken.sol#L17

Recommended Mitigation Steps

Declare some public variables as private or internal to save gas

[G-16] Use calldata instead of memory for function arguments

Using calldata instead of memory for function arguments saves gas sometimes. This can happen when a function is called externally and the memory array values are kept in calldata and copied to memory during ABI decoding (using the opcode calldataload and mstore). If the array is used in a for loop, arr[i] accesses the value in memory using a mload. If calldata is used instead, then instead of going via memory, the value is directly read from calldata using calldataload. That is, there are no intermediate memory operations that carries this value.

Many cases of function arguments using memory instead of calldata can use this improvement to save gas
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L244
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L286
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L336
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L393
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L489
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L550
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L819
https://github.com/code-423n4/2022-06-connext/tree/main/contracts/contracts/core/connext/libraries/SwapUtils.sol#L988

Source
https://gist.github.com/hrkrshnn/ee8fabd532058307229d65dcd5836ddc#use-calldata-instead-of-memory-for-function-parameters

Recommended Mitigation Steps

Change function arguments from memory to calldata

[G-17] Write contracts in vyper

The contracts are all written entirely in solidity. Writing contracts with vyper instead of solidity can save gas.

Source https://twitter.com/eiber_david/status/1515737811881807876
doggo demonstrates https://twitter.com/fubuloubu/status/1528179581974417414?t=-hcq_26JFDaHdAQZ-wYxCA&s=19

Recommended Mitigation Steps

Write some or all of the contracts in vyper to save gas

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Jun 10, 2022
code423n4 added a commit that referenced this issue Jun 10, 2022
@0xleastwood
Copy link
Collaborator

Good series of optimisations. However, I'd like to note that G-10 is not a safe practice to follow. Best to avoid making arbitrary functions payable in order to save gas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working G (Gas Optimization)
Projects
None yet
Development

No branches or pull requests

2 participants