Relayer Handling Swap/Mint Jammed by bad usage of SafeApprove #48
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate
This issue or pull request already exists
Lines of code
https://github.com/code-423n4/2022-06-connext/blob/b4532655071566b33c41eac46e75be29b4a381ed/contracts/contracts/core/connext/facets/BridgeFacet.sol#L389
https://github.com/code-423n4/2022-06-connext/blob/b4532655071566b33c41eac46e75be29b4a381ed/contracts/contracts/core/connext/facets/BridgeFacet.sol#L1025
https://github.com/code-423n4/2022-06-connext/blob/b4532655071566b33c41eac46e75be29b4a381ed/contracts/contracts/core/connext/libraries/AssetLogic.sol#L347
https://github.com/code-423n4/2022-06-connext/blob/b4532655071566b33c41eac46e75be29b4a381ed/contracts/contracts/core/connext/libraries/AssetLogic.sol#L347
Vulnerability details
Context of relevant lines of code and functions:
L389: BridgeFacet.sol: handle function
L1025: BridgeFacet.sol: Comment About This
L1029: BridgeFacet.sol: SafeIncrease of Allowance
L347: AssetLogic.sol: Usage of SafeApprove
Impact
Each call apart from the first one that relies on the
swapFromLocalAssetIfNeededForExactOut
function will be reverted and the whole call will suffer a reversal in cascade. This will deny future nomad relayers calls tohandle
and as a consequence, jam the relayer logic.Proof of Concept
The relayer logic according to the comments and description provided by the Connext team suggests that the
handle
function is called once a router message has been optimistically verified. The flow of how the calls are being triggered will be the following:handle
, L389._reconcile
, L541. This function will handle how the balance of tokens is managed regarding minting and AMM swapping._reconcileProcessPortal
is called in order to repay Aave Portal.swapFromLocalAssetIfNeededForExactOut
L226 logic managed by theAssetLogic
library._swapAssetOut
, trigger made at L226, where the implementation is at L304.SafeERC20.safeApprove(IERC20(_assetIn), address(pool), _amountIn)
.The first time this whole loop is called, every step will pass and the transaction will be mined. But when the second call is triggered, the step 6 will be reverted by following the
SafeERC20
function logic:The reversal comes from the
require
statement under the execution of thesafeApprove
call, more precisely the last argument of theor logic operator
.As the
handle
function is meant to be called several times, this may incur in a severe jamming of the relayer logic preventing them to perform further calls.Recommended Mitigation Steps
OpenZeppelin suggests not using this implementation as is deprecated and it should only be called if the initial allowance wants to be set (initial state of the contract allowances). In order to manage the allowances, following the
SafeERC20
standard suggestions, it is advisable to use insteadSafeERC20.safeIncreaseAllowance
andSafeERC20.safeDecreaseAllowance
.The text was updated successfully, but these errors were encountered: