Dria

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

BuyerAgent's Owner can steal fees paid by a user when listing an asset

Summary

https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/swan/BuyerAgent.sol

An attacker can create a BuyerAgent with attractiveroyaltyFee and an attractive amountPerRound, while the BuyerAgent has only the necessary funds corresponding to the OracleFee.
The user who wishes to list an asset with this agentBuyer will therefore pay royalityFee, even though the asset can never be purchased.
Buyeragent Owner can withdraw fees earned.

Vulnerability Details

An attacker can create a BuyerAgent with attractiveroyaltyFee and an attractive amountPerRound, while the BuyerAgent has only the necessary funds corresponding to the OracleFee. Indeed, there is no verification of the funds owned by BuyerAgent, who can put any amoutPerRound.

In the SELL phase, the user who wishes to list an asset with this BuyerAgent (because of the attractive fees and amountPerRound) will therefore pay royalityFee to the BuyerAgent.

In the BUY phase, no item listed for this buyerAgent will be purchased because he doesn't have the necessary funds.

In the WITHDRAW phase, the attacker will change the BuyerAgent amountPerRound to 0. Then, he will use the withdraw function to withdraw all the fees received.

Example :

The attacker create a buyerAgent with royalityFee = 4 and amountPerRound = 300.
Let's imagine that the fees for the oracle are 5. The attacker will deposit 5 with the transfer() function.
His mindFundAmount() is therefore 300 + 5 = 305.
While his balance is only 5.

During the SELL phase, 3 different users will list an item at 100 to this BuyAgent. They will each pay 100 * 0.04 = 4 to the BuyerAgent.
The Buyer Agent therefore receives 12 and his balance is now 12 + 5 = 17.

During the BUY phase, no item will be purchased because the BuyerAgent doesn't have the funds ( 17 < 100).

During the WITHDRAW phase, the BuyerAgent uses the setAmountPerRound function and sets its amountPerRound to 0.
His mindFundAmount() is now 5 .
It uses the withdraw() function to remove all stolen fees. He therefore withdraws 12.

Impact

The BuyerAgent steals the fees from the users listing the assets because the buyerAgent will never be able to buy the assets.

Tools Used

Manual verification

Recommendations

Verify before a user can list a asset that mindFundAmount() =< treasury()

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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