IOP _ ThunderNFT 34966 - [Smart Contract - High] Royalty or protocol fee of will DoS executing order

Submitted on Mon Sep 02 2024 00:01:57 GMT-0400 (Atlantic Standard Time) by @SimaoAmaro for IOP | ThunderNFT

Report ID: #34966

Report type: Smart Contract

Report severity: High

Target: https://github.com/ThunderFuel/smart-contracts/tree/main/contracts-v1/thunder_exchange

Impacts:

  • Temporary freezing of NFTs for at least 1 hour

  • Temporary freezing of funds for at least 1 hour

Description

Brief/Intro

In the ThunderExchange when executing an order, a royalty fee and/or a protocol fee is charged on the buyer of the nft. When the fee is 0, it reverts due to calling transfer() with a null amount.

Vulnerability Details

ThunderExchange::_transfer_fees_and_funds() and ThunderExchange::_transfer_fees_and_funds_with_pool() calculate the protocol fee and royalty fee and transfer this amount to the corresponding addresses.

However, if these fees are set to 0, but the royalty info has been registered or the protocol_fee_recipient has been set, it will revert due to trying to transfer an amount of 0.

Impact Details

Executing orders will be DoSed until the royalty owner or the protocol increases the fee (it can not be deregistered nor the owner can be set no none).

References

https://github.com/ThunderFuel/smart-contracts/blob/main/contracts-v1/thunder_exchange/src/main.sw

Proof of concept

Proof of Concept

To run a proof of concept, the exchange was modified to allow a maker of type Contract, as Sway tests do not support pranking an EOA.

Additionally, 3 new contracts were created, one user contract simulating a user placing an order and being the owner of a collection, another user contract simulating a user executing the order and a erc1155 contract, simulating an erc1155 token.

The full changes were pushed to a github repository which can be shared with the team if requested.

The main test file is the following:

The user contract placing the order and registering the royalty is:

The user contract executing the order is:

Last updated

Was this helpful?