[WP-H10] `GenericSwapFacet.sol#swapTokensGeneric()` duplicated `.call{ value: msg.value }` makes it possible for the attacker to steal native tokens (ETH) from the contract #163
In the AnyswapFacet.sol, _anyswapData.router is from the caller's calldata, which can really be any contract, including a fake Anyswap router contract, as long as it complies to the interfaces used.
And in _startBridge, it will grant infinite approval for the _anyswapData.token to the _anyswapData.router.
This makes it possible for a attacker to steal all the funds from the contract.
Which we explained in [WP-H6], the diamond contract may be holding some funds for various of reasons.
PoC
Given:
ETH price is 10,000 USDC per ETH;
There are 0.1 ETH (native tokens) in the contract.
The attacker can submit a swapTokensGeneric() with 0.1 ETH as receivingAssetId with the following SwapData[]:
Swap 0.1 ETH to USDC;
Swap 0.1 ETH to USDC.
The attacker will receive ~2,000 USDC. 1,000 of which is the 0.1 ETH stolen from the contract.
Recommendation
Make sure to only call with {value: msg.value} when LibAsset.isNativeAsset(fromAssetId):
Lines of code
https://github.com/code-423n4/2022-03-lifinance/blob/699c2305fcfb6fe8862b75b26d1d8a2f46a551e6/src/Facets/GenericSwapFacet.sol#L22-L43
Vulnerability details
https://github.com/code-423n4/2022-03-lifinance/blob/699c2305fcfb6fe8862b75b26d1d8a2f46a551e6/src/Facets/GenericSwapFacet.sol#L22-L43
https://github.com/code-423n4/2022-03-lifinance/blob/699c2305fcfb6fe8862b75b26d1d8a2f46a551e6/src/Facets/Swapper.sol#L12-L22
https://github.com/code-423n4/2022-03-lifinance/blob/699c2305fcfb6fe8862b75b26d1d8a2f46a551e6/src/Libraries/LibSwap.sol#L29-L58
In the
AnyswapFacet.sol
,_anyswapData.router
is from the caller's calldata, which can really be any contract, including a fake Anyswap router contract, as long as it complies to the interfaces used.And in
_startBridge
, it will grant infinite approval for the_anyswapData.token
to the_anyswapData.router
.This makes it possible for a attacker to steal all the funds from the contract.
Which we explained in [WP-H6], the diamond contract may be holding some funds for various of reasons.
PoC
Given:
The attacker can submit a
swapTokensGeneric()
with0.1 ETH
asreceivingAssetId
with the followingSwapData[]
:The attacker will receive ~2,000 USDC. 1,000 of which is the 0.1 ETH stolen from the contract.
Recommendation
{value: msg.value}
whenLibAsset.isNativeAsset(fromAssetId)
:https://github.com/code-423n4/2022-03-lifinance/blob/699c2305fcfb6fe8862b75b26d1d8a2f46a551e6/src/Libraries/LibSwap.sol#L29-L46