Preview A Swap
quoteNet returns the exact amount you would receive for a given amount, after fees. Pass that amount as minAmountOut when you execute, so the swap reverts if conditions change rather than delivering less than you expected.
Prerequisites
- You have worked through Check eligibility
- You have the pool address, the token addresses, and an RPC endpoint
Step 1: Request a quote
import { createPublicClient, http, parseAbi, parseUnits } from 'viem';
const client = createPublicClient({ transport: http(process.env.RPC_URL) });
const POOL = '0xYOUR_POOL_ADDRESS';
const IBENJI = '0xIBENJI_TOKEN_ADDRESS';
const USDC = '0xUSDC_TOKEN_ADDRESS';
const CALLER = '0xYOUR_CALLING_CONTRACT_ADDRESS';
const poolAbi = parseAbi([
'function quoteNet(address fromToken, address toToken, uint256 amount, address client) view returns (uint256 net, uint256 fee)'
]);
const amount = parseUnits('100', 6); // 100 USDC — USDC has 6 decimals
const [net, fee] = await client.readContract({
address: POOL, abi: poolAbi, functionName: 'quoteNet',
args: [USDC, IBENJI, amount, CALLER]
});
net is what you would receive. fee is what would be deducted. Both are returned in the smallest unit of the relevant token.
Step 2: Work in whole units, not decimals
Compute and compare amounts as integers in the token's smallest unit. Converting to a floating-point number introduces rounding that will not match what the contract does, and a minAmountOut that is off by one unit will revert.
iBENJI has 18 decimals; USDC has 6.
A quote answers the question "what would I receive if this swap succeeded?"
What a quote does not check
quoteNet is arithmetic, not validation. It answers the question above and nothing else, so a
successful quote does not mean the swap will go through. In particular it does not check:
- whether the pool holds enough to fill you.
quoteNetwill return a figure far larger than the pool's entire reserve. Asking to receive 10,000,000 units from a pool holding 100 returns a clean quote for 10,000,000 — and then the swap reverts with refused because the reserve is short. - whether the pool is paused — see refused because trading is paused
- whether you are authorized to trade the pair — a quote succeeds for any address, including one with no authorization at all
- whether the calling contract holds the input token, or has approved the pool
Treat a quote as a price, not as a pre-flight check. The reads on Check eligibility are what tell you a swap can actually settle.
Your fee
quoteNet returns the fee that applies to your address alongside the exact amount you would receive. Use those two figures. The net amount is the final amount.
Quotes go stale
Fees can be changed by the pool owner and take effect immediately, and the pool reserve moves as others swap. Both make a quote perishable.
Re-quote immediately before you execute, and pass the fresh amount as minAmountOut. That value is what protects you if conditions change between quoting and settling — a swap that would deliver less than your minAmountOut reverts rather than settling on worse terms.
iBENJI → stablecoin: amounts must be convertible
When swapping from iBENJI (18 decimals) to a 6-decimal stablecoin, the input amount must be a whole multiple of 10^12 — the difference between the two decimal precisions. An amount that is not convertible is refused — see When a swap is refused.
Trim before quoting:
const raw = parseUnits('1.0000005', 18);
const step = 10n ** 12n;
const trimmed = raw - (raw % step);
This catches most people out the first time. The reverse direction — stablecoin to iBENJI — is unaffected.
Save these outputs
Keep:
net— pass this asminAmountOutwhen you executefee— for your own reconciliation
Then continue to executing the swap, re-quoting first.