Errors & Troubleshooting
Symptom (Circle / RPC):
ESTIMATION_ERROR,CALL_EXCEPTION,execution reverted, or revert without reason.Circle transaction stays in
PENDING_SIGNATUREorPENDING_ESTIMATIONthen fails.
Why it happens:
Calldata is valid, but current pool state (liquidity/price) or allowance/balance makes the call revert.
The
minAmountInis too tight vs. real-time price.Wrong adapterData (e.g., feeTier/spacing) for the chosen router.
You didn’t pass the exact
path/multihopfrom the quote for multi-hop.
Fixes (checklist):
Pre-simulate using the exact builder output (router, signature, params) against your RPC before sending to Circle.
The builder already returns what to call; do not change it.
Use the same numbers from the quote:
amountOut→ router’samountIn(RAW tokenIn)minAmountIn→ router’sminAmountOut(RAW tokenOut)Never re-compute or format these again.
Relax slippage at quote time (e.g., 0.5 → 0.8) if the pool is volatile.
Adapter data must match router type:
Uniswap V3:
feeTier(s)Slipstream: tick spacing(s) (quotes show these as
feeTier: 50/10but builder maps them to spacings).
Multi-hop: include both
pathandmultihopsegments from the quote in/buildTransaction.Router address: must be the one returned by the builder (don’t hardcode).
Deadline/flags: these are baked into
adapterDataby the builder—pass it through unchanged.
Balance / allowance issues
Symptoms:
insufficient funds/ERC20: transfer amount exceeds balanceallowance too low/ approval missingApproval succeeds but swap still fails estimation
Checklist:
Balance: Confirm the tokenIn balance ≥
amountOut(RAW) in the sender wallet.Allowance:
Approve
spender = build.routerAddressAmount can be either exact (
amountOut) or a large cap (e.g., 1e24) if your policy allows.Wait until the approval transaction is CONFIRMED before sending the swap.
Correct token: Approve the input token (fromTokenAddress), not the output.
Correct wallet: The address that sends the swap must be the one holding the funds and the one that did the approval (EOA or SCA).
Right chain: Balance/allowance must be on
chainIdyou’re swapping on.
Common mistakes
Mixing HUMAN and RAW units
/quote→amountis HUMAN (e.g.,"100.00")./buildTransaction→amountOutandminAmountInare RAW (exact values from the quote).Don’t re-parse or
parseUnitsthe builder inputs; just forward them.
Not passing
path/multihopfor multi-hopIf the quote shows a multi-hop route, the build request must include the exact
pathandmultihoparray.
Changing router or adapter
Do not swap router types between quote and build.
Use builder outputs:
routerAddress,abiFunctionSignature,abiParameters,adapterAddress,adapterData.
Relying on fee tiers/spacing defaults
For V3/Slipstream, always forward hop-level params from the quote.
If you omit these, the builder falls back to safe defaults, which may be suboptimal or fail on certain pools.
Too-tight slippage
Very tight slippage can fail at estimation time. Start with
0.5%and tune according to asset volatility/liquidity.
Using a different recipient than expected
userWalletis the recipient. For SCAs (e.g., Circle), pass the SCA address.Ensure your approval is done from the same wallet that executes the swap.
Calling the router with modified calldata
Any modification (parameter order, types, rounding) can break estimation.
Always encode with the exact function signature and parameters returned by the builder.
Wrong chain or token addresses
Ensure token contracts are correct for
chainId8453 (Base in examples).A checksum mismatch won’t revert, but a wrong contract address will.
Skipping pre-simulation
Especially when sending via custodial flows (Circle), always dry-run the router call against RPC to catch issues early.
Quick diagnostics flow
Request: Did you send the right fields? (
amountHUMAN for quote; RAW values for build)Quote: Is
multihopnon-null? Then you must includepath+multihopin build.Build: Are you using the builder’s routerAddress / signature / parameters as-is?
Allowance: Confirm approval confirmed before swap; spender = routerAddress.
Pre-sim: RPC
eth_callusing the same calldata; if revert → adjust slippage/params.Resend: If transient (RPC or upstream), retry with jitter/backoff.
If you still get stuck, log:
The quote payload and response,
The build payload and response,
The exact router call (signature + params), and
The RPC/estimation error message (including revert data if available).
Last updated

