Dria

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

Denial of Service (DoS) Attack in Buyer Agent’s Purchase For A Full Round

Summary

The Swan.sol contract allows anyone to list a token, leading to the deployment of a SwanAsset for that token. Upon deployment, the Swan contract is approved to spend all tokens of the asset. A malicious user can exploit this by listing an asset and then revoking the approval for the Swan contract. This action can result in a Denial of Service (DoS) against the Buyer Agent, preventing it from purchasing any assets in that round.

Vulnerability Details

Vulnerable Components

  • Swan.sol: The purchase() function, which facilitates asset transfers from sellers to buyers.

  • BuyerAgent.sol: The purchase() function that handles batch purchases of assets in a round.

Description of the Vulnerability

  1. Asset Listing and Approval:

    • In the Swan.sol contract, any user can list a token, which automatically approves the Swan contract to manage the token’s assets.

    • Upon listing, the Swan contract is granted permission to transfer the asset on behalf of the seller.

  2. Malicious Behavior:

    • A malicious user can revoke the approval for the Swan contract by calling the setApprovalForAll function and setting it to false after listing the asset.

  3. Impact on Purchase Functionality:

    • The purchase() function in Swan.sol executes the following operations to transfer ownership of the asset:

      // transfer asset from seller to Swan, and then from Swan to buyer
      SwanAsset(_asset).transferFrom(listing.seller, address(this), 1);
      SwanAsset(_asset).transferFrom(address(this), listing.buyer, 1);
    • If the approval has been revoked, the call to transferFrom will fail, leading to a revert.

  4. Buyer Agent Purchase Loop:

    • The BuyerAgent contract's purchase() function is designed to batch process all asset purchases in a single transaction:

      function purchase() external onlyAuthorized {
      ------ SKIP -------
      for (uint256 i = 0; i < assets.length; i++) {
      swan.purchase(asset); // @audit vulnerable to DoS if approval is revoked
      }
      ------- SKIP --------
      }
    • If any individual call to swan.purchase(asset) fails due to the lack of approval, the entire loop will revert, causing the Buyer Agent to be unable to complete any purchases for that round.

The DoS vulnerability ensures that legitimate buyers cannot successfully complete any asset purchases during that round, leading to financial losses and undermining the intended functionality of the asset sale process.

Recommendations

To mitigate this vulnerability:

  • Modify the BuyerAgent purchase() function to handle individual purchase failures gracefully. Implement a try/catch mechanism or a similar approach to allow the batch process to continue even if some purchases fail:

    for (uint256 i = 0; i < assets.length; i++) {
    address asset = assets[i];
    try swan.purchase(asset) {
    // Handle successful purchase
    } catch {
    emit PurchaseFailed(asset); // Log failed purchase attempt
    // Continue with the next asset
    }
    }
Updates

Lead Judging Commences

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

DoS in BuyerAgent::purchase

Support

FAQs

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