LI.FI contest - pmerkleplant's results

Bridge & DEX Aggregation.

General Information

Platform: Code4rena

Start Date: 24/03/2022

Pot Size: $75,000 USDC

Total HM: 15

Participants: 59

Period: 7 days

Judge: gzeon

Id: 103

League: ETH

LI.FI

Findings Distribution

Researcher Performance

Rank: 3/59

Findings: 4

Award: $6,234.50

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: 0xDjango

Also found by: GeekyLumberjack, pmerkleplant

Labels

bug
duplicate
3 (High Risk)

Awards

4566.5778 USDC - $4,566.58

External Links

Lines of code

https://github.com/code-423n4/2022-03-lifinance/blob/main/src/Facets/NXTPFacet.sol#L165

Vulnerability details

Impact

A token swap via NXTPFacet::swapAndCompleteBridgeTokensViaNXTP in which the receiving amount of tokens is zero does not fail.

Proof of Concept

The function NXTPFacet::swapAndCompleteBridgeTokensViaNXTP does not require that the token balance after the swap is higher than the token balance before the swap (see line 165).

Add a require statement checking that postSwapBalance - startingBalance > 0 after the _executeSwap call.

#0 - H3xept

2022-04-06T14:41:13Z

Fixed in lifinance/lifi-contracts@87a27cee2fbde337c4ab873971f37573d2240994

#1 - H3xept

2022-04-11T11:46:47Z

Duplicate of #76

Findings Information

🌟 Selected for report: hake

Also found by: Kenshin, Ruhum, VAD37, WatchPug, csanuragjain, hickuphh3, hyh, kirk-baird, obront, pmerkleplant, rayn, shw, tintin, wuwe1

Labels

bug
duplicate
2 (Med Risk)
disagree with severity
sponsor acknowledged

Awards

77.3842 USDC - $77.38

External Links

Lines of code

https://github.com/code-423n4/2022-03-lifinance/blob/main/src/Libraries/LibSwap.sol#L33 https://github.com/code-423n4/2022-03-lifinance/blob/main/src/Facets/AnyswapFacet.sol#L76

Vulnerability details

Impact

Any ERC20 token balance held in the contract can be stolen by an attacker.

Proof of Concept

The swap function in the LibSwap.sol library checks if the contract's balance is sufficient to execute the trade (see line 33). If the contract does not hold the number of tokens to swap, the amount is transferred from the caller to the contract.

As long as the swap function is called with a swap amount of a token being less than the balance of the token in the contract, the function does not transfer the tokens from the caller but uses the contract's own tokens for the swap.

Furthermore, as the swapData argument is created by the caller (see for example AnyswapFacet.sol line 76), the contract called could be controlled by the caller and statically only returning 1 arbitrary token.

Remove the second condition in the if-clause in the LibSwap::swap function to always transfer the tokens from the caller to the contract before executing a swap.

#0 - H3xept

2022-04-12T08:38:40Z

Duplicate of #66

We are aware that the contract allows users to use latent funds, although we disagree on it being an issue as no funds (ERC20 or native) should ever lay in the contract. To make sure that no value is ever kept by the diamond, we now provide refunds for outstanding user value (after bridges/swaps).

Findings Information

🌟 Selected for report: hyh

Also found by: danb, kirk-baird, pmerkleplant

Labels

bug
duplicate
2 (Med Risk)

Awards

924.732 USDC - $924.73

External Links

Lines of code

https://github.com/code-423n4/2022-03-lifinance/blob/main/src/Facets/NXTPFacet.sol#L133

Vulnerability details

Impact

A user wanting to bridge ERC20 tokens would lose all ETH accidentally send to the contract.

Proof of Concept

The bridging facets follow the pattern of checking if the token is native or ERC20. In case the token is ERC20, there is no check that msg.value == 0 (except for NXTPFacet::completeBridgeTokensViaNXTP).

This leads to the ETH sent accidentally by a user being held unaccounted for in the contract and being lost for the user.

Refactor following functions to include a check that msg.value == 0 in case the token address is not zero:

  • CBridgeFacet::startBridgeTokensViaCBridge
  • CBridgeFacet::swapAndStartBridgeTokenViaCBridge
  • AnyswapFacet::startBridgeTokensViaAnyswap
  • AnyswapFacet::swapAndStartBridgeTokensViaAnyswap
  • NXTPFacet::swapAndStartBridgeTokensViaNXTP
  • NXTPFacet::swapAndStartBridgeTokensViaAnyswap
  • HopFacet::swapAndStartBridgeTokensViaHop
  • HopFacet::startBridgeTokensViaHop

#0 - H3xept

2022-04-11T12:47:57Z

Findings Information

🌟 Selected for report: shw

Also found by: Picodes, hickuphh3, hyh, pmerkleplant

Labels

bug
duplicate
2 (Med Risk)

Awards

665.807 USDC - $665.81

External Links

Lines of code

https://github.com/code-423n4/2022-03-lifinance/blob/main/src/Facets/CBridgeFacet.sol#L68

Vulnerability details

Impact

A user wanting to bridge ETH via CBridge could lose some amount of ETH.

Proof of Concept

The function startBridgeTokenViaCBridge checks the amount of ETH transfered with msg.value >= _cBridgeData.amount in case the token address is zero.

If a user accidentally sends more ETH than _cBridgeData.amount, that ETH would be held unaccounted for in the contract and be lost for the user.

Refactor the check to msg.value == _cBridgeData.amount.

#0 - H3xept

2022-04-06T08:19:34Z

Fixed in previous commit.

#1 - H3xept

2022-04-11T11:17:07Z

Duplicate of #207

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter