Published in


OMNI Attack Analysis

Omni is a platform for creating and trading custom digital assets and currencies. It is a software layer built on top of the most popular, most audited, most secure blockchain — Bitcoin. Omni transactions are Bitcoin transactions that enable next-generation features on the Bitcoin Blockchain. Our reference implementation, Omni Core is an enhanced Bitcoin Core that provides all the features of Bitcoin as well as advanced Omni Layer features.

Attack wallet address:







  1. The attacker flashloan 1000 WETH from Balancer to


2. The attacker uses the flashloan function to borrow 20 Doodles and uses 13.203802230912588834 WETH to exchange 1 Doodles via sushiswap

3. Call the supplyERC721 method to stake three NFTs and lend 12.15 WETH

4.Take out two of the NFTs

5.Return the loaned 12.15 WTH and call the clearing method for the remaining one NFT

6. Continue the re-entry attack by calling the ERC721_checkOnERC721Received function during the liquidation process to stake 20 doodles and lend 81 WETH

7.take out 20 NFT, due to the return value of the clearing function will be set to the state of false, so in the take-out function for the debit and credit status error, 20 NFT can be successfully taken out

8.Since the NFT is first removed when the liquidation is performed and the money returned is deducted afterwards, the attacker makes a re-entry by removing the NFT and continues to make a judgment after the re-entry, at which point the state has changed and the 12.15 WETH previously lent does not need to be returned, so the attacker will end up with 93.15 WETH

9. Return the 20 Doodles obtained by calling flashloan and return the 1000 WETH obtained by flashloan

The attacker does so by calling the liquidation method executeERC721LiquidationCall in LiquidationLogic.sol

When calling the _burnCollateralNTokens method, the burn function calls the _checkOnERC721Received method in ERC721

At this point, the TO address is the address of the attack contract, where the attacker implements the re-entry attack. Continue to stake 20 Doodles for borrowing.

The ID status is marked as true, and the clearing function overrides the true to false when it continues to execute the clearing function. isBorrowAny() then determines the ID status, which is false, and successfully removes the staked Doodles.

The two attacking wallet addresses have transferred 800 ETH and 426.5 ETH of captured funds to Tornado.Cash

The core of the attack is a flaw in the access control of the project’s contract, which does not restrict the re-entry of pledges in the Pool contract, allowing the attacker to maliciously call the _checkOnERC721Received function in ERC721 to carry out the re-entry attack, as well as not setting the status judgment operation before the setBorrowing() method.

New to trading? Try crypto trading bots or copy trading



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store

Lunaray takes a leading position in smart contract auditing and consulting service for blockchain security.