Tapioca DAO - IllIllI's results

The first ever Omnichain money market, powered by LayerZero.

General Information

Platform: Code4rena

Start Date: 05/07/2023

Pot Size: $390,000 USDC

Total HM: 136

Participants: 132

Period: about 1 month

Judge: LSDan

Total Solo HM: 56

Id: 261

League: ETH

Tapioca DAO

Findings Distribution

Researcher Performance

Rank: 94/132

Findings: 1

Award: $76.55

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: IllIllI

Also found by: 0x007, Breeje, cergyk, hack3r-0m, kutugu, pks_

Labels

bug
2 (Med Risk)
downgraded by judge
primary issue
satisfactory
selected for report
M-35

Awards

76.5537 USDC - $76.55

External Links

Lines of code

https://github.com/code-423n4/2023-07-tapioca/blob/7f9fd0f315225b7bd09042b0da8941b93d1b156f/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L118

Vulnerability details

Impact

get_virtual_price() was originally considered to be a manipulation-resistant price - suitable as a price oracle, but it was later found to be vulnerable to a read-only reentrancy attack, where the Curve contract could be put into a partially-modified state, and an attacker could gain control via the raw external call remove_liquidity() makes. The attacker could use this to artificially inflate the price of the LP token/its balance, and use the inflated balance to take out loans which become undercollateralized at the end of the transaction, or to buy assets at exchange rates not actually available on the open market.

Proof of Concept

ARBTriCryptoOracle calls get_virtual_price() without calling any nonreentrant functions:

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

117      function _get() internal view returns (uint256 _maxPrice) {
118 @>       uint256 _vp = TRI_CRYPTO.get_virtual_price();
119  
120          // Get the prices from chainlink and add 10 decimals
121          uint256 _btcPrice = uint256(BTC_FEED.latestAnswer()) * 1e10;
122          uint256 _wbtcPrice = uint256(WBTC_FEED.latestAnswer()) * 1e10;
123          uint256 _ethPrice = uint256(ETH_FEED.latestAnswer()) * 1e10;
124          uint256 _usdtPrice = uint256(USDT_FEED.latestAnswer()) * 1e10;
125  
126          uint256 _minWbtcPrice = (_wbtcPrice < 1e18)
127              ? (_wbtcPrice * _btcPrice) / 1e18
128              : _btcPrice;
129  
130          uint256 _basePrices = (_minWbtcPrice * _ethPrice * _usdtPrice);
131  
132          _maxPrice = (3 * _vp * FixedPointMathLib.cbrt(_basePrices)) / 1 ether;
133  
134          // ((A/A0) * (gamma/gamma0)**2) ** (1/3)
135          uint256 _g = (TRI_CRYPTO.gamma() * 1 ether) / GAMMA0;
136          uint256 _a = (TRI_CRYPTO.A() * 1 ether) / A0;
137          uint256 _discount = Math.max((_g ** 2 / 1 ether) * _a, 1e34); // handle qbrt nonconvergence
138          // if discount is small, we take an upper bound
139          _discount = (FixedPointMathLib.sqrt(_discount) * DISCOUNT0) / 1 ether;
140  
141          _maxPrice -= (_maxPrice * _discount) / 1 ether;
142:     }

https://github.com/code-423n4/2023-07-tapioca/blob/7f9fd0f315225b7bd09042b0da8941b93d1b156f/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L117-L142

_get() is used by get(), peek(), and peekSpot(), which are used by the Magnetar to price tokens.

Tools Used

IllIllI-bot

In order to protect against the attack, many protocols call uint256[2] calldata amts; ICurvePool(token).remove_liquidity(0, amts); prior to calling get_virtual_price() since calling remove_liquidity() will ensure, via a reentrancy guard, that the user isn't currently manipulating the value, and since amounts are zero, it has no other effect. Another alternative is to call claim_admin_fees().

Assessed type

Reentrancy

#0 - c4-pre-sort

2023-08-05T06:47:10Z

minhquanym marked the issue as duplicate of #704

#1 - c4-judge

2023-09-13T08:57:56Z

dmvt marked the issue as satisfactory

#2 - c4-judge

2023-09-20T20:12:27Z

dmvt changed the severity to 2 (Med Risk)

#3 - c4-judge

2023-10-08T11:45:59Z

dmvt marked the issue as selected for report

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