Root + Impact
Description
The protocol collects fees from each sale and the owner should be able to withdraw accumulated fees later.
The collectUsdcFromSelling function transfers the fee amount to address(this), which is the contract itself, accomplishing nothing and wasting gas.
solidity
function collectUsdcFromSelling(uint256 _listingId) external onlySeller(_listingId) {
Listing memory listing = s_listings[_listingId];
require(!listing.isActive, "Listing must be inactive to collect USDC");
uint256 fees = _calculateFees(listing.price);
uint256 amountToSeller = listing.price - fees;
uint256 collateralToReturn = collateralForMinting[listing.tokenId];
totalFeesCollected += fees;
amountToSeller += collateralToReturn;
@> usdc.safeTransfer(address(this), fees);
usdc.safeTransfer(msg.sender, amountToSeller);
}
Risk
Likelihood:
This happens every single time a seller collects their USDC after a sale
The fees are already sitting in the contract from when the buyer paid, so moving them to the same address does nothing
Impact:
Wastes gas on every collection
Makes the code confusing and harder to audit
The fee accounting doesn't work properly because the transfer is redundant
Proof of Concept
solidity
fees = 50 USDC
amountToSeller = 950 USDC + 20 collateral = 970 USDC
usdc.safeTransfer(address(this), 50);
usdc.safeTransfer(alice, 970);
Recommended Mitigation
diff
function collectUsdcFromSelling(uint256 _listingId) external onlySeller(_listingId) {
Listing memory listing = s_listings[_listingId];
require(!listing.isActive, "Listing must be inactive to collect USDC");
uint256 fees = _calculateFees(listing.price);
uint256 amountToSeller = listing.price - fees;
uint256 collateralToReturn = collateralForMinting[listing.tokenId];
totalFeesCollected += fees;
amountToSeller += collateralToReturn;
- usdc.safeTransfer(address(this), fees);
usdc.safeTransfer(msg.sender, amountToSeller);
}