Dria

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

Zero-Price Asset Relisting & Invalid Buyer Assignment in Swan Protocol

Summary

Swan.sol allows assets to be relisted with zero prices and to potentially invalid buyer addresses, compromising the protocol's economic model and asset management system.

Vulnerability Details

https://github.com/Cyfrin/2024-10-swan-dria/blob/c3f6f027ed51dd31f60b224506de2bc847243eb7/contracts/swan/Swan.sol#L197-L220

function relist(address _asset, address _buyer, uint256 _price) external {
AssetListing storage asset = listings[_asset];
// only the seller can relist the asset
if (asset.seller != msg.sender) {
revert Unauthorized(msg.sender);
}
// asset must be listed
if (asset.status != AssetStatus.Listed) {
revert InvalidStatus(asset.status, AssetStatus.Listed);
}
// @bug detected: Missing price validation allows zero-price relisting
// This can be used to manipulate market statistics and bypass fee calculations
// @bug detected: No validation that _buyer address is a valid BuyerAgent contract
// Malicious actors could relist to invalid addresses, breaking protocol assumptions
// relist can only happen after the round of its listing has ended
(uint256 oldRound,,) = BuyerAgent(asset.buyer).getRoundPhase();
if (oldRound <= asset.round) {
revert RoundNotFinished(_asset, asset.round);
}
  1. Zero-Price Vulnerability:

  • Allows relisting assets with zero price

  • Breaks core protocol invariants around value transfer

  • Enables fee evasion since percentage calculations on zero price equal zero

  • Can distort market statistics and price discovery mechanisms

  1. Buyer Validation Gap:

  • Missing validation of buyer address being a legitimate BuyerAgent contract

  • Could lead to assets being relisted to invalid addresses

  • Breaks core protocol assumptions about buyer behavior and round management

  • Potential for permanent asset locking if relisted to non-compliant contract addresses

Particularly dangerous because:

  • Exists in a core marketplace function

  • Can be exploited without special permissions (any seller can trigger)

  • Impact multiple protocol components (fees, rounds, asset management)

  • Break fundamental protocol invariants around asset pricing and buyer validation

Impact

Economic Impact:

  • Zero-price listings bypass fee calculations

  • Royalty payments become zero: uint256 buyerFee = (asset.price * asset.royaltyFee) / 100;

  • Platform fees avoided: uint256 driaFee = (buyerFee * getCurrentMarketParameters().platformFee) / 100;

Tools Used

Manual Review

Recommendations

modifier validPrice(uint256 price) {
require(price > 0, "Invalid price");
_;
}
modifier validBuyer(address buyer) {
require(IBuyerAgent(buyer).isValid(), "Invalid buyer");
_;
}
function relist(...) external validPrice(_price) validBuyer(_buyer) {
...
}
Updates

Lead Judging Commences

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

DOS the buyer / Lack of minimal amount of listing price

Support

FAQs

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