Blog

Conic Finance Incident Analysis

Research reportsIncident analysis
Conic Finance Incident Analysis

Introduction

On 21 July, 2023 the Conic Finance ETH Omnipool was exploited for 1724 ETH ($3.2 million) via a read-only reentrancy vulnerability. Despite having reentrancy guards in place, an incorrect assumption led to a reentrancy guard being bypassed. Conic paused the ETH Omnipool but a few hours later they lost a further $300,000 to MEV arbitrage in the crvUSD Omnipool.

Who Are Conic Finance

Conic Finance operates Omnipools for the Curve Finance ecosystem and offer a platform for liquidity providers to diversify their exposure to multiple Curve pools. Users can provide liquidity into a Conic Omnipool which allocates funds across Curve in proportion to protocol controlled pool weights.

Event Summary

On 21 July, 2023 Conic Finance was exploited via a flash loan. An attacker flash loaned approximately $140 million which was used to manipulate Conic’s ETH Omnipool. Following the attack Conic confirmed the exploit was limited to the ETH pool and disabled deposits while they investigated.

conic1
Image: Conic Finance Twitter announcement Source: @ConicFinance (opens in a new tab)

Conic Finance had also been exploited two weeks earlier on 4 July, 2023 when they lost $1,600 also via pool manipulation.

conic2
Image: Conic Finance flash loan exploit on 4 July. Source: Etherscan (opens in a new tab)

Following the exploit the attacker sent the stolen funds to EOA 0x3d32. As of 27 July the wallet held a balance of 1727 ETH ($3,264,214). The attacker has been offered a white hat bounty of approximately 10%.

conic3
Image: Conic Finance attempt to negiotiate with the attacker. Source: Etherscan (opens in a new tab)

The 24 hour deadline passed on 24 July and there still appears to have been no activity.

A few hours after the initial exploit, the Conic crvUSD Omnipool was also exploited due to an imbalance in the Curve pools caused by the initial exploit. MEV (Miner Extracted Value) bots took advantage of an arbitrage opportunity by conducting the following steps:

  1. Swap crvUSD to USDC in the Curve pool

  2. Deposit crvUSD into Conic

  3. Swap USDC to crvUSD in the Curve pool

  4. Withdraw the crvUSD from Conic

  5. Repeat steps 1 to 4

Approximately $300,000 was taken from the crvUSD Omnipool. The MEV activity prompted Conic to pause all deposits to Omnipools to protect against any further loss. Conic finance reached out to the MEV operators and struck a deal with one of the MEV operators for a 10% bounty. The offer saw 81.30 ETH ($150K) returned to Conic Finance.

conic4
Image: A MEV owner returned 81.30 ETH to Conic Finance. Source: Etherscan (opens in a new tab)

Summary of losses as of 27 July:

Total amount lost: Approximately $3.35 million.

Total amount returned: 91.30 ETH (Approximately $150K)

Attack Flow

Attacker: 0x8d67db0b205e32a5dd96145f022fa18aae7dc8aa (opens in a new tab)

Contract Attacker: 0x743599ba5cfa3ce8c59691af5ef279aaafa2e4eb (opens in a new tab)

ConicEthPool (Victim): 0xbb787d6243a8d450659e09ea6fd82f1c859691e9 (opens in a new tab)

Exploit Txn: 0x8b74995d1d61d3d7547575649136b8765acb22882960f0636941c44ec7bbe146 (opens in a new tab)

The exploit is a result of read-only reentrancy despite Conic Finance having reentrancy guards in place.

“Our assumption was that Curve v2 pools using ETH have the ETH address (0xeee…eee) as one of their coins. However, they instead have the WETH address. This led to _isETH returning false, and in turn, to the reentrancy guard of the rETH pool being bypassed.” Source: Conic Finance Post Mortem (opens in a new tab)

The attacker flash loaned assets worth approximately $134 million which included 20,000 stETH from AAVE as well as 20,550 rETH, 3000 CbETH and 28,504.2 WETH from Balancer.

The flash loaned funds were deposited via an ‘addLiquidity()’ call using the contract ‘vyper_contract'.

The attacker then called ‘remove_liquidity()' which burned the attacker’s LP tokens and transferred funds back to the attacker triggering a callback.

During the callback to the attacker they called ‘ConicEthPool.withdraw()’. As the remove_liquidity() function had not yet completed the ‘rETH-f.totalSupply()’ was incorrect. The attacker took advantage of this incorrect value to get more funds than was initially deposited.

conic5
Image: remove_liquidity function in the contract 'vyper_contract'. Source: Etherscan (opens in a new tab)

The attacker transferred the funds to EOA 0x3d32c5a2e592c7b17e16bddc87eab75f33ae3010 (opens in a new tab). As of writing the funds are still in the wallet.

Conclusion

This incident is the largest flash loan attack in July 2023 and the 7th largest we have recorded in 2023. With the EraLend exploit (link below) on 25 July it is also one of two read-only reentrancy exploits that occurred within the space of four days.

Understanding reentrancy is hugely important to secure smart contracts. Reentrancy can occur whenever a function calls another contract, as such an otherwise secure function can still lead to a contract being drained. Smart contracts should try to follow the process of Checks → Effects → Interactions in order to protect against reentrancy. Functions can be further protected by also using ReentrancyGuard which prevents a function from being re-entered.

Further reading

What is a Reentrancy Attack? https://www.certik.com/resources/blog/3K7ZUAKpOr1GW75J2i0VHh-what-is-a-reentracy-attack

EraLend Incident Analysis https://www.certik.com/resources/blog/4NPEuNEiaUUcm6S3gdKKLP-eralend-incident-analysis

Share

Tell us what you are building.