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(uint256price,addressexpectedPayingToken)privatereturns(uint256amount){ 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.
The following test demonstrates how minting with a small price results in platform fees being zeroed out.
1
Setup (initialize a Foundry project)
Initialize a Foundry project.
Paste the repository files mentioned in the test into the src folder.
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.)