redeem-convert-auto — Auto-redeem plus USDC.e → pUSD wrapper

Superset of redeem-auto. Also wraps on-chain USDC.e into pUSD via Polymarket's CollateralOnramp using the builder relayer. Required after V2/pUSD migration if any market still pays USDC.e.

Version v1.0.0 · One-time payment · Source code download
Strategy typeUtility
AssetAll
Timeframe
Market typeAll Polymarket markets
Minimum capital$0
Dependencies@polymarket/clob-client-v2, @polymarket/builder-relayer-client, ethers

What it does

redeem-convert-auto is a strict superset of redeem-auto. Every cycle (default every 5 minutes), it does two things:

  1. Redeem: if CLOB cash balance < threshold, spawn tools/redeem.js --live to claim resolved positions on-chain.
  2. Convert: read the wallet's on-chain USDC.e balance. If above the wrap minimum (default $0.10), call CollateralOnramp.wrap(USDC_E, owner, amount) through Polymarket's builder relayer to convert the USDC.e to pUSD. Auto-approves USDC.e for the Onramp on first use.

The edge

After Polymarket's V2 migration, the CLOB trades in pUSD, but the CTF redemption pathway for legacy markets still pays out in USDC.e. Without a wrap step, your winnings accumulate as USDC.e dust that the bots can't see as collateral. The first time the redemption happens after a winning resolution, you discover this the hard way: CLOB balance shows $0 even though the wallet holds $40+ USDC.e on-chain.

This script eliminates that gap by wrapping in the same loop. After every redeem, it checks the on-chain wallet and converts any USDC.e it finds to pUSD via the official Polymarket Onramp contract.

How it works

loop { cash = await CLOB.getBalanceAllowance('COLLATERAL') // pUSD on CLOB if cash < THRESHOLD: spawn('node tools/redeem.js --live') bals = on-chain wallet balances (USDC.e + pUSD + allowance) if bals.usdce >= WRAP_MIN: if allowance < usdce: approve(USDC_E, ONRAMP, MaxUint256) wrap(USDC_E, owner, bals.usdceRaw) // via builder relayer sleep INTERVAL_SEC }

Contracts used (Polygon mainnet):

USDC.e 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 pUSD 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB CollateralOnramp 0x93070a847efEf7F70739046A929D47a521F5B8ee

Transactions are submitted via @polymarket/builder-relayer-client using your proxy wallet — exactly the same path the Polymarket UI uses for on-chain actions, so the gas is sponsored.

Approval is "max" (MaxUint256) on first use so you never have to pay for it again.

Sample output

[25/05/2026, 17:00:00] Auto redeem+convert started | threshold=$20 | wrap-min=$0.10 | interval=300s [25/05/2026, 17:00:02] Cash (pUSD on CLOB): $34.50 | Threshold: $20.00 [25/05/2026, 17:00:03] On-chain pUSD: $0.00 USDC.e: $0.00 [25/05/2026, 17:10:01] Cash (pUSD on CLOB): $18.40 | Threshold: $20.00 [25/05/2026, 17:10:01] Cash below threshold — triggering redeem [25/05/2026, 17:10:18] On-chain pUSD: $0.00 USDC.e: $42.13 [25/05/2026, 17:10:18] Wrapping $42.13 USDC.e → pUSD (approving first) [25/05/2026, 17:10:24] Wrap submitted: txID=relay-9c4e8f1a [25/05/2026, 17:10:39] Wrap confirmed: 0xabc12345... [25/05/2026, 17:10:42] Post-wrap pUSD: $42.13 USDC.e: $0.00

Design targets

End-to-end latency from a winning resolution to spendable pUSD on CLOB:

  • Resolution → tools/redeem.js submitted: up to INTERVAL_SEC (default 5 min)
  • Redeem TX confirmation: ~3-15 seconds on Polygon
  • Wrap TX confirmation via relayer: 15-30 seconds (relayer poll + Polygon confirm)
  • pUSD visible on CLOB: immediate after wrap confirmation

Total: 5 min 30 sec worst case at default interval. Shorten the interval if your scalpers churn faster.

Live status

This is the script running on the author's wallet right now (PID rotates with each pm2 restart but the watcher has been continuous since April 30 2026).

FAQ

Do I need this if my bots use CLOB v2 / pUSD directly?

If every market your bots touch resolves directly in pUSD, redeem-auto is enough. But neg-risk markets and many older CTF markets still pay out in USDC.e on redemption, so unless you've audited every market you trade, redeem-convert-auto is the safer default.

What if the relayer is down?

The wrap call wraps in a try/catch. A relayer failure logs the error and the watcher continues. Next cycle re-attempts.

Can I run both redeem-auto and redeem-convert-auto?

No. They both spawn redeem.js --live and both would race. Pick one. redeem-convert-auto is a strict superset, so it's always the safe choice.

What's included

  • tools/redeem-convert-auto.js
  • tools/redeem.js
  • README with pm2 ecosystem.config.js example, contract address reference, and relayer recovery notes

Configuration

FlagDefaultDescription
--threshold 2020Cash balance threshold in USD. Triggers redeem when balance drops below.
--interval 300300Seconds between balance checks. Default 5 minutes.
--wrap-min 0.100.10Minimum USDC.e to wrap into pUSD. Skips dust below this.
--onceRun one check then exit.

Related bots