Team Secure3 recently discovered a malicious attack on the OMNI Protocol, with the hacker stealing almost 2000 ETH (~2.4M USD) from OMNI.
According to the OMNI Protocol, only internal testing funds were affected, no customer funds were lost.
Team Secure3 independently analyzed the logic loopholes behind the hack, and now publicly shares our analysis and conclusions to the community in this post.
According to the open-source code repository from OMNI Protocol on 07/06/2022 (4 days before the hack), function executeERC721LiquidationCall
in the contract LiquidationLogic
does not follow the **Checks-Effects-Interactions**
pattern.
Such a critical security issue brings **Reentrancy**
risk, making it possible for hackers to claim back the collateralized NFT assets without paying back the loan borrowed from OMNI.
Secure3 team carefully reviewed the public commit history of OMNI Protocol repository:
As well as the auditing reports published on 07/05/2022,
We noticed that the loophole contracts were within the scope of smart contract security auditing, yet this issue was not reported by corresponding auditing parties.
Some notable addresses:
Attacker borrowed 1000 ETH through flash loan from Balancer, and then borrowed 20 Doodles NFT from NFTX flash loan, using the borrowed ETH.
As shown on the image above, the attacker:
supplyERC721
function in the Pool contract 0xebe72cdafebc1abf26517dd64b28762df77912a9
to deposit three Doodles (720, 5251, 7425) and received nToken (nDoodles) as the proof of deposit.withdrawERC721
function in the Pool contract 0xebe72cdafebc1abf26517dd64b28762df77912a9
to take back two of the three Doodles (720 and 5251).Note:
**safeTransferFrom**
below has**Reentrancy**
risk and will be mentioned later.
During the collateral transfer, attack contract executed malicious onERC721Received
function and called liquidationERC721
function from Pool contract 0xebe72cdafebc1abf26517dd64b28762df77912a9
to liquidate:
The risk is within the liquidation logic:
Within liquidation function executeERC721LiquidationCall
in the LiquidationLogic
contract, attacker paid back 12.15 WETH borrowed, and executed code logistics above:
_burnCollateralNTokens
to:safeTransferFrom
to return collateral DoodlessetBorrowing
to set the borrowing state to false
This is where the issue occurs: the code does not follow the **Checks-Effects-Interactions**
code pattern and brings in **Reentrancy**
risk.
Attack contract implemented onERC721Received
function to accomplish reentrancy, which executed logics below just before setBorrowing(..., false)
above:
setBorrowing
function to set the borrowing state as true
After the execution of staking and borrowing, it went back to the previous liquidating logic to continue executing setBorrowing(..., false)
Apparently, the continuous calling of **setBorrowing**
overwrites the borrowing record to **false**
, and thus erased the borrow record and cleared the borrow collateral.
Then the attacker called withdrawERC721
function to try taking out Doodles and, as the Borrowing
state was already false
(considered as no debts), it bypassed the check and successfully took away all Doodles.
**_Reentrancy_**
Happened?According to EIP-721, when utilizing safeTransferFrom
function to transfer NFT, if the target address is a contract, it will call onERC721Received
function in this contract and require a specific value to be returned from the function.
The reason for this requirement is to make sure the contract is compatible with NFT transfer operations and prevent the NFT from getting transferred to incompatible non-transferrable contracts.
However, it also introduces security risks such that attackers can put malicious code into onERC721Received
function.
If a given contract does not consider this risk, and neither apply [**ReentrancyGuard**](https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard)
nor following the **check-effects-interactions**
pattern, it becomes vulnerable to reentrancy
attack.
In this case, we suggest to use [**ReentrancyGuard**](https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard)
, and follow the **checks-effects-interactions**
pattern during implementation:
**setBorrowing**
before transfer NFT in**executeERC721LiquidationCall**
function.Secure 3 aims to secure Web3 by empowering a transparent, collaborative and verifiable security ecosystem. We aim to provide trustworthy security auditing for projects, competitive incentive model for auditors, and verifiable auditing track record for Web3 community.
Boost Security, Fuel Innovation
Get straight to the insights
On August 14, 2023, according to Secure3, a blockchain security audit contest company, the decentralized yield aggregator ZunamiProtocol was attacked, resulting in a loss of more than 2 million US dollars. The Secure3 security team analyzed that the root cause of this attack was that the LP asset price calculation logic in ZunamiProtocol had defects, and the attacker used it to manipulate the price. The Secure3 security team summarized the reasons for this incident.
On July 31, 2023, according to Secure3, a blockchain security audit contest platform, multiple protocols including Curve were attacked. Further analysis revealed that the root cause was vulnerabilities in the underlying Vyper compiler for the Ethereum smart contract programming language. Versions 0.2.15, 0.2.16 and 0.3.0 contained serious flaws, resulting in multiple attacks on projects like Curve Finance, Alchemix and JPEG’d, inflicting losses totaling around $70 million. The Secure3 security team determined that the fundamental reason behind the attacks was the failure of reentrancy locks in the vulnerable Vyper versions. Secure3’s security team analyzed the factors behind this incident.
On July 7, 2023, according to Secure3, a blockchain security audit contest platform, Fantom Bridge from Multichain was attacked. Multichain has announced through its official Twitter that it has suspended all bridge services and has no estimated resume time yet. The Secure3 security team analyzed and found that there is no evidence showing this is caused by smart contract vulnerability, suspecting that the attack may have been caused by the comproise of the MPC wallet multi-signature private key, causing a loss of about $126 million.
Get In Touch
audit@secure3.io