Platform: Code4rena
Start Date: 08/06/2022
Pot Size: $115,000 USDC
Total HM: 26
Participants: 72
Period: 11 days
Judge: leastwood
Total Solo HM: 14
Id: 132
League: ETH
Rank: 24/72
Findings: 2
Award: $479.12
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: BowTiedWardens
Also found by: 0x1f8b, 0x29A, 0x52, 0xNazgul, 0xNineDec, 0xf15ers, 0xkatana, 0xmint, Chom, ElKu, Funen, IllIllI, JMukesh, Jujic, Kaiziron, Lambda, MiloTruck, Ruhum, SmartSek, SooYa, TerrierLover, TomJ, WatchPug, Waze, _Adam, asutorufos, auditor0517, bardamu, c3phas, catchup, cccz, ch13fd357r0y3r, cloudjunky, cmichel, cryptphi, csanuragjain, defsec, fatherOfBlocks, hansfriese, hyh, jayjonah8, joestakey, k, kenta, obtarian, oyc_109, robee, sach1r0, shenwilly, simon135, slywaters, sorrynotsorry, tintin, unforgiven, xiaoming90, zzzitron
141.8552 USDC - $141.86
getPriceFromDex uses the spot price of a LP to determine token price. Using a single data point from the LP, instead of using a TWAP, makes the price vulnerable to manipulation. https://github.com/code-423n4/2022-06-connext/blob/4dd6149748b635f95460d4c3924c7e3fb6716967/contracts/contracts/core/connext/helpers/ConnextPriceOracle.sol#L99-L115
More advice from samczsun: https://shouldiusespotpriceasmyoracle.com/
Use a TWAP or similar secure method for a backup price oracle.
#0 - jakekidd
2022-07-01T22:15:26Z
This is not a QA issue but a level 2, and a duplicate of others
Duplicate of https://github.com/code-423n4/2022-06-connext-findings/issues/13
#1 - 0xleastwood
2022-08-15T00:58:01Z
I'm keeping this as QA
because ConnextPriceOracle.sol
is not currently used at all within the codebase.
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xmint, BowTiedWardens, ElKu, Fitraldys, Funen, Kaiziron, Lambda, Metatron, MiloTruck, Randyyy, Ruhum, SmartSek, TomJ, Tomio, UnusualTurtle, Waze, _Adam, apostle0x01, asutorufos, c3phas, catchup, csanuragjain, defsec, fatherOfBlocks, hansfriese, hyh, ignacio, joestakey, k, kaden, nahnah, oyc_109, rfa, robee, sach1r0, simon135, slywaters
337.2601 USDC - $337.26
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
Use prefix not postfix to increment in a loop
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
Remove the redundant zero initialization
uint256 i;
instead of uint256 i = 0;
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
Use separate require statements instead of concatenating with &&
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
Cache the array length before the for loop
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
Replace > 0
with != 0
to 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
Shorten all require strings to less than 32 characters
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
Make the increment in for loops unsafe to save gas
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
Use the assembly iszero
evm opcode to compare values to zero
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
Remove SafeMath import from solidity 0.8.X files.
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
Add payable to these functions for gas savings
An internal function can save gas vs. a modifier. A modifier inlines the code of the original function but an internal function does not.
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
Use internal functions in place of modifiers to save gas.
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;
Replace the comparison operator and reverse the logic to save gas using the suggestions above
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
Remove unnecessary require statements to save gas
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
Use type(uint232).max
instead
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
Declare some public variables as private or internal to save gas
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
Change function arguments from memory to calldata
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
Write some or all of the contracts in vyper to save gas
#0 - 0xleastwood
2022-08-16T19:40:31Z
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.