Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: high
Invalid

The BuyerAgent initialization is not strictly verified, allowing anyone to create their own version of BuyerAgent, which can break some of the contract's invariants.

Summary

The BuyerAgent contract is deployed by a contract called BuyerAgentFactory by default. However, in Swan, it's not verified that the contract was actually deployed by this factory, allowing anyone to create their own version of the BuyerAgent contract and bypass essential checks (such as buyer phases and protections against frontrunning attacks).

Vulnerability Details

The Swan contract allows users to trade their NFTs with other users, who are represented by the BuyerAgent contract. A seller can list their asset for a specific user as seen here: https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/swan/Swan.sol#L157-L191, enabling that user to purchase it during a special phase of the BuyerAgent contract: https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/swan/Swan.sol#L276-L302.

The issue with this setup is that any address can serve as a buyer since there is no verification that it was actually deployed by BuyerAgentFactory. This means any user can deploy a BuyerAgent contract with custom logic.

This could lead to the following attack:

  1. Alice is an active user of Swan. Because she makes many sales, she has approved the fee token up to a value of uint256.max to the Swan contract to avoid transaction fees on each sale.

  2. Alice sends a transaction to the mempool to list an asset.

  3. Bob sees this and decides to frontrun the transaction by updating his royaltyFee() to match the total allowance of the token Alice owns, which will be used to pay the royalties. Bob can frontrun this transaction because the BuyerAgent deployment source is unchecked, allowing him to deploy an identical contract with minor modifications to setFeeRoyalty by removing all checks, thus enabling him to update the fee at any time: https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/swan/BuyerAgent.sol#L380-L387.

  4. Alice lists her asset and sends all of her tokens to the protocol, with Bob collecting these in the transferRoyalties function: https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/swan/Swan.sol#L265-L271.

Impact

All BuyerAgent invariants are broken, and buyers can frontrun sellers to steal all tokens that the seller has approved for the contract.

Tools Used

Manual review.

Recommendations

Add a strict check to ensure that the BuyerAgent was deployed by BuyerAgentFactory. This will prevent buyers from adding custom logic to the contract and circumventing these invariants.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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