Caviar contest - 9svR6w's results

A fully on-chain NFT AMM that allows you to trade every NFT in a collection.

General Information

Platform: Code4rena

Start Date: 12/12/2022

Pot Size: $36,500 USDC

Total HM: 8

Participants: 103

Period: 7 days

Judge: berndartmueller

Id: 193

League: ETH

Caviar

Findings Distribution

Researcher Performance

Rank: 13/103

Findings: 2

Award: $791.24

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: carlitox477

Also found by: 9svR6w, KingNFT, Lambda, cccz, cozzetti, gzeon, koxuan, minhquanym, rvierdiiev

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
edited-by-warden
duplicate-343

Awards

750.9785 USDC - $750.98

External Links

Lines of code

https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L172 https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L95

Vulnerability details

Impact

Some ERC20 tokens implement the EIP 777 interface including the tokensToSend() hook, which performs a callback to the user from which tokens will be transferred before the tokens are transferred. A contract can be constructed to receive such a callback in (for example) Pair's buy() line 172, safeTransferFrom(). At the time of this callback the fractional tokens have been transferred out of the Pair but the base tokens have not been transferred into the Pair. At this moment, the xyk exchange rate between these assets will be incorrect. Because Pair does not employ reentrancy protection, the malicious contract can use the tokensToSend() callback to perform another transaction against the Pair to take advantage of this temporarily incorrect exchange rate. (It may in addition be possible to use Pair's add() to trigger tokensToSend() via safeTransferFrom() in a similar manner.)

The contest description states "It's assumed that all NFTs and base token contracts used to create new pairs are honest." I am noting this issue because an ERC777 base token may itself be honest, and users may wish to trade this token but be unaware of the possible exploit available to other users of the honest ERC777 contract due to lack of reentrancy protection in Pair.

Note that the same basic issue was identified in uniswap https://github.com/ConsenSys/Uniswap-audit-report-2018-12#31-liquidity-pool-can-be-stolen-in-some-tokens-eg-erc-777-29 https://github.com/OpenZeppelin/exploit-uniswap and reentrancy protection is now available as an option https://ethereum.stackexchange.com/a/113700

Proof of Concept

Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.

Tools Used

Add reentrancy protection to Pair trading functions add(), remove(), buy(), sell().

#0 - c4-judge

2022-12-29T11:34:08Z

berndartmueller marked the issue as duplicate of #343

#1 - c4-judge

2023-01-13T11:51:04Z

berndartmueller changed the severity to 3 (High Risk)

#2 - c4-judge

2023-01-13T11:51:38Z

berndartmueller marked the issue as satisfactory

Awards

40.2564 USDC - $40.26

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-376

External Links

Lines of code

https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L63-L99 https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L423

Vulnerability details

Impact

A user of Pair calls add() supplying a baseTokenAmount and a fractionalTokenAmount they intend to use to purchase LP tokens. They also supply minLpTokenAmount, the minimum number of LP tokens they expect to receive. The add() function in turn calls addQuote(), which checks the exchange rates for both base tokens and fractional tokens and determines the number of LP tokens to issue, based on the exact exchange rate for either base tokens or fractional tokens. The selection of whether the exchange rate for base tokens or fractional tokens is to be used is based on which results in the smallest number of LP tokens being issued for the asset amounts provided by the caller of add(). This means that for the asset (base or fractional token) with an exchange rate that is not used, there may be an excess bid provided by the caller in that token. This excess bid is not refunded to the caller.

This means that if exchange rates change between when the caller of add() requests their transaction and when the transaction is committed, they will be charged based on the full amount of assets they provide, not on the exchange rate value (in the higher valued asset) at the time. Furthermore, in anticipation of volatile exchange rates, the caller may want to include some slack in providing baseTokenAmount, fractionalTokenAmount, and minLpTokenAmount. But because they will not receive a refund for any excess amount provided they are discouraged from providing too much slack. And in fact they may even be unaware of the no-refund policy in the first place and simply lose an arbitrary excess bid provided. Finally, while the excess assets (non refunded excess bids) will tend to accrue to the Pair pool when transactions are ordered arbitrarily, it may be possible for a miner to extract MEV by ordering (delaying) a call to add() until after a separate transaction that changes the base token or fractional token exchange rates with respect to LP tokens, and adding additional transactions to capture some of the excess bid assets that would normally be absorbed by the Pair pool.

Proof of Concept

Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.

Tools Used

Return excess bid of baseTokenAmount or fractionalTokenAmount to the caller of add().

#0 - c4-judge

2022-12-28T12:41:18Z

berndartmueller marked the issue as duplicate of #376

#1 - c4-judge

2023-01-10T09:02:03Z

berndartmueller changed the severity to 3 (High Risk)

#2 - c4-judge

2023-01-10T09:02:08Z

berndartmueller marked the issue as satisfactory

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