Back to Blog

Post Mortem: NFTXMarketplace0xZap Vulnerability

This is a brief overview of the recent vulnerability reported through our bug bounty program.

*Note this post has been updated on 30th September 2022 to include the full details of the post mortem.

Incident Summary

The purpose of the NFTXMarketplaceZap is to facilitate buying and selling vault tokens in conjunction with minting, redeeming, and swapping on NFTX. Last month the NFTX team wrote and deployed a new contract called NFTXMarketplace0xZap which differed from the previous zap contract by sourcing liquidity from 0xProtocol instead of just Sushiswap. On September 5th, the NFTX team switched over to the new NFTXMarketplace0xZap, and users began interacting with it when buying, selling, and swapping NFTs on the NFTX dapp.

On September 13th, p0n1 from SECBIT Labs, submitted a detailed bug report via email to [email protected] explaining that anyone who approved the NFTXMarketplace0xZap was at risk of having NFTs stolen from whichever NFT contracts they approved. The estimated potential loss was over 300 ETH in NFTs. Upon receiving the report, the NFTX team paused minting, redeeming, and swapping across all vaults to negate the possibility of an exploit and allow time to investigate and deploy a fix.

On September 14th, a new vault contract was deployed and staged as an upgrade via the NFTX DAO. The unpause functions were also staged to follow after the upgrade. On September 15th, the vault upgrade was enacted on the DAO, followed by the unpause calls, bringing the NFTX protocol back online for regular usage.

Impact

Fortunately, no assets were lost during the incident, and no assets remain at risk from the vulnerability. There was no activity during the pause, so anyone staking inventory or liquidity missed out on yield opportunities during that time.

Attack Vector

NFTXMarketplace0xZap has an internal function called _fillQuote that allows arbitrary calls. This function is called by the mintAndSell721, buyAndSwap721, buyAndRedeem, and mintAndSell1155 functions, allowing the final swapTarget and swapCallData parameters to be specified by the caller.

As a result, an attacker could construct arbitrary parameters to execute arbitrary code in the name of the NFTXMarketplace0xZap contract, enabling two possible attacks:

  1. Transferring any assets held in the NFTXMarketplace0xZap contract.
  2. Transferring any assets authorized to the NFTXMarketplace0xZap contract.

Solution

As a fix, the NFTX team deployed a new NFTXVaultUpgradeable contract as an upgrade for all NFTX vaults. This new vault contract includes a checkAddressOnDenyList function which gets called by mintTo, redeemTo, and swapTo, blocking execution of any calls originating from the vulnerable NFTXMarketplace0xZap. This ensures that the previously deployed NFTXMarketplace0xZap cannot be exploited by an attacker.

A new NFTXMarketplace0xZap contract is being prepared for an audit and has been updated since learning about the vulnerability. The update involved removing the ability for a frontend client to provide the 0x integration swapTarget and instead set the address immutably on contract creation. This swapTarget sets the address reference that will handle the fill request and should always point to a 0x proxy contract.

This resolved the potential exploit threat, and we additionally implemented pausable logic to the contract to allow for the zap processes to be halted, rather than requiring an entire protocol halt which was required this time.

Event Timeline

Takeaway

The primary takeaway of this incident for the NFTX team is that future periphery smart contracts must be treated with the same caution as core smart contracts, especially when they receive authorization of users’ assets. Going forward, any periphery contracts will be audited before deployment, including the updated NFTXMarketplace0xZap contract which is being prepared for audit now.

Next Steps

While the only risk for the NFTXMarketplace0xZap is if it is used with the vault factory contract (which it can no longer do due to the hardcoded deny list) we believe it is best practice to revoke any access the NFTXMarketplace0xZap contract has to your NFTs if they are not to be of use.

  1. Go to https://revoke.cash/
  2. Connect your account
  3. Find any mentions of 0xbbc53022Af15Bb973AD906577c84784c47C14371
  4. Click on the revoke button
Loading...