57877 sc high accesstoken creators can bypass fees so that platform address will receive 0 fees

Submitted on Oct 29th 2025 at 10:46:29 UTC by @ZestfulHedgehog609 for Audit Comp | Belongarrow-up-right

  • Report ID: #57877

  • Report Type: Smart Contract

  • Report severity: High

  • Target: https://github.com/immunefi-team/audit-comp-belong/blob/main/contracts/v2/tokens/AccessToken.sol

  • Impacts:

    • Theft of unclaimed royalties

    • Theft of unclaimed yield

Description

Brief/Intro

A user can create an AccessToken collection with the help of the Factory.sol::produce() function. Other users can mint these NFTs with their preferred metadata using the mintStaticPrice() or the mintDynamicPrice() functions for the amount specified by the owner of the NFT contract. A small fee is taken by the platform address when the NFTs are minted. But the owner of the NFT can choose an NFT mint price such that no fees are sent to the platform address and the full mint price is transferred to the NFT owner.

Vulnerability Details

The problem is in the _pay() function.

function _pay(uint256 price, address expectedPayingToken) private returns (uint256 amount) {
    AccessTokenParameters memory _parameters = parameters;
    Factory.FactoryParameters memory factoryParameters = _parameters.factory.nftFactoryParameters();

    amount = expectedPayingToken == NATIVE_CURRENCY_ADDRESS ? msg.value : price;

    require(amount == price, IncorrectNativeCurrencyAmountSent(amount));

    uint256 fees = (amount * factoryParameters.platformCommission) / PLATFORM_COMISSION_DENOMINATOR;
    //999*10/10,000 ==0.
    uint256 amountToCreator;
    unchecked {
        amountToCreator = amount - fees;
        // full price of the nft amount to the creator because fees=0.
    }
}
/////
//// rest of the code
////
 if (expectedPayingToken == NATIVE_CURRENCY_ADDRESS) {
    if (fees > 0) {
        factoryParameters.platformAddress.safeTransferETH(fees);
        // This line will not trigger because fees is 0
    }
    if (referralFees > 0) {
        refferalCreator.safeTransferETH(referralFees);
    }
    _parameters.creator.safeTransferETH(amountToCreator);
    // Full amount is transfered to the creator of the nft.
}

When calculating the fees, a user can make the price of the NFT so small that amount * factoryParameters.platformCommission is less than PLATFORM_COMISSION_DENOMINATOR. Due to integer division/truncation in Solidity, this results in fees being 0. There is no subsequent check inside the function to prevent fees == 0. Therefore the full amount is sent to the creator of the NFT and the platform receives no fee.

Impact Details

The platform will suffer a loss because it will not receive any fees from the minting of these NFTs. NFT owners can set many NFTs to low prices so that they avoid platform fees entirely.

References

  • https://github.com/immunefi-team/audit-comp-belong/blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v2/tokens/AccessToken.sol#L320

  • https://github.com/immunefi-team/audit-comp-belong/blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v2/tokens/AccessToken.sol#L328

Proof of Concept

The following test demonstrates how minting with a small price results in platform fees being zeroed out.

1

Setup (initialize a Foundry project)

  1. Initialize a Foundry project.

  2. Paste the repository files mentioned in the test into the src folder.

  3. Create a test file called AccesTokenTest.t.sol in the test folder.

2

Run the test

Run:

3

Test code

Paste the following test into test/AccesTokenTest.t.sol:

4

Expected / Observed result

Logs from the test run:

  • Ran 1 test for test/AccesTokenTest.t.sol:AccesTokenTest

  • [PASS] test_Bypass_Platform_Fee() (gas: 952889)

Observed logs:

  • balance of user before nft purchase: 0

  • balance of user after nft purchase: 999

  • balance of platform fee receiver: 0

As shown, the platform received 0 fees while the creator received the full mint amount.

Notes

  • The vulnerability arises from integer truncation when computing small fee amounts: (amount * platformCommission) / PLATFORM_COMISSION_DENOMINATOR can evaluate to zero for small amounts.

  • Mitigation approaches (not exhaustive and not added to the report text): enforce a minimum fee floor, revert when fees == 0 and platformCommission > 0, or compute fees using higher precision (e.g., require price >= denominator / gcd(denominator, platformCommission) or use fixed-point arithmetic). (No fixes were added to source code here; these are general mitigation ideas and are not part of the original report.)

Was this helpful?