All trading on Kuest is denominated in USDC (USD Coin), a stablecoin pegged 1:1 to the US dollar.
Why USDC?
Stable value
1 USDC = $1 USD always
Native on Polygon
No bridging required
Widely accepted
Compatible with Polymarket
Redeemable
Convert to USD anytime
USDC contract addresses
Network: Polygon (Chain ID 137)
USDC: 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359
Decimals: 6
Symbol: USDC
Network: Polygon Amoy (Chain ID 80002)
USDC: 0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582
Decimals: 6
Symbol: USDC
From src/lib/contracts.ts:
import { IS_TEST_MODE } from '@/lib/network'
export const NATIVE_USDC_TOKEN_ADDRESS = IS_TEST_MODE
? '0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582' as `0x${string}`
: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359' as `0x${string}`
export const COLLATERAL_TOKEN_ADDRESS = IS_TEST_MODE
? '0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582' as `0x${string}`
: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174' as `0x${string}`
Native USDC is the current standard. The older bridged USDC.e is supported for backwards compatibility.
Get USDC on Polygon
Option 1: Centralized exchanges
Buy USDC on exchange
Purchase USDC on Coinbase, Binance, or Kraken.
Select Polygon network
When withdrawing, choose Polygon (not Ethereum!).
Enter your wallet address
Paste your Polygon wallet address.
Confirm withdrawal
USDC arrives in 2-5 minutes.
Selecting the wrong network will result in lost funds. Always verify you’re using Polygon.
Option 2: Bridge from Ethereum
Bridge USDC from Ethereum to Polygon:
import { LiFi } from '@lifi/sdk'
const lifi = new LiFi()
const route = await lifi.getRoutes({
fromChainId: 1, // Ethereum
toChainId: 137, // Polygon
fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum
toTokenAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', // USDC on Polygon
fromAmount: '100000000', // 100 USDC (6 decimals)
fromAddress: walletAddress,
})
// Execute bridge
await lifi.executeRoute(route)
Kuest integrates LI.FI for cross-chain swaps (see src/lib/lifi.ts).
Option 3: On-ramp services
Buy USDC directly with credit card or bank transfer:
- Transak: Integrated in Kuest UI
- Ramp Network: Low fees
- MoonPay: Fast processing
Check USDC balance
Using wagmi
Using viem
Using ethers
import { useBalance } from 'wagmi'
import { NATIVE_USDC_TOKEN_ADDRESS } from '@/lib/contracts'
const { data: balance } = useBalance({
address: walletAddress,
token: NATIVE_USDC_TOKEN_ADDRESS,
})
console.log('USDC balance:', balance?.formatted)
import { createPublicClient, http } from 'viem'
import { polygon } from 'viem/chains'
const client = createPublicClient({
chain: polygon,
transport: http(),
})
const balance = await client.readContract({
address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
abi: [{
name: 'balanceOf',
type: 'function',
stateMutability: 'view',
inputs: [{ type: 'address' }],
outputs: [{ type: 'uint256' }],
}],
functionName: 'balanceOf',
args: [walletAddress],
})
console.log('Balance:', Number(balance) / 1e6, 'USDC')
import { ethers } from 'ethers'
const USDC_ABI = ['function balanceOf(address) view returns (uint256)']
const usdcContract = new ethers.Contract(
'0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
USDC_ABI,
provider
)
const balance = await usdcContract.balanceOf(walletAddress)
console.log('Balance:', ethers.formatUnits(balance, 6), 'USDC')
USDC has 6 decimals (not 18 like most tokens). 1 USDC = 1,000,000 smallest units.
Approve USDC for trading
Before trading, approve the CTF Exchange contract to spend your USDC:
import { useWriteContract } from 'wagmi'
import { NATIVE_USDC_TOKEN_ADDRESS, CTF_EXCHANGE_ADDRESS } from '@/lib/contracts'
const { writeContract } = useWriteContract()
// Approve unlimited USDC (recommended for trading)
await writeContract({
address: NATIVE_USDC_TOKEN_ADDRESS,
abi: [{
name: 'approve',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'spender', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
outputs: [{ name: 'success', type: 'bool' }],
}],
functionName: 'approve',
args: [
CTF_EXCHANGE_ADDRESS,
BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'),
],
})
Approving max uint256 avoids repeated approvals. You can revoke anytime by approving 0.
Trading with USDC
When you place a trade, USDC is automatically:
- Locked in the order book
- Minted into shares when matched
- Released when shares are sold
- Redeemed at settlement (winning shares → 1 USDC)
Example: Buy YES shares
// Buy 10 YES shares at 0.65 USDC each
// Cost: 10 × 0.65 = 6.5 USDC
const order = await placeOrder({
market_id: '0x123...',
side: 'BUY',
outcome: 'YES',
price: 0.65,
size: 10,
})
// USDC is locked until order fills
// When filled, you receive 10 YES shares
// If YES wins, shares redeem for 10 USDC
// Profit: 10 - 6.5 = 3.5 USDC
Understanding share minting
Prediction market shares are collateralized:
- 1 YES + 1 NO = 1 USDC locked
- When you buy YES at 0.65, someone sells NO at 0.35
- Total: 0.65 + 0.35 = 1.00 USDC
From src/lib/contracts.ts:
export const CONDITIONAL_TOKENS_CONTRACT = '0x4682048725865bf17067bd85fF518527A262A9C7'
This contract mints outcome tokens backed by USDC collateral.
Withdraw USDC
Redeem winning shares or withdraw unused USDC:
Redeem winning shares
import { CTF_EXCHANGE_ADDRESS } from '@/lib/contracts'
// After market resolves to YES
await redeemPosition({
market_id: '0x123...',
outcome: 'YES',
amount: 10,
})
// Your 10 YES shares convert to 10 USDC
Transfer USDC out
import { parseUnits } from 'viem'
await writeContract({
address: NATIVE_USDC_TOKEN_ADDRESS,
abi: [{
name: 'transfer',
type: 'function',
inputs: [
{ name: 'to', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
}],
functionName: 'transfer',
args: [
destinationAddress,
parseUnits('100', 6), // 100 USDC
],
})
Split and merge operations
Advanced users can manually split USDC into shares or merge shares back:
Split USDC into YES + NO
// Split 10 USDC into 10 YES + 10 NO shares
await splitPosition({
market_id: '0x123...',
amount: 10,
})
// Result: 10 USDC → 10 YES shares + 10 NO shares
Merge shares back to USDC
// Merge 5 YES + 5 NO back to 5 USDC
await mergePosition({
market_id: '0x123...',
amount: 5,
})
// Result: 5 YES + 5 NO → 5 USDC
Split/merge is useful for arbitrage and reducing risk exposure.
USDC transaction examples
// User deposits 100 USDC
const tx = await usdcContract.transfer(
ESCROW_ADDRESS,
parseUnits('100', 6)
)
Troubleshooting
Insufficient USDC balance
Solution:
- Check balance on PolygonScan
- Verify you’re looking at correct wallet address
- Buy more USDC on exchange or bridge from Ethereum
Approval transaction failed
Causes:
- Insufficient POL for gas
- Previous approval still pending
- Contract address incorrect
Solution: Wait for pending transactions to confirm, add POL for gas.
Check:
- Transaction confirmed on PolygonScan
- Correct network (Polygon, not Ethereum)
- Correct token address (native USDC)
Polygon transactions finalize in ~2 seconds.
Next steps
Smart contracts
View all contract addresses and ABIs
Trading API
Place orders via REST API