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: 17/72
Findings: 3
Award: $941.66
π Selected for report: 0
π Solo Findings: 0
π Selected for report: SmartSek
Also found by: csanuragjain, hansfriese
https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L286 https://github.com/code-423n4/2022-06-connext/blob/main/contracts/contracts/core/connext/facets/StableSwapFacet.sol#L21-L23
In StableSwapFacet, users can swap tokens in case of emergencies and this could lead to unexpected results.
According to L21-L23, swap must be paused in case of emergencies. But StableSwapFacet.swapExactOut() can work as it doesn't have a "whenNotPaused" modifier and it could lead to unexpected results.
Solidity Visual Developer of VSCode
"whenNotPaused" must be added to StableSwapFacet.swapExactOut().
#0 - ecmendenhall
2022-06-20T15:54:15Z
Duplicate of #175
#1 - jakekidd
2022-06-25T00:35:16Z
π 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
151.3887 USDC - $151.39
I've found 7 low-risk issues and some non-critical ones.
2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L227 "@return amount of tokens the user must transfer"
2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L240 "@notice Calculate the amount of tokens the user must transfer"
2022-06-connext\contracts\contracts\core\connext\libraries\LibConnextStorage.sol#L299 Currently, it's the same as "portalDebt" and it must be changed for "portalFeeDebt".
2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L209 "// xpReduced[i] = xp[i] - dxExpected * fee / FEE_DENOMINATOR"
2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L790 "Swap needs more than max tokens"
safeApprove() is deprecated, use safeIncreaseAllowance() and safeDecreaseAllowance() instead 2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L347
Missing events for onlyAdmin functions that change important parameters 2022-06-connext\contracts\contracts\core\connext\facets\PortalFacet.sol#L68
Check address(0) before transfer funds even if they are onlyAdmin functions. 2022-06-connext\contracts\contracts\core\connext\facets\RelayerFacet.sol#L172 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L260 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L293 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L296 2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L142 2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L145 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1059
PortalFacet.getAavePortalFeeDebt() returns wrong results. 2022-06-connext\contracts\contracts\core\connext\facets\PortalFacet.sol#L39 It must return "s.portalFeeDebt[_transferId]".
Check address(0) when change admin role. 2022-06-connext\contracts\contracts\core\connext\helpers\ConnextPriceOracle.sol#L168
Inconsistent implementation of "adminFee" and "swapFee". 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1071 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1084 2022-06-connext\contracts\contracts\core\connext\facets\StableSwapFacet.sol#L432-L433 2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L97-98
It checks adminFee < MAX_ADMIN_FEE, swapFee < MAX_SWAP_FEE in 2 places but checks adminFee <= MAX_ADMIN_FEE, swapFee <= MAX_SWAP_FEE in other place.
2022-06-connext\contracts\contracts\core\connext\facets\PortalFacet.sol#L80 @param _transferId
2022-06-connext\contracts\contracts\core\connext\facets\StableSwapFacet.sol#L255 @param minAmountOut @param deadline @return
2022-06-connext\contracts\contracts\core\connext\facets\StableSwapFacet.sol#L279 @param maxAmountIn @param deadline @return
2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L319 @return
2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L336 @return
2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L354 @return
2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L226 @param _maxIn @return
2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L262 @param _slippageTol @return
2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L304 @param _maxIn @return
2022-06-connext\contracts\contracts\core\connext\libraries\LibConnextStorage.sol#L77 @param routerSignatures
2022-06-connext\contracts\contracts\core\connext\libraries\LibConnextStorage.sol#L100 @param approvedForPortalRouters
2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L173 @param totalSupply
2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L484 @param balances
2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L515 @param balances
Event should use indexed fields if there are three or more fields 2022-06-connext\contracts\contracts\core\connext\facets\AssetFacet.sol#L27 2022-06-connext\contracts\contracts\core\connext\facets\AssetFacet.sol#L35 2022-06-connext\contracts\contracts\core\connext\facets\AssetFacet.sol#L44 2022-06-connext\contracts\contracts\core\connext\facets\AssetFacet.sol#L55 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L179 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L187 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L195 2022-06-connext\contracts\contracts\core\connext\facets\RelayerFacet.sol#L25 2022-06-connext\contracts\contracts\core\connext\helpers\ConnextPriceOracle.sol#L66-L67 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L73 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L78 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L83 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L88 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L93 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L98 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L108 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L113 2022-06-connext\contracts\contracts\core\connext\libraries\AmplificationUtils.sol#L17 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L69 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L81 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L92 2022-06-connext\contracts\contracts\core\promise\PromiseRouter.sol#L78 2022-06-connext\contracts\contracts\core\relayer-fee\RelayerFeeRouter.sol#L50
Typo 2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L244 @return amount of tokens the user "must(has to)" transfer
2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L253 @notice Swaps assetIn "t" assetOut using the stored stable swap or internal swap pool
2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L295 @notice Swaps assetIn "t" assetOut using the stored stable swap or internal swap pool
2022-06-connext\contracts\contracts\core\connext\libraries\AssetLogic.sol#L331
NOTE: this is less efficient "then" relying on the swapInternalOut
revert, but makes it easier
2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L917 minAmounts must match "poolTokens" => "pooledTokens"?
Needless import 2022-06-connext\contracts\contracts\core\connext\helpers\ConnextPriceOracle.sol#L4 2022-06-connext\contracts\contracts\core\connext\libraries\AmplificationUtils.sol#L5 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L4
Immutable addresses should be 0-checked 2022-06-connext\contracts\contracts\core\connext\helpers\Executor.sol#L48
Open TODOs 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L492 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L579 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L1027 2022-06-connext\contracts\contracts\core\connext\helpers\Executor.sol#L7 2022-06-connext\contracts\contracts\core\connext\libraries\LibConnextStorage.sol#L303
#0 - jakekidd
2022-07-02T00:11:37Z
Low-Risk issues don't seem to carry any risk or are invalid
Non-critical (QA) are great
π 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
88.7836 USDC - $88.78
Use != 0 instead of > 0 for uint variables 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L499 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L665 2022-06-connext\contracts\contracts\core\connext\facets\StableSwapFacet.sol#L416 2022-06-connext\contracts\contracts\core\connext\helpers\ConnextPriceOracle.sol#L150 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L217 2022-06-connext\contracts\contracts\core\connext\libraries\AmplificationUtils.sol#L86 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L121 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L139 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L158 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L226 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L232 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L247 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L369 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L670 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L711 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L765 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L799 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L845 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L965 2022-06-connext\contracts\contracts\core\promise\PromiseRouter.sol#L259
Use ++i instead of i++, i+=1, also unchecked increments in for-loops will save gas cost 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L613 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L684 2022-06-connext\contracts\contracts\core\connext\facets\BridgeFacet.sol#L799 2022-06-connext\contracts\contracts\core\connext\facets\DiamondLoupeFacet.sol#L31 2022-06-connext\contracts\contracts\core\connext\facets\RelayerFacet.sol#L144 2022-06-connext\contracts\contracts\core\connext\facets\RelayerFacet.sol#L168 2022-06-connext\contracts\contracts\core\connext\facets\StableSwapFacet.sol#L415 2022-06-connext\contracts\contracts\core\connext\helpers\ConnextPriceOracle.sol#L176 2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L81 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L104 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L129 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L134 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L147 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L153 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L162 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L205 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L254 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L268 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L289 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L300 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L302 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L344 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L405 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L425 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L558 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L591 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L844 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L869 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L924 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1014 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1019 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1039 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1055 2022-06-connext\contracts\contracts\core\relayer-fee\libraries\RelayerFeeMessage.sol#L85
Non-strict inequalities are cheaper than strict ones 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L214 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L256 2022-06-connext\contracts\contracts\core\connext\helpers\SponsorVault.sol#L258 2022-06-connext\contracts\contracts\core\connext\libraries\AmplificationUtils.sol#L59 2022-06-connext\contracts\contracts\core\connext\libraries\MathUtils.sol#L29
Check require(), assert() at the beginning of function 2022-06-connext\contracts\contracts\core\connext\helpers\LPToken.sol#L50 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L123 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L141 2022-06-connext\contracts\contracts\core\connext\libraries\LibDiamond.sol#L161
No need to initialize variables with default values 2022-06-connext\contracts\contracts\core\relayer-fee\libraries\RelayerFeeMessage.sol#L81 2022-06-connext\contracts\contracts\core\connext\facets\StableSwapFacet.sol#L415 2022-06-connext\contracts\contracts\core\connext\helpers\ConnextPriceOracle.sol#L176 2022-06-connext\contracts\contracts\core\connext\helpers\StableSwap.sol#L81 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L205 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L254 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L268 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L289 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L300 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L302 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L344 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L405 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L425 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L558 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L591 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L844 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L869 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L924 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1014 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1019 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1039 2022-06-connext\contracts\contracts\core\connext\libraries\SwapUtils.sol#L1055
Don't use storage value if possible 2022-06-connext\contracts\contracts\core\connext\facets\PortalFacet.sol#L108
s.routerBalances[msg.sender][_local] = routerBalance - amountIn;