NFT Dealers

First Flight #58
Beginner FriendlyFoundry
100 EXP
Submission Details
Impact: low
Likelihood: medium

Fee transfer in `collectUsdcFromSelling` is a self-transfer no-op — fees never isolated

Author Revealed upon completion

Root + Impact

Description

  • Line 181 executes usdc.safeTransfer(address(this), fees) — the contract sends USDC to itself, which is a no-op. Fees are tracked only via totalFeesCollected but never separated from user funds.

usdc.safeTransfer(address(this), fees); // @> no-op: contract sends to itself
usdc.safeTransfer(msg.sender, amountToSeller);

Risk

Likelihood:

  • Executes on every call to collectUsdcFromSelling

Impact:

  • Wasted gas. No ring-fenced fee balance — withdrawFees() draws from the same pool as user collateral

Proof of Concept

Calling collectUsdcFromSelling triggers usdc.safeTransfer(address(this), fees) which transfers USDC from the contract to itself — a no-op that costs gas. The contract balance does not change from this call; only the subsequent safeTransfer(msg.sender, amountToSeller) moves funds.

Recommended Mitigation

Remove the self-transfer. The fee accounting via totalFeesCollected is sufficient since the contract already retains fees worth of USDC by only sending price - fees + collateral to the seller.

totalFeesCollected += fees;
amountToSeller += collateralToReturn;
- usdc.safeTransfer(address(this), fees);
usdc.safeTransfer(msg.sender, amountToSeller);

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!