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).
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:
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.
Alice sends a transaction to the mempool to list an asset.
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.
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.
All BuyerAgent invariants are broken, and buyers can frontrun sellers to steal all tokens that the seller has approved for the contract.
Manual review.
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.