IOP _ ThunderNFT 34605 - [Smart Contract - Critical] ERC tokens can be stolen because the amount is

Submitted on Sat Aug 17 2024 12:25:21 GMT-0400 (Atlantic Standard Time) by @Schnilch for IOP | ThunderNFT

Report ID: #34605

Report type: Smart Contract

Report severity: Critical

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

Impacts:

  • Direct theft of any user NFTs, whether at-rest or in-motion, other than unclaimed royalties

Description

Brief/Intro

In the update_order function in the Thunder Exchange contract, there is no validation to check whether a seller has increased the amount of ERC1155 tokens being sold. This allows someone to simply increase the amount of tokens being sold without sending those tokens to the contract. The order could then be canceled, and since the amount is too high, the seller would receive more tokens than they actually possess.

Vulnerability Details

On the exchange, ERC1155 tokens can also be sold. Since an ERC1155 token does not have to be unique, multiple tokens can be sold at once, which is why you can specify an amount when selling. In the place_order function, the amount is validated (see 1. reference). There it is checked whether the user actually sends the amount he specifies. If the order is then updated with update_order, an attacker can change the amount parameter, but it is not checked in the function (see 2. reference). Even in the strategy, the amount is not checked again and the order is simply overwritten. This means that an attacker can simply set any amount without transferring the tokens into the contract. If there are several users offering the same ERC1155 tokens, the attacker can steal all of these tokens by setting the amount of his sell order to the balance of the ERC1155 tokens that the thunder exchange has and then canceling his order with cancel_order. In doing so, he gets back the amount of tokens that are in the order (see 3. reference).

Impact Details

An attacker could steal all erc1155 tokens that are being sold, of which he himself has at least one, in order to be able to create an order. The attacker could also buy this one erc1155 token and then steal the others.

References

  1. https://github.com/ThunderFuel/smart-contracts/blob/260c9859e2cd28c188e8f6283469bcf57c9347de/contracts-v1/thunder_exchange/src/main.sw#L96-L102

  2. https://github.com/ThunderFuel/smart-contracts/blob/260c9859e2cd28c188e8f6283469bcf57c9347de/contracts-v1/thunder_exchange/src/main.sw#L124

  3. https://github.com/ThunderFuel/smart-contracts/blob/260c9859e2cd28c188e8f6283469bcf57c9347de/contracts-v1/thunder_exchange/src/main.sw#L155-L167

Proof of concept

Proof of Concept

Since the POC is in rust a bit of setup is needed. To do this, he following steps must be carried out:

  1. In the smart-contracts folder: cargo new thunder-tests

  2. Open the Cargo.toml in thunder-tests and add these dev-dependencies:

  1. Then this code needs to be inserted into thunder-tests/src/main.rs:

Since an erc1155 token is required for the POC, a smart contract must be created in the contracts-v1 folder:

  1. In contracts-v1: force new erc1155

  2. Add these dependencies to the Forc.toml of the erc1155 contract:

  1. Paste the code into contracts-v1/erc1155/src/main.sw (The code is mainly copied from https://docs.fuel.network/docs/sway/blockchain-development/native_assets/#multi-native-asset-example):

  1. Run forc build in all smart contract folders that are needed:

    • contracts-v1/asset_manager

    • contracts-v1/erc1155

    • contracts-v1/execution_manager

    • contracts-v1/execution_strategies/strategy_fixed_price_sale

    • contracts-v1/interfaces

    • contracts-v1/libraries

    • contracts-v1/pool

    • contracts-v1/royalty_manager

    • contracts-v1/thunder_exchange

  2. To run the PoC go to the thunder-tests folder and run this command: cargo test test_poc -- --nocapture

Last updated

Was this helpful?