The contract maintains an internal balances
mapping to track how many ERC20 tokens (fractions) each user owns. However, these ERC20 tokens are standard tokens that users can transfer outside the contract (e.g., via MetaMask, Uniswap, or other wallets). This creates a critical inconsistency: the contract’s internal balances
mapping does not reflect real on-chain ERC20 balances, leading to mismatched state and potential exploits.
Inability to Claim NFTs:
Users who acquire fractions outside the contract (e.g., via decentralized exchanges) cannot claim the NFT, as their internal balances
are not updated.
Fake Balances for Internal Logic:
Functions like sellErc20
and claimNft
rely on the stale balances
mapping. For example:
solidity
Copy
A user with a high internal balance but low real ERC20 balance can list tokens they don’t actually own.
Double-Spending Risk:
A malicious user could exploit the inconsistency:
Transfer ERC20 tokens out externally (real balance decreases).
Use the stale internal balances
to call sellErc20()
or claimNft()
.
POC
This test assumes a user Alice
and Bob
.
Alice mints the NFT and divide it into 1000 fractions.
Alice transfers 500 fractions to Bob DIRECTLY via ERC20 (bypassing TokenDivider)
Bob tries to claim the NFT for the fraction he received from Alice(50% in this case).
Because it did not update in the internal mapping, Bob fails the claim.
Remove the balances
Mapping:
Use the ERC20 token’s native balanceOf(address)
function to check real balances.
Example fix in claimNft()
:
solidity
Copy
Update All Functions:
Replace all balances[user][erc20]
references with direct ERC20 balance checks.
Remove the transferErcTokens()
function, as users can transfer ERC20 tokens directly.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.