# Only one GroupBuy can ever use USDT or similar tokens with front-running approval protections

SeaportLister calls approve(conduit, max) without resetting to zero, so USDT-like tokens revert on relisting, bricking ERC20 listings for a vault.

- Payout: Contest reward
- Severity: medium
- Program: Tessera
- Credited: IllIllI
- Disclosed: 2023-04-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-tessera-findings/issues/37
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-tessera%3AM-06
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:dos

**Target:** SeaportLister.validateListing ERC20 approval path
**Root cause:** validateListing unconditionally calls IERC20(token).approve(conduit, type(uint256).max) without first setting allowance to zero; tokens like USDT revert on non-zero-to-non-zero approval changes.
**Steps:**
1. Vault lists an ERC20 (e.g. USDT) via SeaportLister; approve(conduit, max) succeeds from zero allowance.
2. Order partially fills, reducing allowance below max.
3. Vault attempts to relist same ERC20; validateListing calls approve(conduit, max) again.
4. USDT-style token reverts since current allowance is non-zero; listing/order reverts permanently.
**How found:** Code review of SeaportLister.validateListing approval logic combined with knowledge of USDT's non-zero-to-non-zero approve restriction; noted conduit is immutable so no workaround.
**Insight:** When a contract sets max ERC20 allowance to a fixed spender, check whether partial fills can leave a non-zero allowance; USDT-like tokens then permanently block re-approval unless you approve(0) first.
