Skip to content

fix: route approve commands through proxy wallet#42

Open
mvanhorn wants to merge 3 commits intoPolymarket:mainfrom
mvanhorn:osc/4-approve-ctf-signature-type
Open

fix: route approve commands through proxy wallet#42
mvanhorn wants to merge 3 commits intoPolymarket:mainfrom
mvanhorn:osc/4-approve-ctf-signature-type

Conversation

@mvanhorn
Copy link

@mvanhorn mvanhorn commented Mar 10, 2026

Summary

Fixes approve and ctf commands ignoring --signature-type proxy, which caused all on-chain transactions to go from the EOA instead of the proxy wallet.

Fixes #4
Related: #1, #24

Changes

File Change
src/auth.rs Add resolve_wallet_address() that returns EOA, proxy, or Safe address based on signature type
src/main.rs Pass signature_type to approve and ctf commands
src/commands/approve.rs Route approve set through Proxy Wallet Factory when signature type is proxy; fix approve check to query the correct wallet
src/commands/ctf.rs Accept signature_type parameter for forward compatibility

How it works

approve check: Now resolves the wallet address based on --signature-type. With proxy, it queries allowances of the derived proxy wallet instead of the EOA, so users see their actual allowance status.

approve set: With --signature-type proxy, encodes USDC approve and CTF setApprovalForAll calls as calldata and routes them through the Proxy Wallet Factory at 0xaB45.... This batches both approvals per target into a single factory call, so the proxy wallet gets the approvals instead of the EOA.

ctf: Accepts --signature-type but does not yet route through proxy (marked for follow-up). This is a smaller, separable change.

Test plan

  • cargo fmt --check passes
  • cargo clippy -- -D warnings passes
  • cargo test - all 131 tests pass
  • Manual: polymarket approve check --signature-type proxy shows proxy wallet allowances
  • Manual: polymarket approve set --signature-type proxy sends approvals through factory

This contribution was developed with AI assistance (Claude Code).


Note

Medium Risk
Changes how on-chain approval transactions are constructed/sent (EOA vs proxy batching via factory), which could affect users’ allowances and trading readiness if mis-routed. Scope is limited to approval flow and wallet address resolution logic.

Overview
Fixes the approve command to honor --signature-type for both reading and writing approvals.

Adds auth::resolve_wallet_address() to derive the correct owner address (EOA, proxy wallet, or Gnosis Safe) for allowance/approval checks, and wires signature_type through main.rs into approve/ctf (the latter is parameter-only for now).

For approve set, proxy mode now batches USDC approve + CTF setApprovalForAll per target via the Proxy Wallet Factory (wallet_contract_config), while gnosis-safe mode is blocked with a message directing users to submit approvals via the Safe UI.

Written by Cursor Bugbot for commit 09aaa7a. This will update automatically on new commits. Configure here.

…e proxy

- `approve check` now queries the correct wallet (proxy or EOA) based on
  --signature-type, so users see actual allowances instead of zeros
- `approve set` with proxy signature type routes transactions through
  the Proxy Wallet Factory, batching USDC and CTF approvals per target
- `ctf` commands now accept --signature-type for forward compatibility

Fixes Polymarket#4
Related: Polymarket#1, Polymarket#24

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents silent routing breakage if DEFAULT_SIGNATURE_TYPE is ever
changed to a non-proxy value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
approve check uses resolve_wallet_address which returns the derived
Safe address for gnosis-safe, but approve set only handles proxy
and falls through to the EOA path. This would silently approve on
the wrong address. Add an early bail for gnosis-safe with guidance
to use the Safe wallet interface instead.
@mvanhorn
Copy link
Author

Addressed the gnosis-safe check/set inconsistency in 09aaa7a. approve set now rejects --signature-type gnosis-safe with a clear error directing users to submit approvals through their Safe wallet interface, since the CLI can't route transactions through the Safe execution flow. This prevents the silent mismatch where set would approve on the EOA but check would query the Safe address.

Re: the proxy check comparison - this is already comparing against the literal "proxy", not against DEFAULT_SIGNATURE_TYPE, so no change needed there.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.


for target in &targets {
step += 1;
let label = format!("USDC \u{2192} {} (proxy)", target.name);
Copy link

Choose a reason for hiding this comment

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

Proxy path label omits CTF approval information

Medium Severity

In the proxy path, each transaction batches both USDC approve and CTF setApprovalForAll into a single factory call, but the label is "USDC → {target} (proxy)" — it never mentions CTF. In the EOA path, users see separate "USDC → target" and "CTF → target" lines for each target. In the proxy path, there is zero indication that CTF approvals were also set, so users may believe they still need to approve CTF separately or that something went wrong.

Additional Locations (1)
Fix in Cursor Fix in Web

output: OutputFormat,
) -> Result<()> {
let sig_type = config::resolve_signature_type(signature_type)?;
let is_proxy = sig_type == "proxy";
Copy link

Choose a reason for hiding this comment

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

Fragile string comparison duplicates signature type matching logic

Low Severity

The set function in approve.rs duplicates the signature-type-to-behavior mapping from auth::parse_signature_type using hardcoded string literals ("proxy", "gnosis-safe") instead of reusing the existing enum-based logic. Notably, auth.rs uses the config::DEFAULT_SIGNATURE_TYPE constant while approve.rs uses the string literal "proxy" — if the constant ever changes, the two code paths would diverge silently.

Additional Locations (1)
Fix in Cursor Fix in Web

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.

approve set and all on-chain commands ignore --signature-type proxy, send txs from EOA

1 participant