Casting a Magic Spell on Abracadabra
An Arbitrage Captured the Price Caching Design Defect to Profit Over $110K
by: SlowMist Security Team & EigenPhi Research
Key Takeaways:
Human mistakes, such as bad code and the intricacy of complex systems, can lead to disastrous consequences for DeFi protocols.
The utilization of the price-caching design defect of Abracadabra was the cause of the $110K arbitrage opportunity.
Tools and services such as EigenPhi’s EigenTx and SlowMist can help to monitor and analyze risks in DeFi protocols in a financial and bottom-up style.
※ ※ ※ ※ ※ ※ ※ ※
From Team Finance’s $15.8M loss to Skyward Finance’s $3.2M rekt, one after another, these recent protocols’ debacles have become the symbol of DeFi’s disastrous year in terms of poor risk management. The aforementioned 2 cases belong to a growing category of human mistakes: bad code.
With so many open-source projects overlapping each other, forming complex systems, and so little time to do a full-scale code review and audit, the hidden risks are evolving into time bombs that few can detect, not to mention predict.
Working together and starting from assets flows, Smart Contract codes, and underlying transaction structures, EigenPhi and SlowMist bring mighty tools to the DeFi community and enable protocol designers, researchers, and daily users to monitor and analyze risks. Our tools empower everyone to dismantle the internal mechanics of complex Smart Contract transactions and demonstrate the transaction processes, thus contributing risk mitigation efforts for DeFi protocols.
Recently, we both identified an arbitrage reaping $110K profit on a cost of $27. After rigorous investigations, we independently recognized that this was utilization of the design defect of Abracadabra: failing to update the price cache of collaterals. When the price of collaterals declined rapidly, a windfall arbitrage opportunity emerged and was seized by the searcher.
So, let me show you how it's done from start to finish.
Protocols and Addresses Involved
SushiSwap BentoBoxV1, the vault of SushiSwap: 0xf5bce5077908a1b7370b9ae04adc565ebd643966. According to the official document, the stored tokens can be flash loaded or used in strategies - the yield from this will go to the token depositors.
Abracadabra Cauldron, the $xSUSHI lending smart contract: 0xbb02A884621FB8F5BFd263A67F58B65df5b090f3, created by SushiSwap BentoBoxV1
SushiSwap MIM-WETH Liquidity Pool: 0x07D5695a24904CC1B6e3bd57cC7780B90618e3c4
SushiSwap xSUSHI-WETH Liquidity Pool: 0x36e2FCCCc59e5747Ff63a03ea2e5C0c2C14911e7
This figure shows you the asset flow of the arbitrage.
We will guide you through every step in the chart. Before that, let’s take a quick tour.
A Brief Walkthrough from SlowMist
SlowMist identified that the asset of the arbitrager (or exploiter) was from Tornado.Cash: Router, in which he whitewashed his earnings.
The arbitrager first used a flash loan to take out 450,000 xSUSHI tokens from BentoBoxV1 in preparation for the transaction.
Then, he transferred 418,303 $xSUSHI to the BentoBoxV1 contract.
Next, he added collateral: transferring 418,285 $xSUSHI to the CauldronMediumRiskV1 contract via the BenToBox V1 contract.
The arbitrager borrowed 808,233 $MIM from the CauldronMediumRiskV1 contract, then he updated CauldronMediumRiskV1’s exchange rate of $MIM against $xSUSHI. This is the critical step in creating the price spread.
The arbitrager liquidated himself on CauldronMediumRiskV1. The liquidation amount passed in is 682,090 $MIM. At this point, the original $xSUSHI against $MIM price was higher due to the untimely oracle price update being stored in the cache. The updated exchange rate made $xSUSHI cheaper against $MIM, which means the liquidation can exchange all the collateralized $xSUSHI tokens with fewer $MIM. Therefore, the CauldronMediumRiskV1 contract gave back all the $xSUSHI tokens (418,285) to the arbitrage contract, and the contract transferred 696,904 $MIM to the CauldronMediumRiskV1 contract.
The arbitrager finally withdrew 418,303 $xSUSHI and 111,329 $MIM. Then he swapped the MIM for 225 $xSUSHI using SushiSwap.
At last, the arbitrager transferred 450,225 $xSUSHI back to BenToBoxV1 to return the flash loan, finally making a profit of $110,911 $MIM.
To find out how exactly the arbitrager managed it, let’s take you to dive into the code he used step by step.
A Step-by-Step Code Review
We are going to use the EigenTx transaction visualizer to show every step along the way of the token flow chart. EigenTx’s CallTrace tree feature makes it easier to check the Smart Contract code bit by bit.
Step 1.
BentoBoxV1.batchFlashLoan(address,address[],address[],uint256[],bytes) method supports flash-loaning multiple assets in batch. The arbitrager used it to borrow 450K $xSushi and 0 $MIM.
Step 2.
BentoBoxV1.batchFlashLoan used a callback to invoke the borrower’s onBatchFlashLoan function. It checked the balanced and executed an approval operation.
Step 3.
The arbitrager deposited 418,303 $xSUSHI to BentoBoxV1 and received 418,285 virtualShareSUSHI.
Please be noted that there is no such token as virtualShareSUSHI. The protocol uses such internal measures to keep a record of shares for users’ loans. For the sake of clarity, we name it virtualShareSUSHI.
Step 4.
The arbitrager collateralized the 418,285 virtualShareSUSHI, getting 418,285 virtualShare, which is also a measure of internal record, an abstraction dissociating specific assets or tokens, named by EigenPhi.
Step 5.
The arbitrager borrowed 808,233 virtualShareMIM, and the Cauldron protocol wrote down his debt as 808,637 virtualDebtMIM. The latter amount included the fees demanded by the protocol. Again, virtualShareMIM and virtualDebtMIM are internal measures.
This step required the exchange rate of $MIM against $xSUSHI, which was the old exchangeRate. The pictures below are from Tender.ly.
Step 6. This is the critical step in creating the opening for arbitrage.
The arbitrager updated the exchange rate.
The rate data below is from EthTx:
Here emerged the arbitrage opportunity.
Borrow the asset using the old exchange rate.
Update the exchange rate.
Liquidate the debt using the new exchange rate.
The price change from Etherscan:
The rate’s last updated date is Nov 5. The price of $xSUSHI was $2.6.
The price chart from CoinGecko:
When the arbitrage happened, the price of $xSUSHI was $2.2, down 15%.
The price chart from CoinGecko:
Using the rate 387970202315884682, the arbitrager borrowed more $MIM, seen here from Tender.ly:
Liquidating his debt using rate 533537989524363604, the arbitrager took back his collateral with less $MIM, seen here from Tender.ly:
Step 7.
The arbitrager liquidated himself.
He returned 696,904 virtualShareMIM and took out his collateral: 418,285 virtualShareSUSHI. Here are the details.
First, the arbitrager’s collateral shares were deducted.
Next, the debt shares of the arbitrager, a.k.a. the borrower, got deducted.
Then, the collateral shares of the liquidator, a.k.a. the arbitrager, increased.
Last, the repaid assets of the liquidator, a.k.a. the arbitrager, were deducted.
Step 8.
The arbitrager withdrew the tokens by converting the shares to real tokens: 418,303 xSUSHI & 111,329 $MIM. The latter came from deducting the returned 696,904 $MIM from the borrowed 808,233 $MIM.
Step 9.
The arbitrager swapped 417.9725 $MIM for 225 $xSUSHI to pay the fee of flash loans.
Step 10.
The arbitrager paid back the flash loans to the BentoBoxV1.
Step 11.
The arbitrager raked his gain: 110,911 $MIM.
Better Late Than Never
After this event, Abracadabra started a bot to update the exchange price regularly. This measure fits one of the three methods EigenPhi and SlowMist recommend for scenarios relying on oracle providing prices.
The protocol runs a price bot to update the rate regularly. Besides, the update needs to run under certain conditions, such as the price of $ETH reaching a certain point and some kind of calculation, i.e., the debt is overcollateralized.
Every borrowing and liquidation, all these operations requiring exchange rate, invoke the oracle to update the price.
Use Chainlink Keepers for decentralized automatic price execution.
An Increasingly Complex DeFi Needs More Enhanced Tools
According to the report of Delphi Digital, the loss caused by “flaws within the protocol architecture or smart contracts” has reached $2.7B in 2022, a 63% increase from last year.
With more and more DeFi derivatives showing up on the horizon and more TradFi embedding within DeFi protocols, it’s imperative and beneficial for the DeFi community to embrace more advanced tools to monitor, detect, and mitigate risks. Tools and services like SlowMist and EigenPhi build the financial, not merely data analysis, infrastructures for DeFi. Starting from Smart Contracts to analyze the underlying transaction structures and presenting the results to the public in a straightforward way, this is how we demystify the dark magic born from the dark forest of DeFi.