Understanding Rodeo Finance Exploit

6 min read

Learn how Rodeo Finance was exploited on Arbitrum, resulting in a loss of $888,000.

TL;DR#

On July 11, 2023, Rodeo Finance was exploited on the Arbitrum chain, resulting in a loss of 472 ETH, worth approximately $888,000.

Introduction to Rodeo Finance#

Rodeo is a leveraged yield protocol on Arbitrum. 

Vulnerability Assessment#

The root cause of the exploit is a flawed price oracle dependency, allowing for the pair reserves, unshETH and WETH, of a UniswapV2 pool to be manipulated due to the pool's depth.

Steps#

Step 1:

We attempt to analyze the attack transaction executed by the exploiter.

Step 2:

The TWAP Oracle used an ETH to unshETH reserve ratio for checking price, and the attacker was able to force the platform to swap USDC to unshETH through the earn function with the unconfigured strategy address.

It means that the earn routine can be forced to swap from USDC to WETH to unshETH, but the slippage control cannot take effect as expected due to the flawed unshETH price oracle.

Step 3:

The TWAP price is calculated by averaging the last 4 instances of updated prices, where each price update occurs every 45 minutes. Thus, the affected contracts utilized the faulty price but were forced to believe that the position was healthy.

function latestAnswer() external view returns (int256) {
  require(block.timestamp < lastTimestamp + (updateInterval * 2), "stale price");
  int256 price = (prices[0] + prices[1] + prices[2] + prices[3]) / 4;
  return price;
}

Step 4:

The attacker initially manipulated the TWAP oracle by sandwiching the update, opened a leveraged position by calling the earn function from the Investor contract, and borrowed funds worth $400,000 USDC.

function earn(address usr, address pol, uint256 str, uint256 amt, uint256 bor, bytes calldata dat)
  external
  loop
  returns (uint256)
{
  if (status < S_LIVE) revert WrongStatus();
  if (!pools[pol]) revert InvalidPool();
  if (strategies[str] == address(0)) revert InvalidStrategy();
  uint256 id = nextPosition++;
  Position storage p = positions[id];
  p.owner = usr;
  p.pool = pol;
  p.strategy = str;
  p.outset = block.timestamp;
  pullTo(IERC20(IPool(p.pool).asset()), msg.sender, address(actor), uint256(amt));
  (int256 bas, int256 sha, int256 bar) = actor.edit(id, int256(amt), int256(bor), dat);
  p.amount = uint256(bas);
  p.shares = uint256(sha);
  p.borrow = uint256(bar);
  emit Edit(id, int256(amt), int256(bor), sha, bar);
  return id;
}

Step 5:

The assets were swapped into the underlying CamelotDEX pool, while the prepared unshETH were sold back to the pool.

Step 6:

The contract also checks whether the execution is valid or not, which was easily bypassed as the attacker controlled this strategy. Thus, the exploiter was able to arbitrage the bad position by selling prepared unshETH back to the pool, taking the liquidity from the platform in the previous steps.

Step 7:

The exploiter bridged the stolen funds from Arbitrum to Ethereum, swapped 285 ETH for unshETH, and bridged them back to Arbitrum to continue the hack. The stolen funds, worth 150 ETH, have been transferred to Tornado Cash, and 371.2 ETH, worth approximately $701,679, are still held at this address controlled by the attacker.

Aftermath#

The exploit took place after the launch of the RDO token on the Camelot DEX. Following the incident, the price of the RDO token dropped from $0.2 to $0.08 and is known to be trading at $0.12 at the time of this writing.

The team also acknowledged the exploit and stated that the financial impact of the exploit resulted in an approximate loss of $880,000 from the lending pool. The total loss from the incident was actually $1.7 million; however, funds worth $810,000 were recovered. The protocol has been placed in a paused state to protect funds and will remain so until a remediation plan has been finalized and implemented.

According to them, the attack was successful because one of their oracles meant to be TWAP for Camelot's uniswap v2 pools was sandwiched just around its price update in order to inflate its price. This allowed the hacker to borrow from the lending pool and swap it all for said token, incurring heavy slippage but still going through because of the inflated oracle pricing.

The lost funds represent a debt from the protocol to USDC lending pool LPs and will be refilled from the Rodeo treasury. The repayment plan will primarily consist of treasury funds from the sale but may also include native tokens such as RDO, xRDO, or other RDO derivatives.

They have also sent an on-chain message to the attacker in order to negotiate the return of the stolen funds. A white-hat payment is suggested in return for all or a portion of the funds being returned.

Solution#

The Time-Weighted Average Price, or TWAP, acts as an oracle to determine the average price of a digital asset over a certain period of time. Usually, this technique is used to lessen the effects of transient increases in price volatility. By fraudulently skewing the computed average price of an item, hackers can use TWAP oracles to their benefit during a transaction.

The oracle in reference used the reserve of the WETH/unshETH pair to derive its pricing data using the Time-Weighted Average pricing (TWAP) approach. These reserves have poor liquidity, which caused significant volatility in unshETH pricing.

The price of unshETH as stated by the oracle and its anticipated value also differed significantly. unshETH was priced at $4219 according to the oracle, but based on its normal rate of exchange with WETH, it should have been closer to $1880. Because of this inconsistency, the hacker was able to manipulate trades and make money while the protocol's slippage controls were unable to stop him.

To prevent such exploits, DeFi protocols need to ensure their price oracles are correctly implemented. This includes a broad set of sources to ensure pricing accuracy and resilience against manipulation. Utilizing oracles that take advantage of multiple data points can help ensure a more accurate reflection of asset prices. It is also crucial to have adequate liquidity in any pools that the oracle relies on for price determination. Attacks of this nature leading to Oracle price manipulation could have been regulated to a greater extent using data providers like ChainLink.

However, despite the most meticulous precautions, some attacks may still succeed. This is where solutions like Neptune Mutual can play a critical role in managing the aftermath of such incidents. If the team associated with Rodeo Finance had established a dedicated cover pool with Neptune Mutual, the impact of this exploit could have been significantly curtailed. Neptune Mutual offers coverage for users who have suffered losses of funds or digital assets due to smart contract vulnerabilities, utilizing their innovative parametric policies.

When a user purchases a Neptune Mutual parametric cover policy, they do not need to provide evidence of their loss to receive payouts. Instead, once an incident has been confirmed and resolved through Neptune Mutual's incident resolution system, payouts can be claimed immediately. Our marketplace is available on multiple popular blockchain networks, including EthereumArbitrum, and the BNB chain. This broad reach allows us to serve a diverse array of DeFi users, offering them protection from potential vulnerabilities and bolstering their confidence in the ecosystem.

Reference Source PeckShieldRodeo

By

Tags