Skip to content

feat: add SwapProxy contract for permit2-less swap flow#469

Open
marktoda wants to merge 10 commits intomainfrom
feat/approve-proxy
Open

feat: add SwapProxy contract for permit2-less swap flow#469
marktoda wants to merge 10 commits intomainfrom
feat/approve-proxy

Conversation

@marktoda
Copy link
Contributor

@marktoda marktoda commented Feb 20, 2026


✨ Claude-Generated Content

Summary

Introduces a stateless SwapProxy contract that enables a 2-transaction swap flow (approve + swap) without requiring Permit2 signed messages. This provides an alternative integration path for platforms that cannot or prefer not to support EIP-712 signed permits.

Changes

  • Add SwapProxy.sol contract that pulls ERC20 tokens from users directly into the Universal Router, then executes UR commands with payerIsUser=false
  • Add ISwapProxy.sol interface with NatSpec documentation
  • Add DeploySwapProxy.s.sol deployment script
  • Add comprehensive Foundry tests covering:
    • Exact input swaps via proxy
    • Exact output swaps with sweep for unused tokens
    • Revert on insufficient approval
    • Revert on expired deadline
    • Token safety checks (no tokens stuck in proxy/router)
    • Gas comparison benchmark vs direct Permit2 flow

How It Works

User -> approve SwapProxy (one-time)
User -> SwapProxy.execute() (each swap)
         |-> transferFrom(user -> UR, amount)
         |-> UR.execute(commands, inputs, deadline)

Integration Notes

  • All swap commands must use payerIsUser=false
  • All recipient addresses must be the user's explicit address, NOT MSG_SENDER (which resolves to the proxy contract)
  • For exact output swaps, include a SWEEP command to return unused input tokens
  • This contract is for token-input actions; ETH-input actions should be sent directly to the UR

@marktoda marktoda requested a review from a team as a code owner February 20, 2026 22:47
@github-actions
Copy link

github-actions bot commented Feb 20, 2026

🤖 Claude Code Review

Review complete

Clean, minimal proxy contract that enables a 2-tx (approve + swap) flow without Permit2 signatures. The design is sound:

  • Stateless, no constructor, no storage -- minimal attack surface
  • router as a parameter (per hensha256's feedback) avoids re-approvals on UR upgrades
  • payable removed (per earlier review discussion) since this contract is for token inputs only
  • Tokens transfer atomically with router.execute, so a revert in the router rolls back the transfer too
  • Solmate's SafeTransferLib no-code-check caveat is documented inline

One consideration worth noting:

router parameter is caller-controlled: The user specifies which router to send tokens to and call execute on. This is fine since the caller is spending their own allowance -- a malicious router address only harms the caller themselves. But integrators should be aware that frontends must ensure the router address is correct, as a compromised frontend could direct tokens to a malicious contract. This is inherent to the design and documented well enough in the NatSpec.

Tests cover the main flows (exact in, exact out + sweep, reverts, no stuck tokens, gas comparison). Looks good to ship.


💡 Want a fresh review? Add a comment containing @request-claude-review to trigger a new review at any time.

@github-actions github-actions bot changed the title Feat/approve proxy feat: add SwapProxy contract for permit2-less swap flow Feb 20, 2026
github-actions[bot]
github-actions bot previously approved these changes Feb 20, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

@marktoda marktoda requested a review from hensha256 February 20, 2026 22:51
@github-actions github-actions bot dismissed their stale review February 20, 2026 22:52

Superseded by new review after PR update

github-actions[bot]
github-actions bot previously approved these changes Feb 20, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

@github-actions github-actions bot dismissed their stale review February 23, 2026 22:15

Superseded by new review after PR update

github-actions[bot]
github-actions bot previously approved these changes Feb 23, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

marktoda and others added 5 commits February 23, 2026 17:15
External proxy contract that enables a 2-transaction swap flow
(approve + swap) without requiring Permit2 signed messages.
Addresses integrator feedback about the 3-tx first-time flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot dismissed their stale review February 23, 2026 22:17

Superseded by new review after PR update

github-actions[bot]
github-actions bot previously approved these changes Feb 23, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

@github-actions github-actions bot dismissed their stale review February 25, 2026 22:30

Superseded by new review after PR update

github-actions[bot]
github-actions bot previously approved these changes Feb 25, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

@github-actions github-actions bot dismissed their stale review February 25, 2026 22:31

Superseded by new review after PR update

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

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