Skip to content

fix(permit2-sdk): check signature-transfer nonce against the owner - #701

Open
SashaMIT wants to merge 1 commit into
Uniswap:mainfrom
SashaMIT:fix/permit2-sdk-owner-nonce
Open

SashaMIT wants to merge 1 commit into
Uniswap:mainfrom
SashaMIT:fix/permit2-sdk-owner-nonce

Conversation

@SashaMIT

Copy link
Copy Markdown

PR Scope

fix(permit2-sdk): correctness of isPermitValid / validatePermit.

Description

SignatureProvider.isNonceUsed documents its first argument as the owner and calls permit2.nonceBitmap(owner, wordPos). validatePermit passed permit.spender instead.

Permit2 signature-transfer nonces are keyed by the EIP-712 signer. After the owner spends nonce N, the spender (usually a router) still has that bit unset. isPermitValid returned true. On-chain Permit2 still reverts InvalidNonce. The harmed caller is an off-chain consumer that treats this helper as the live-permit check (quotes, inventory, replay gates).

isPermitValid and validatePermit now take owner and check isNonceUsed(owner, nonce).

Threat model: the attacker already holds a spent owner nonce and a permit that names a spender whose bitmap bit is unused. The remaining library guard is this verify API. Checking the spender turns that guard into a no-op.

How Has This Been Tested?

Unit test spies isNonceUsed and asserts it is called with owner, not spender.

bun test src/providers/SignatureProvider.test.ts -t "owner nonce bitmap"

Revert-tested: putting permit.spender back makes that assertion fail.

tsc -p tsconfig.types.json clean. Existing fork-based tests need FORK_URL and were not re-run here. Call sites in this file now pass owner.

Are there any breaking changes?

Yes, TypeScript callers must pass owner as the second argument. The old one-argument form checked the wrong account, so keeping that signature would keep the fail-open. If you want this titled feat(breaking): and a major bump, I can retitle.

(Optional) Feedback Focus

Whether minor (changeset) vs major is the right version bump for the extra required argument.

Made with Cursor

nonceBitmap is keyed by the EIP-712 signer. validatePermit passed
the spender, so isPermitValid fail-opened after the owner nonce was spent.
@SashaMIT
SashaMIT requested a review from a team as a code owner August 19, 2026 05:47
@graphite-app
graphite-app Bot requested a review from a team September 18, 2026 05:52
@graphite-app
graphite-app Bot requested a review from a team September 18, 2026 05:52
@graphite-app

graphite-app Bot commented Sep 18, 2026

Copy link
Copy Markdown

Graphite Automations

"Request reviewers once CI passes on sdks monorepo" took an action on this PR • (09/18/26)

3 reviewers were added and 1 assignee was added to this PR based on Siyu Jiang (See-You John)'s automation.

This branch has not been deployed

No deployments
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.

1 participant