NeuyRouter Developer Docs

Updated Dec 4, 2025 - Versioned cross-chain DEX router

NeuyRouter is an aggregated DEX router that searches across multiple pools and routes on each supported chain to find efficient swaps. This page shows how to integrate it from JavaScript and Python on Arbitrum, Avalanche, Binance, Base, Polygon, and Ethereum.

0. Why Use NeuyRouter?

NeuyRouter occupies a unique place in the DEX aggregator landscape. Traditional aggregators rely heavily on centralized off-chain APIs to compute routes, while pure Web3 DEXs offer permissionless access but no multi-DEX price optimization. NeuyRouter delivers the best of both: the routing power of an aggregator with the transparency and determinism of fully on-chain logic.

This makes NeuyRouter ideal for developers, arbitrage systems, automation frameworks, and any application requiring predictable, verifiable smart-contract routing without depending on external servers, API keys, or proprietary infrastructure.

Attribute Uniswap 1inch ParaSwap Matcha/0x Odos NeuyRouter
Fully on-chain routing
No API dependency
Multi-DEX aggregation
Split-route support
Native token routing
Calls usable directly by smart contracts LimitedNot idealNot idealNot idealNot ideal Ideal
Deterministic, transparent routing logic
Fee model 0-0.15% ~0% + slippage capture 0% Variable ~0% 0.01% only on surplus

NeuyRouter is the only Web3-native aggregator built entirely on-chain-no servers, no APIs, no rate limits. This makes it a transparent, permissionless routing primitive that developers can rely on across Arbitrum, Binance, Base, Ethereum, and Polygon.

1. Overview

NeuyRouter is a smart-contract router that aggregates liquidity across multiple DEXs and routes to find competitive pricing. It exposes a single interface for:

  • Getting quotes for ERC20 > ERC20 swaps (V2, V3, and split routes)
  • Executing swaps via NeuyRouter instead of talking to DEXs directly
  • Swapping native gas token <> ERC20 on V2 chains (Arbitrum, Binance)

There are currently two versions deployed:

  • V2: Arbitrum, Binance (supports native swap endpoints)
  • V1: Base, Ethereum, Polygon

2. Networks & contract addresses

Chain Version Router address
Arbitrum V2 0x0BA133CbfdAE0b431c35459B0b5f9Fe627c48cac
Avalanche V2 0x1252b87BAd75AEfaCE59B594239F439EFF67cEF0
Binance (BSC) V2 0x600df1F1d2EAb5f81B7Acfe1319AD7B283525C88
Base V1 0x4A0FA0A6d728F985Fe2c478265BB04e57BCD01C2
Ethereum V1 0x4A0FA0A6d728F985Fe2c478265BB04e57BCD01C2
Polygon V1 0xcc9F06616208A9a02870D464ee1fBe71BCEABdf6

Native swap endpoints (dexV2NativeSwapETHToToken or dexV2NativeSwapBNBToToken, dexV2NativeSwapTokenToETH or dexV2NativeSwapTokenToBNB) are available on V2 chains only (Arbitrum, Binance).

3. Router ABI (shared subset)

The core ABI used across all deployments:

[
  "function balanceOf(address account) external view returns (uint256)",
  "function getV3Quote(address tkIn, address tkOut, uint256 amountIn) external returns (uint256,uint256)",
  "function dexV3Swap(uint256 route, uint256 amountIn, uint256 amountOut, address tkIn, address tkOut) external returns (uint256)",
  "function getV2Quote(address tkIn, address tkOut, uint256 amountIn) external view returns (uint256,uint256)",
  "function dexV2Swap(uint256 route, uint256 amountIn, uint256 amountOut, address tkIn, address tkOut) external returns (uint256)",
  "function getSplitV2Quote(address tkIn, address tkOut, uint256 amountIn) external view returns (uint256,uint256,uint256)",
  "function dexSplitV2Swap(uint256 route1, uint256 route2, uint256 amountIn, uint256 amountOut, address tkIn, address tkOut) external returns (uint256)",

  // Native endpoints (V2 only: Arbitrum, Binance)
  // Arbitrim Only
  "function dexV2NativeSwapETHToToken(uint256 route, uint256 amountOutMin, address tkOut) external payable returns (uint256)",
  "function dexV2NativeSwapTokenToETH(uint256 route, uint256 amountIn, uint256 amountOutMin, address tkIn) external returns (uint256)"

  // Binance Only
  "function dexV2NativeSwapBNBToToken(uint256 route, uint256 amountOutMin, address tkOut) external payable returns (uint256)",
  "function dexV2NativeSwapTokenToBNB(uint256 route, uint256 amountIn, uint256 amountOutMin, address tkIn) external returns (uint256)"

  // Avalanche Only
  "function dexV2NativeSwapAVAXToToken(uint256 route, uint256 amountOutMin, address tkOut) external payable returns (uint256)",
  "function dexV2NativeSwapTokenToAVAX(uint256 route, uint256 amountIn, uint256 amountOutMin, address tkIn) external returns (uint256)",

]

4. Quick start

Below is a minimal example of connecting to NeuyRouter, getting a quote, and performing a swap. Use the tabs to switch between JavaScript (ethers.js) and Python (web3.py).

// JavaScript (browser + ethers v5)
// Assumes window.ethereum is injected (MetaMask, etc.)

const ROUTERS = {
  arbitrum: "0x0BA133CbfdAE0b431c35459B0b5f9Fe627c48cac",  // V2
  avalanche: "0x1252b87BAd75AEfaCE59B594239F439EFF67cEF0",  // V2
  bsc:      "0x600df1F1d2EAb5f81B7Acfe1319AD7B283525C88",  // V2
  base:     "0x4A0FA0A6d728F985Fe2c478265BB04e57BCD01C2",  // V1
  ethereum: "0x4A0FA0A6d728F985Fe2c478265BB04e57BCD01C2",  // V1
  polygon:  "0xcc9F06616208A9a02870D464ee1fBe71BCEABdf6"   // V1
};

const routerAbi = [ /* ABI from section above */ ];

async function initNeuyRouter() {
  await window.ethereum.request({ method: "eth_requestAccounts" });

  const provider = new ethers.providers.Web3Provider(window.ethereum, "any");
  const signer = provider.getSigner();

  // Example: Arbitrum V2 router
  const router = new ethers.Contract(
    ROUTERS.arbitrum,
    routerAbi,
    signer
  );

  return { provider, signer, router };
}

// Example: get a V2 quote & perform a swap (ERC20 > ERC20)
async function swapExample() {
  const { router } = await initNeuyRouter();

  const tkIn  = "0x...";   // ERC20 in
  const tkOut = "0x...";   // ERC20 out
  const amountIn = ethers.utils.parseUnits("1.0", 18); // 1 token (18 decimals)

  // 1) Get V2 quote (amountOut, route)
  const [amountOut, route] = await router.getV2Quote(tkIn, tkOut, amountIn);

  // 2) Apply slippage protection
  const slippage = 0.98; // 2% slippage
  const minOut = amountOut.mul(98).div(100);

  // 3) Make sure tkIn is approved for the router before calling dexV2Swap.
  //    (approve done on the token contract: token.approve(router.address, ...))

  const tx = await router.dexV2Swap(
    route,
    amountIn,
    minOut,
    tkIn,
    tkOut
  );
  const receipt = await tx.wait();
  console.log("Swap completed:", receipt.transactionHash);
}
# Python (web3.py)
from web3 import Web3

ROUTERS = {
    "arbitrum": "0x0BA133CbfdAE0b431c35459B0b5f9Fe627c48cac",  # V2
    "avalanche": "0x1252b87BAd75AEfaCE59B594239F439EFF67cEF0",  // V2
    "bsc":      "0x600df1F1d2EAb5f81B7Acfe1319AD7B283525C88",  # V2
    "base":     "0x4A0FA0A6d728F985Fe2c478265BB04e57BCD01C2",  # V1
    "ethereum": "0x4A0FA0A6d728F985Fe2c478265BB04e57BCD01C2",  # V1
    "polygon":  "0xcc9F06616208A9a02870D464ee1fBe71BCEABdf6",  # V1
}

router_abi = [  # same ABI as above, truncated here for brevity
    "function getV2Quote(address,address,uint256) view returns (uint256,uint256)",
    "function dexV2Swap(uint256,uint256,uint256,address,address) returns (uint256)"
]

# 1) Connect to a node (example: Arbitrum)
w3 = Web3(Web3.HTTPProvider("YOUR_ARB_RPC_URL"))
router_addr = Web3.to_checksum_address(ROUTERS["arbitrum"])
router = w3.eth.contract(address=router_addr, abi=router_abi)

tk_in  = Web3.to_checksum_address("0x...")
tk_out = Web3.to_checksum_address("0x...")
amount_in = 1 * 10**18  # 1 token with 18 decimals

# 2) Get quote
amount_out, route = router.functions.getV2Quote(
    tk_in, tk_out, amount_in
).call()

# 3) Slippage protection
min_out = amount_out * 98 // 100  # 2% slippage

# 4) Build transaction (from an EOA you control)
from_addr = Web3.to_checksum_address("0xYourEOA...")
nonce = w3.eth.get_transaction_count(from_addr)

tx = router.functions.dexV2Swap(
    route,
    amount_in,
    min_out,
    tk_in,
    tk_out,
).build_transaction({
    "from": from_addr,
    "nonce": nonce,
    "gas": 600000,
    "gasPrice": w3.to_wei("0.1", "gwei"),
})

# 5) Sign & send
signed = w3.eth.account.sign_transaction(tx, private_key="YOUR_PRIVATE_KEY")
tx_hash = w3.eth.send_raw_transaction(signed.rawTransaction)
print("Swap submitted:", tx_hash.hex())

5. Getting quotes

NeuyRouter exposes multiple quote functions. All quote endpoints are read-only and can be called from a public or private RPC.

5.1 getV2Quote

Returns the best V2-style route and amountOut for a given ERC20 > ERC20 input.

  • tkIn: input token address
  • tkOut: output token address
  • amountIn: input amount (uint256)
  • returns: (amountOut, routeId)
// JS example
const [amountOut, route] = await router.getV2Quote(tkIn, tkOut, amountIn);

5.2 getV3Quote

Returns a V3-style quote when available on the underlying chain / pools. Usage mirrors getV2Quote:

const [amountOutV3, routeV3] = await router.getV3Quote(tkIn, tkOut, amountIn);

5.3 getSplitV2Quote

Returns a split-route quote across two V2 paths: (amountOut, route1, route2).

const [amountOutSplit, route1, route2] =
  await router.getSplitV2Quote(tkIn, tkOut, amountIn);

6. ERC20 <> ERC20 swaps

For ERC20 <> ERC20, approve NeuyRouter to spend your input token, then call one of the swap functions with a route obtained from the quote functions.

6.1 dexV2Swap

  • route: route id from getV2Quote
  • amountIn: exact input amount
  • amountOut: minimum output (slippage protected)
  • tkIn: input token
  • tkOut: output token
const [amountOut, route] = await router.getV2Quote(tkIn, tkOut, amountIn);
const minOut = amountOut.mul(98).div(100); // 2% slippage

const tx = await router.dexV2Swap(
  route,
  amountIn,
  minOut,
  tkIn,
  tkOut
);
await tx.wait();

6.2 dexV3Swap

Similar to dexV2Swap, but uses V3 routing if supported by the router on that chain.

const [amountOutV3, routeV3] = await router.getV3Quote(tkIn, tkOut, amountIn);
const minOutV3 = amountOutV3.mul(98).div(100);

const tx = await router.dexV3Swap(
  routeV3,
  amountIn,
  minOutV3,
  tkIn,
  tkOut
);
await tx.wait();

6.3 dexSplitV2Swap

Executes a split V2 swap using two routes returned by getSplitV2Quote.

const [amountOutSplit, route1, route2] =
  await router.getSplitV2Quote(tkIn, tkOut, amountIn);

const minOutSplit = amountOutSplit.mul(98).div(100);

const tx = await router.dexSplitV2Swap(
  route1,
  route2,
  amountIn,
  minOutSplit,
  tkIn,
  tkOut
);
await tx.wait();

7. Native <> token swaps (V2 chains only)

On V2 chains only (Arbitrum, Avalance, Binance), NeuyRouter exposes dedicated endpoints for native gas token <> ERC20 swaps. On other chains (V1), wrap/unwrap native assets yourself and then use ERC20 routes.

7.1 dexV2NativeSwapETHToToken or dexV2NativeSwapBNBToToken or dexV2NativeSwapAVAXToToken

  • route: route id from getV2Quote (using wrapped native)
  • amountOutMin: minimum ERC20 out
  • tkOut: ERC20 token to receive
  • msg.value: native amount in
// Example: on Arbitrum (ETH > token)
// 1) Quote using wrapped native (e.g. WETH) for tkIn
const [amountOut, route] = await router.getV2Quote(
  WETH_ADDRESS,
  tkOut,
  amountIn
);
const minOut = amountOut.mul(98).div(100);

const tx = await router.dexV2NativeSwapETHToToken(
  route,
  minOut,
  tkOut,
  { value: amountIn }
);
await tx.wait();

7.2 dexV2NativeSwapTokenToETH or dexV2NativeSwapTokenToBNB or dexV2NativeSwapTokenToAVAX

  • route: route id from getV2Quote (tkIn > wrapped native)
  • amountIn: ERC20 amount in
  • amountOutMin: minimum native out
  • tkIn: ERC20 token you’re selling
const [amountOut, route] = await router.getV2Quote(
  tkIn,
  WETH_ADDRESS,
  amountIn
);
const minOut = amountOut.mul(98).div(100);

// tkIn must be approved for router.address
const tx = await router.dexV2NativeSwapTokenToETH(
  route,
  amountIn,
  minOut,
  tkIn
);
await tx.wait();

8. balanceOf

The router contract also exposes a simple balanceOf view, which can be used for tracking balances where appropriate.

const bal = await router.balanceOf("0xYourAddress");
console.log("Balance:", bal.toString());

9. Fees, routing, and best practices

  • A small protocol fee (max ~0.01%) may be applied only on positive surplus and routed back into NEUY buybacks / staking pools.
  • Always apply your own slippage guard by reducing the quoted amountOut (for example, multiply by 0.98 for 2% slippage).
  • Low-liquidity routes or highly volatile pairs may revert; catch and handle reverts in your integration.
  • Use a dedicated read-only RPC endpoint for quote spam if you are building automated arbitrage or routing bots.

For more examples (including front-end integrations and arbitrage scripts), see the public repository: github.com/NEUYTeam/NeuyAI .

10. Risk Disclosure

The NeuyRouter contracts operate autonomously on public blockchain networks and are not monitored, controlled, or upgraded by NeuyAI once deployed. By choosing to interact with these contracts, you assume full responsibility for all associated risks, including but not limited to smart-contract bugs, market volatility, failed transactions, slippage, and loss of funds. NeuyAI provides no warranties and disclaims all liability for any damages arising from the use of this protocol.