-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
An attacker can make many functions revert, including Emergency Market Shutdown #147
Comments
raymondfam marked the issue as insufficient quality report |
raymondfam marked the issue as duplicate of #72 |
See #72. |
hansfriese changed the severity to QA (Quality Assurance) |
hansfriese marked the issue as grade-c |
Hello It's not exactly a duplicate of issue 72 because this issue focuses on making the Emergency Market Shutdown revert, whereas the original issue is concentrated on price differences. Additionally, the comment left in issue 72 does not apply here:
Emergency market shutdowns are caused by black swan events. The team may want to invoke it in the event of a malfunction in the Chainlink oracle, such as when the oracle starts to revert or experiences other issues. It is important to ensure that the protocol team understands that in some black swan events, an attacker can cause the While the probability is low (if you trust Chainlink), the impact is high, so I would argue that a medium severity rating is appropriate. Thank you for taking another look at this. |
Not too worried about the impact here because of easy mitigation, plus the number of steps required to make it feasible:
DAO should just use flashbots when calling marketShutdown |
QA is appropriate due to the rare likelihood. |
Lines of code
https://github.com/code-423n4/2024-03-dittoeth/blob/91faf46078bb6fe8ce9f55bcb717e5d2d302d22e/contracts/libraries/LibOracle.sol#L139
Vulnerability details
Summary
It's possible to sandwich calls to a function that uses an oracle, reduce the Uniswap v3 USDC_WETH pool WETH balance below 100, and make the function revert because Ditto's code reverts in cases when the Uniswap USDC_WETH pool has < 100 WETH. It may also be used to use Chainlink's price when it should have used TWAP.
Vulnerability Details
There is a check in
twapCircuitBreaker
An attacker can use a flash loan from Uniswap's USDC/WETH pool (when they call the function themselves) to borrow enough WETH that the pool has < 100.
Or do a sandwich attack in all other cases. A sandwich attack is more dangerous.
Steps for the attacker (all in a flashbots bundle, so it's atomic):
0. See a transaction sent by a user/DAO/admin.
wethBal < 100 ether
check.Attack success can depend on several factors: TVL, how concentrated the liquidity is.
The lower the TVL, the cheaper the attack. When the liquidity is highly concentrated, an attack is more expensive but possible because an attacker doesn't need to pay a high price to reduce the WETH balance of the pool; they pay a market price.
In my PoC, I show a case when a pool has a significant amount of WETH (2550) yet it's possible to sandwich it to have < 100 WETH. The fees in this case will be around 2.5 WETH (7k USDC in prices of a block used for PoC).
Also notice that it had less WETH than in my PoC not so long ago, around 08/03/2024 it had 2162.
See the graph and a table here.
The pool balance can go down as users migrate to UniV4 or other platforms, which will make the attack cheaper. It can fall below 100 WETH naturally too.
twapCircuitBreaker
is used in many functions, all of them are listed below:LibOracle.twapCircuitBreaker
LibOracle.getOraclePrice
2xLibOracle.baseOracleCircuitBreaker
LibOracle.getOraclePrice
MarketShutdownFacet.shutdownMarket
OwnerFacet.createMarket
DeployHelper.postDeploySetup
DeployDiamond.run
ViewFacet.getShortIdAtOracle
ViewFacet.getOracleAssetPrice
ViewFacet.getAssetCollateralRatio
LibOracle.getSavedOrSpotOraclePrice
SecondaryLiquidationFacet.liquidateSecondary
ShortOrdersFacet.createLimitShort
ShortOrdersFacet.decreaseCollateral
LibShortRecord.getCollateralRatioSpotPrice
ShortRecordFacet.increaseCollateral
ViewFacet.getCollateralRatioSpotPrice
LibOrders._updateOracleAndStartingShort
LibOrders.updateOracleAndStartingShortViaThreshold
BidOrdersFacet._createBid
BidOrdersFacet.createBid
BidOrdersFacet.createForcedBid
ExitShortFacet.exitShort
PrimaryLiquidationFacet._performForcedBid
PrimaryLiquidationFacet.liquidate
ShortOrdersFacet.createLimitShort
LibOrders.updateOracleAndStartingShortViaTimeBidOnly
BidOrdersFacet.createBid
ExitShortFacet.exitShort
PrimaryLiquidationFacet.liquidate
Note: the attack requires the Chainlink oracle to malfunction, which can be a possible reason to try to shut down a market. We need to get here.
Impact
The biggest impact is that it would be impossible to shut down a market, which will lead to high losses. It breaks a security assumption link:
Also, the attacker can block other liquidators' liquidations, which will also lead to the accrual of bad debt. And liquidate big positions themselves when it becomes cheaper, which can be profitable.
An attacker can also censor
createBid
and other functions, which can lead to disruptions in main protocol functionality.Proof of Concept
package.json
the"forge-std"
line to"forge-std": "github:foundry-rs/forge-std#v1.8.0"
npm i; npm update forge-std; forge clean;
contracts/AAUniswapPoolSandwich.t.sol
MAINNET_RPC_URL
in.env
forge test -vvv --mt testRevertsInSandwich
Expected output:
Tools Used
Manual review.
Recommended Mitigation Steps
Consider checking the pool's liquidity and not the WETH balance.
Assessed type
Oracle
The text was updated successfully, but these errors were encountered: