Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: low
Valid

Fee Calculations Can Be Exploited to Avoid Protocol Fees Due to Rounding Errors

Vulnerability Details

The protocol uses 100 as the denominator for percentage calculations, which not only leads to precision loss but can be exploited by sellers to completely avoid paying protocol fees.

Swan.sol#L257-L272

/// @notice Function to transfer the royalties to the seller & Dria.
function transferRoyalties(AssetListing storage asset) internal {
// calculate fees
uint256 buyerFee = (asset.price * asset.royaltyFee) / 100;
uint256 driaFee = (buyerFee * getCurrentMarketParameters().platformFee) / 100;
// first, Swan receives the entire fee from seller
// this allows only one approval from the seller's side
token.transferFrom(asset.seller, address(this), buyerFee);
// send the buyer's portion to them
token.transfer(asset.buyer, buyerFee - driaFee);
// then it sends the remaining to Swan owner
token.transfer(owner(), driaFee);
}

Scenario:

price = 99 // Seller carefully chooses this price
royaltyFee = 1 // Buyer sets minimal royalty fee (according to value set in test/BuyerAgent.test.ts)
platformFee = 1 // Protocol fee (1%) (according to value set in test/BuyerAgent.test.ts)
buyerFee = (99 * 1) / 100 = 0.99 -> 0 // Rounds down to 0 due to integer division
driaFee = (0 * 1) / 100 = 0 // No protocol fee paid!

A malicious seller can:

  1. Choose specific prices that cause rounding down to zero

  2. Completely avoid paying protocol fees while still selling assets

  3. Create multiple listings with carefully calculated prices to maximize this exploit

Impact

  1. Protocol fees can be completely bypassed

  2. Direct loss of revenue for the protocol and the buyers

Recommendations

  1. Use industry-standard precision with 10_000 as denominator.

  2. And/or add minimum fee thresholds to be paid or the function reverts.

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Rounding Issue in `Swan.sol::transferRoyalties` function

Support

FAQs

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