Normal behavior
The contract collects protocol fees from NFT sales and tracks them using totalFeesCollected. These fees are expected to remain available in the contract and be withdrawable by the owner via withdrawFees().
Issue
Fees are only tracked via a storage variable and are not explicitly segregated from the contract’s USDC balance. Seller payouts are executed from the same shared pool that includes fees, meaning the contract implicitly relies on perfect balance alignment. Any small reduction in the contract’s balance causes totalFeesCollected to exceed actual funds, leading to withdrawFees() reverting and permanently* locking protocol fees.
Likelihood: MEDIUM
Occurs when the contract balance deviates slightly from expected accounting due to rounding, integration changes, or unexpected token behavior
Arises during normal operation as multiple trades and balance movements accumulate over time
Impact: HIGH
withdrawFees() can revert permanently* once fees are not fully backed
Protocol fees become locked and unclaimable, resulting in direct financial loss
Note on “permanent” revert:
The revert is considered permanent because once totalFeesCollected exceeds the contract’s actual token balance, there is no mechanism in the contract to restore consistency between accounting and available funds. The withdrawFees() function will continue to attempt transferring the full totalFeesCollected amount, which will always exceed the available balance and therefore always revert. Since the contract does not provide any way to reduce totalFeesCollected or recover the missing funds, fee withdrawals become indefinitely impossible.
Defensive check (fallback)
Ensure fees are never used to pay sellers.
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.
The contest is complete and the rewards are being distributed.