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
Rank: 26/132
Findings: 4
Award: $2,276.11
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: ladboy233
Also found by: 0xSmartContract
349.0423 USDC - $349.04
The Uniswap V3 documentation states that its oracles are not suitable for Optimism because on that chain block.timestamp refers to the L1's timestamp, and thus the oracle is much less costly to manipulate. https://docs.uniswap.org/concepts/protocol/oracle#oracles-integrations-on-layer-2-rollups
Price information is obtained from Uniswapv3 TWAP in GLPOracle.sol contract
tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol: 23 /// @inheritdoc IOracle 24: function get( 25: bytes calldata 26: ) public view override returns (bool success, uint256 rate) { 27: return (true, _get()); 28: } 29: 30: // Check the last exchange rate without any state changes 31: /// @inheritdoc IOracle 32: function peek( 33: bytes calldata 34: ) public view override returns (bool success, uint256 rate) { 35: return (true, _get()); 36: } 37: 38: // Check the current spot exchange rate without any state changes 39: /// @inheritdoc IOracle 40: function peekSpot( 41: bytes calldata data 42: ) external view override returns (uint256 rate) { 43: (, rate) = peek(data); 44: } 45:
Project oracle has contracts reading oracle rates from both UniswapV3 and Chainlink from just UniswapV3 or from just Chainlink.
https://docs.tapioca.xyz/tapioca/core-technologies/pearlayer-and-oracles#price-feeds-oracles
Price Feeds (Oracles) Tapioca leverages a combination of Chainlink and Uniswap V3 TWAP (Time Weighted Average Price) oracles with a 10-minute time window. Whenever there is a need for an oracle value, the protocol chooses between the output of Uniswap V3 TWAP and Chainlink Price Feed which is most at the advantage of the protocol. For assets that do not have either a Uniswap V3 TWAP Oracle or Chainlink Price Feed, such as GMX GLP or Curve TriCrypto, the assets respectives protocol's price feed itself will be utilized.
Consider using only Chainlink oracles on these L2s. Dont use Uniswap TWAP v3
Oracle
#0 - c4-pre-sort
2023-08-05T09:56:13Z
minhquanym marked the issue as low quality report
#1 - c4-pre-sort
2023-08-09T08:21:41Z
minhquanym marked the issue as duplicate of #1474
#2 - c4-judge
2023-09-20T21:23:22Z
dmvt changed the severity to QA (Quality Assurance)
#3 - c4-judge
2023-09-22T15:40:10Z
dmvt marked the issue as grade-a
#4 - c4-judge
2023-10-05T10:39:59Z
This previously downgraded issue has been upgraded by dmvt
#5 - c4-judge
2023-10-05T10:41:29Z
dmvt marked the issue as satisfactory
🌟 Selected for report: Sathish9098
Also found by: 0xSmartContract, 0xnev, Udsen, jasonxiale, rvierdiiev, tsvetanovv
58.8874 USDC - $58.89
https://github.com/Tapioca-DAO/tapioca-bar-audit/blob/master/contracts/markets/bigBang/BigBang.sol#L365-L370 https://github.com/Tapioca-DAO/tapioca-bar-audit/blob/master/contracts/markets/bigBang/BigBang.sol#L404-L408 https://github.com/Tapioca-DAO/tapioca-bar-audit/blob/master/contracts/markets/bigBang/BigBang.sol#L618
The BigBang
contract does not allow users to submit a deadline for their actions which execute swaps . This missing feature enables pending transactions to be maliciously executed at a later point.
A slippage check is in place, the only viable attack scenario seems to be stealing of positive slippage by MEV bots;
tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol: 336: function buyCollateral( 337: address from, 338: uint256 borrowAmount, 339: uint256 supplyAmount, 340: uint256 minAmountOut, 341: ISwapper swapper, 342: bytes calldata dexData 343: ) external notPaused solvent(from) returns (uint256 amountOut) { // codes... 364: uint256 collateralShare; 365: (amountOut, collateralShare) = swapper.swap( 366: swapData, 367: minAmountOut, 368: from, 369: dexData 370: ); // codes... 375: } tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol: 384: function sellCollateral( 385: address from, 386: uint256 share, 387: uint256 minAmountOut, 388: ISwapper swapper, 389: bytes calldata dexData 390: ) external notPaused solvent(from) returns (uint256 amountOut) { // codes... 403: uint256 shareOut; 404: (amountOut, shareOut) = swapper.swap( 405: swapData, 406: minAmountOut, 407: from, 408: dexData 409: ); // codes... 424: }
Omitted in this case, since the exploit is solely based on the fact that there is no limit on how long a transaction including a swap is allowed to be pending, which can be clearly seen when looking at the mentioned functions.
Introduce a deadline parameter to all functions which potentially perform a swap on the user's behalf.
MEV
#0 - c4-pre-sort
2023-08-05T12:45:39Z
minhquanym marked the issue as duplicate of #1513
#1 - c4-judge
2023-09-29T21:45:37Z
dmvt marked the issue as satisfactory