You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When variable is not initialized, it will have its default values.
Example: 0 for uint, false for bool and address(0) for address
I suggest removing default value initialization for following variables.
./connext/facets/BridgeFacet.sol:68: uint16 public constant AAVE_REFERRAL_CODE = 0;
./connext/facets/StableSwapFacet.sol:415: for (uint8 i = 0; i < _pooledTokens.length; i++) {
./connext/facets/VersionFacet.sol:16: uint8 internal immutable _version = 0;
./connext/libraries/SwapUtils.sol:205: for (uint256 i = 0; i < xp.length; i++) {
./connext/libraries/SwapUtils.sol:254: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:268: for (uint256 i = 0; i < MAX_LOOP_LIMIT; i++) {
./connext/libraries/SwapUtils.sol:289: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:300: for (uint256 i = 0; i < MAX_LOOP_LIMIT; i++) {
./connext/libraries/SwapUtils.sol:302: for (uint256 j = 0; j < numTokens; j++) {
./connext/libraries/SwapUtils.sol:344: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:405: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:425: for (uint256 i = 0; i < MAX_LOOP_LIMIT; i++) {
./connext/libraries/SwapUtils.sol:558: for (uint256 i = 0; i < balances.length; i++) {
./connext/libraries/SwapUtils.sol:591: for (uint256 i = 0; i < balances.length; i++) {
./connext/libraries/SwapUtils.sol:844: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:869: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:924: for (uint256 i = 0; i < amounts.length; i++) {
./connext/libraries/SwapUtils.sol:1014: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1019: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1039: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1055: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/helpers/ConnextPriceOracle.sol:176: for (uint256 i = 0; i < tokenAddresses.length; i++) {
./connext/helpers/StableSwap.sol:81: for (uint8 i = 0; i < _pooledTokens.length; i++) {
For example these can change to:
uint16 public constant AAVE_REFERRAL_CODE;
for (uint8 i; i < _pooledTokens.length; i++) {
[G-02] Save Gas in For-Loops by Storing Array's Length as a Variable
3 gas per iteration can be saved by storing an array's length as a variable before
the for-loop.
Issue found at:
./connext/facets/StableSwapFacet.sol:415: for (uint8 i = 0; i < _pooledTokens.length; i++) {
./connext/facets/RelayerFacet.sol:140: for (uint256 i; i < _transferIds.length; ) {
./connext/facets/RelayerFacet.sol:164: for (uint256 i; i < _transferIds.length; ) {
./connext/libraries/LibDiamond.sol:104: for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
./connext/libraries/LibDiamond.sol:129: for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
./connext/libraries/LibDiamond.sol:147: for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
./connext/libraries/LibDiamond.sol:162: for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
./connext/libraries/SwapUtils.sol:205: for (uint256 i = 0; i < xp.length; i++) {
./connext/libraries/SwapUtils.sol:558: for (uint256 i = 0; i < balances.length; i++) {
./connext/libraries/SwapUtils.sol:591: for (uint256 i = 0; i < balances.length; i++) {
./connext/libraries/SwapUtils.sol:844: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:869: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:924: for (uint256 i = 0; i < amounts.length; i++) {
./connext/libraries/SwapUtils.sol:1014: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1019: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1039: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1055: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/helpers/ConnextPriceOracle.sol:176: for (uint256 i = 0; i < tokenAddresses.length; i++) {
./connext/helpers/StableSwap.sol:81: for (uint8 i = 0; i < _pooledTokens.length; i++) {
For example, I suggest changing it to:
pooledTokensLength = _pooledTokens.length
for (uint i; i < pooledTokensLength; i++) {
[G-03] ++i costs less gas than i++
It is better to use ++i than i++ when possible since it costs less gas.
Issue found at:
./connext/facets/BridgeFacet.sol:613: i++;
./connext/facets/BridgeFacet.sol:684: i++;
./connext/facets/BridgeFacet.sol:799: i++;
./connext/facets/StableSwapFacet.sol:415: for (uint8 i = 0; i < _pooledTokens.length; i++) {
./connext/facets/DiamondLoupeFacet.sol:31: for (uint256 i; i < numFacets; i++) {
./connext/facets/RelayerFacet.sol:144: i++;
./connext/facets/RelayerFacet.sol:168: i++;
./connext/libraries/LibDiamond.sol:104: for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
./connext/libraries/LibDiamond.sol:129: for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
./connext/libraries/LibDiamond.sol:134: selectorPosition++;
./connext/libraries/LibDiamond.sol:147: for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
./connext/libraries/LibDiamond.sol:153: selectorPosition++;
./connext/libraries/LibDiamond.sol:162: for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
./connext/libraries/SwapUtils.sol:205: for (uint256 i = 0; i < xp.length; i++) {
./connext/libraries/SwapUtils.sol:254: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:268: for (uint256 i = 0; i < MAX_LOOP_LIMIT; i++) {
./connext/libraries/SwapUtils.sol:289: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:300: for (uint256 i = 0; i < MAX_LOOP_LIMIT; i++) {
./connext/libraries/SwapUtils.sol:302: for (uint256 j = 0; j < numTokens; j++) {
./connext/libraries/SwapUtils.sol:344: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:405: for (uint256 i = 0; i < numTokens; i++) {
./connext/libraries/SwapUtils.sol:425: for (uint256 i = 0; i < MAX_LOOP_LIMIT; i++) {
./connext/libraries/SwapUtils.sol:558: for (uint256 i = 0; i < balances.length; i++) {
./connext/libraries/SwapUtils.sol:591: for (uint256 i = 0; i < balances.length; i++) {
./connext/libraries/SwapUtils.sol:844: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:869: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:924: for (uint256 i = 0; i < amounts.length; i++) {
./connext/libraries/SwapUtils.sol:1014: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1019: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1039: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/libraries/SwapUtils.sol:1055: for (uint256 i = 0; i < pooledTokens.length; i++) {
./connext/helpers/ConnextPriceOracle.sol:176: for (uint256 i = 0; i < tokenAddresses.length; i++) {
./connext/helpers/StableSwap.sol:81: for (uint8 i = 0; i < _pooledTokens.length; i++) {
[G-04] Defined Variables Used Only Once
Certain variables is defined even though they are used only once.
Remove these unnecessary variables to save gas.
For cases where it will reduce the readability, one can use comments to help describe
what the code is doing.
Issue found at
DiamondLoupeFacet.sol
Remove ds variable of facetFunctionSelectors function
88: uint256 routerBalance = s.routerBalances[msg.sender][_local]; // in local
91: if (routerBalance < _maxIn) revert PortalFacet__repayAavePortal_insufficientFunds();
ConnextPriceOracle.sol
Remove rawTokenAmount, tokenDecimalDelta, tokenAmount, rawBaseTokenAmount, baseTokenDecimalDelta,
baseTokenAmount, baseTokenPrice and tokenPrice variable of getPriceFromDex function
!= 0 costs less gas when optimizer is enabled and is used for unsigned integers in "require" statement.
I suggest changing > 0 to != 0
Issue found at:
./connext/libraries/AmplificationUtils.sol:86: require(futureA_ > 0 && futureA_ < MAX_A, "futureA_ must be > 0 and < MAX_A");
./connext/libraries/LibDiamond.sol:121: require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
./connext/libraries/LibDiamond.sol:139: require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
./connext/libraries/LibDiamond.sol:158: require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
./connext/libraries/LibDiamond.sol:226: require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)");
./connext/libraries/LibDiamond.sol:247: require(contractSize > 0, _errorMessage);
./connext/libraries/SwapUtils.sol:845: require(v.totalSupply != 0 || amounts[i] > 0, "Must supply all tokens in pool");
./connext/helpers/ConnextPriceOracle.sol:150: require(baseTokenPrice > 0, "invalid base token");
[G-07] Reduce the Long Revert Strings of Error Messages
By keeping the revert strings within 32 bytes will save you gas since each slot is 32 bytes.
Following are revert strings that are more than 32 bytes.
./connext/libraries/LibDiamond.sol:66: require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner");
./connext/libraries/LibDiamond.sol:121: require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
./connext/libraries/LibDiamond.sol:123: require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
./connext/libraries/LibDiamond.sol:132: require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
./connext/libraries/LibDiamond.sol:139: require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
./connext/libraries/LibDiamond.sol:141: require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
./connext/libraries/LibDiamond.sol:150: require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
./connext/libraries/LibDiamond.sol:158: require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
./connext/libraries/LibDiamond.sol:161: require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
./connext/libraries/LibDiamond.sol:191: require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
./connext/libraries/LibDiamond.sol:193: require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
./connext/libraries/LibDiamond.sol:224: require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty");
./connext/libraries/LibDiamond.sol:226: require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)");
./connext/libraries/SwapUtils.sol:697: require(dy <= self.balances[tokenIndexTo], "Cannot get more than pool balance");
./connext/libraries/SwapUtils.sol:784: require(dy <= self.balances[tokenIndexTo], "Cannot get more than pool balance");
[G-08] Both named returns and return statement are used
Removing unused named returns variable in below code can save gas and improve code readability.
Issue found at
StableSwap.sol (remove returns variable availableTokenAmount)
[G-09] Use require instead of &&
When there are multiple conditions in require statement, break down the require statement into
multiple require statements instead of using && can save gas.
Issue found at
./connext/libraries/AmplificationUtils.sol:86: require(futureA_ > 0 && futureA_ < MAX_A, "futureA_ must be > 0 and < MAX_A");
./connext/libraries/SwapUtils.sol:397: require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, "Tokens must be in pool");
./connext/libraries/SwapUtils.sol:493: require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, "Token index out of range");
./connext/libraries/SwapUtils.sol:524: require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, "Token index out of range");
./connext/libraries/SwapUtils.sol:1007: require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, ">LP.balanceOf");
./connext/helpers/StableSwap.sol:85: tokenIndexes[address(_pooledTokens[i])] == 0 && _pooledTokens[0] != _pooledTokens[i],
For example these can be changed to
require(futureA_ > 0);
require(futureA_ < MAX_A, "futureA_ must be > 0 and < MAX_A");
[G-10] Use Calldata instead of Memory for Read Only Function Parameters
It is cheaper gas to use calldata than memory if the function parameter is read only.
Calldata is a non-modifiable, non-persistent area where function arguments are stored,
and behaves mostly like memory.
I recommend changing following memory to calldata
BridgeFacet.sol
./connext/facets/BridgeFacet.sol:541: function _reconcile(uint32 _origin, bytes memory _message) internal {
./connext/facets/BridgeFacet.sol:706: function _getTransferId(XCallArgs calldata _args, ConnextMessage.TokenId memory _canonical)
./connext/facets/BridgeFacet.sol:917: function _reconcileProcessMessage(bytes memory _message)
[G-01] Unnecessary Default Value Initialization
When variable is not initialized, it will have its default values.
Example: 0 for uint, false for bool and address(0) for address
I suggest removing default value initialization for following variables.
For example these can change to:
[G-02] Save Gas in For-Loops by Storing Array's Length as a Variable
3 gas per iteration can be saved by storing an array's length as a variable before
the for-loop.
Issue found at:
For example, I suggest changing it to:
[G-03] ++i costs less gas than i++
It is better to use ++i than i++ when possible since it costs less gas.
Issue found at:
[G-04] Defined Variables Used Only Once
Certain variables is defined even though they are used only once.
Remove these unnecessary variables to save gas.
For cases where it will reduce the readability, one can use comments to help describe
what the code is doing.
Issue found at
baseTokenAmount, baseTokenPrice and tokenPrice variable of getPriceFromDex function
For mitigation, simply don't define variable that is used only once.
Below is mitigation example of above 1.
[G-05] Redundant Use of Variable
Update admin / _owner valiable after emiting the event so we do not have to
define oldAdmin / oldOwner variable to save gas.
Issue found in
Change it to
Change it to
[G-06] != 0 costs less gass then > 0
!= 0 costs less gas when optimizer is enabled and is used for unsigned integers in "require" statement.
I suggest changing > 0 to != 0
Issue found at:
[G-07] Reduce the Long Revert Strings of Error Messages
By keeping the revert strings within 32 bytes will save you gas since each slot is 32 bytes.
Following are revert strings that are more than 32 bytes.
[G-08] Both named returns and return statement are used
Removing unused named returns variable in below code can save gas and improve code readability.
Issue found at
StableSwap.sol (remove returns variable availableTokenAmount)
[G-09] Use require instead of &&
When there are multiple conditions in require statement, break down the require statement into
multiple require statements instead of using && can save gas.
Issue found at
For example these can be changed to
[G-10] Use Calldata instead of Memory for Read Only Function Parameters
It is cheaper gas to use calldata than memory if the function parameter is read only.
Calldata is a non-modifiable, non-persistent area where function arguments are stored,
and behaves mostly like memory.
I recommend changing following memory to calldata
The text was updated successfully, but these errors were encountered: