Dria

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

Second Buyer Creation Reverts Due to Pre-existing Approval If Swan.token() Uses A Token That Requires Zero Approval Before Re-approving Such As USDT

Summary

In the BuyerAgent contract, if the Swan contract's designated token is USDT, a user’s attempt to create a BuyerAgent for the second time will fail. This occurs because of a max approval set during BuyerAgent deployment in the constructor. Certain tokens, like USDT, require the allowance to be reset to zero before re-approval; without this, subsequent calls to the createBuyer function will revert.

Vulnerability Details

The BuyerAgent contract constructor grants a max allowance to the swan.coordinator and swan addresses:

swan.token().approve(address(swan.coordinator()), type(uint256).max);
swan.token().approve(address(swan), type(uint256).max);

For tokens like USDT, a non-zero allowance cannot be modified directly to another value without first being set to zero. If USDT is designated as the token in Swan.sol, attempts to create a second BuyerAgent with the createBuyer function will revert upon reaching the approve call due to the existing non-zero allowance.

Impact

  1. Swan contract designates USDT as the payment token.

  2. A user deploys a BuyerAgent using the createBuyer function, which sets a max allowance to swan.coordinator and swan.

  3. The user attempts to deploy a second BuyerAgent using createBuyer.

  4. The transaction fails when the contract attempts to set a max approval on USDT without first resetting it to zero.

Recommendations

Use safeApprove, which resets the allowance to zero before setting a new value, to prevent reverts when handling tokens like USDT.

Replace the following in the constructor:

swan.token().approve(address(swan.coordinator()), type(uint256).max);
swan.token().approve(address(swan), type(uint256).max);

With:

swan.token().safeApprove(address(swan.coordinator()), type(uint256).max);
swan.token().safeApprove(address(swan), type(uint256).max);

This adjustment ensures compatibility with tokens requiring a zero-allowance reset, thus supporting repeated BuyerAgent deployments with any designated token.

Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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