SlowMist: An Analysis of the Attack on the OmniX NFT Platform (Released in 2022)
According to the SlowMist Security Team, on July 10, 2022, the OmniX NFT platform suffered a flash loan attack. The SlowMist Security Team now shares a brief review and analysis as follows:
Attack Contract Addresses Deployed by the Attacker:
Analysis of the Attack
1. The attacker first borrowed 1,000 WETH from Balancer: Vault with a flash loan, then bought BeaconProxy DOODLE credentials for 16.505 WETH.
2. The attacker then borrowed 20 DOODLE credentials from BeaconProxy with a flash loan and withdrew the corresponding 20 DoodleNFT by using the redeem function. At this point, the attacker’s preparation was complete.
3. The attacker created a contract 0x23F8770bd80EFFA7F09dFfdc12A35B7221d5cad3. The attacker transferred 20 DoodleNFT to the newly created contract and used the contract to call supplyERC721 to mortgage the NFT and obtained the NToken of the pledge. Then the attacker called the borrow function to borrow 12.15 WETH.
4. The attacker called withdrawERC721 to take the pledged NFT.
Then came the heart of the attack. The executeWithdrawERC721 needs to burn the NToken of the pledge credentials.
However, burn in NToken uses the transfer function with the callback feature.
So in the process of burn, the attacker used this feature to reenter the liquidationERC721 function of the contract.
5. The attacker repaid the previous 12.15 WETH and obtained the corresponding NFT from the liquidation logic, which was in the liquidation logic.
In the callback, the attacker continued to pledge all of the NFT and reloaned 81 WETH. If normal borrowing logic was followed, the contract would call userConfig.setBorrowing(reserve.id, true); record that the user had a borrowing status.
However, after the reentrant call ended, the attacker proceeded to complete the remaining logic of executeERC721LiquidationCall. Since the attacker was paying in full before reentering, the attacker can judge by vars.userTotalDebt == vars.actualDebtToLiquidate. The attacker then executed userConfig.setBorrowing(liquidationAssetReserve.id, false); set the user’s credit status to false.
The attacker then initiated a separate withdrawERC721 operation, which checked whether there was a debit flag before determining the amount of debt. Since the debit status had already been set to false in the previous attack, the attacker could take out the pledged NFT without clearing the liability.
6. Finally, the attacker created a new contract to perform the same attack, paid back the flash loan’s WETH and NFT, and went with profits.
In this case, the burn function of NToken is a function with callbacks, which allows the attacker to reenter the contract multiple times, resulting in an error in the contract’s accounting. Even if the user borrows after reentry, the user’s status is set to not borrowed, resulting in no repayment. The SlowMist Security Team recommends using reentry locks on key functions to prevent reentry problems.
SlowMist is a blockchain security firm established in January 2018. The firm was started by a team with over ten years of network security experience to become a global force. Our goal is to make the blockchain ecosystem as secure as possible for everyone. We are now a renowned international blockchain security firm that has worked on various well-known projects such as Huobi, OKX, Binance, imToken, Crypto.com, Amber Group, Klaytn, EOS, 1inch, PancakeSwap, TUSD, Alpaca Finance, MultiChain, O3Swap, etc.