Skip to content

fix(erc20Fulfillment): skip ERC20 preflight for partial fills - #1993

Closed
MrFaruk0 wants to merge 1 commit into
ProjectOpenSea:mainfrom
MrFaruk0:fix/erc20-partial-fill
Closed

fix(erc20Fulfillment): skip ERC20 preflight for partial fills#1993
MrFaruk0 wants to merge 1 commit into
ProjectOpenSea:mainfrom
MrFaruk0:fix/erc20-partial-fill

Conversation

@MrFaruk0

Copy link
Copy Markdown

Summary

Fixes a false-positive ERC20 balance/allowance preflight for partial fills.

For AdvancedOrder partial fills, getErc20Payment() previously summed the full ERC20 consideration without accounting for the order's numerator / denominator. This could cause a valid partial fill to be rejected before sendTransaction() because the SDK checked the buyer against the full-order payment amount.

Changes

  • Detect fractional AdvancedOrder fills in getErc20Payment().
  • Preserve the existing ERC20 spendability preflight for confidently readable full fills.
  • Fail open and skip the optional preflight for partial or unmodelable fractions instead of incorrectly checking the full-order amount.
  • Leave standard orders, basic orders, and private-listing behavior unchanged.

The implementation intentionally does not scale the aggregate consideration by the fraction. Seaport applies fractions per consideration item and enforces exact divisibility, so aggregate-first scaling could produce incorrect results.

Tests

Added regression coverage for:

  • partial ERC20 AdvancedOrder fills skipping the incorrect full-order preflight
  • partial fills proceeding past the preflight when balance and allowance cover the actual fill
  • full fills continuing to enforce ERC20 balance checks
  • full fills continuing to enforce ERC20 allowance checks
  • equivalent positive full-fill fractions such as 2/2
  • malformed or unsupported fractions failing open without introducing a new blocking validation path

@ryanio

ryanio commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

This is the most valuable contribution in the current batch, so thank you. Summing the full order's consideration for a partial fill made requireErc20PaymentIsSpendable throw "Insufficient balance" at a buyer who could comfortably afford the fill, which is about the worst failure mode a preflight can have.

Failing open is also exactly what the function already promised in its own docstring: it returns null for anything it cannot read with confidence so an unfamiliar response shape can never block a working purchase. Your change brings the code back in line with that.

This repo is a read-only mirror, so it is recreated in our internal monorepo with you credited as co-author and ships in the next release. Closing in favor of that.

@ryanio ryanio closed this Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants