# Table of Contents - [Introduction | Metric](#introduction-metric) - [Glossary | Metric](#glossary-metric) - [Oracle Basics | Metric](#oracle-basics-metric) - [via API | Metric](#via-api-metric) - [Integration guideline for Solvers/Aggregators | Metric](#integration-guideline-for-solvers-aggregators-metric) - [SDK | Metric](#sdk-metric) - [API | Metric](#api-metric) - [Metadata | Metric](#metadata-metric) - [Smart Contracts Reference(Deprecated) | Metric](#smart-contracts-reference-deprecated-metric) - [Retrieve Current Bid and Ask | Metric](#retrieve-current-bid-and-ask-metric) - [Get Quote | Metric](#get-quote-metric) - [Swapping via Router | Metric](#swapping-via-router-metric) - [API(Deprecated) | Metric](#api-deprecated-metric) - [Smart Contracts Reference | Metric](#smart-contracts-reference-metric) - [Find Best Route | Metric](#find-best-route-metric) - [Swapping directly via pool | Metric](#swapping-directly-via-pool-metric) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Introduction | Metric](#introduction-metric) - [Oracle Basics | Metric](#oracle-basics-metric) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [SDK | Metric](#sdk-metric) --- # Introduction | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/introduction.md) . **How active pools work** Each pool runs on two components. A Price Provider reads an external oracle (Pyth, Chainlink, or custom) and handles the pricing logic. A Liquidity Module holds deposits and tracks the reference price automatically. When the market moves, the pool moves with it. Liquidity stays centered on the real market instead of drifting behind it. **For aggregators and solvers** Routing into Metric means routing into liquidity that is already centered on a real market reference, rather than liquidity that drifts and relies on arbitrage to be corrected after the move. Execution is expressed as a deviation around that reference. When the trade lands better than the route’s expected price, the surplus is captured by the routing stack. **For market makers and propAMMs** Metric is PropAMM-on-demand. You control bid, ask, and spread behavior through a Price Provider, and Metric handles the pool and distribution. No need to rebuild the oracle and pool stack. **For RWA issuers** Any asset with a primary price set off-chain gets a persistent on-chain venue that quotes against the live reference feed from launch. This covers tokenized equities, treasuries, commodities, FX, and any other asset with a reliable reference price. Every pool is composable across DeFi, so tokenized assets can be used as collateral, integrated into yield strategies, or plugged into structured products natively. **For liquidity providers** LPs benefit from reduced impermanent loss and a significantly improved liquidity management workflow. There is no longer a need to run rebalancing scripts or bots that continuously track price movements and re-enter liquidity. **Metric. Everything on-chain, priced to reality.** [NextGlossary](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary) Last updated 3 days ago --- # Glossary | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary.md) . ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#price-formats-and-units) Price formats & units #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#q64.64) Q64.64 Fixed-point number format used for all prices. The integer is the real value × 2^64; convert to human-readable with `value / 2^64`. A price is token0 expressed in token1 units (e.g. 1 ETH in USDC). Decimals are normalized internally, so no manual decimal adjustment is needed when feeding values back into the contracts. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#e6) E6 "Parts per million" fixed-point: `1_000_000` = 100%, `10_000` = 1%. Used for `priceImpactE6` and internal fee math (`baseFeeE6`). Note: the routing API's per-leg `priceImpactE6` is a raw E6 string, while the split response's top-level `priceImpactBestRoute` is the same quantity as a **decimal fraction** (`0.01` = 1%). #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#bps-basis-points) bps (basis points) `1 bps = 0.01% = 100 E6`. Used for split-routing thresholds (`split_threshold_bps`, `min_improvement_bps`, `min_leg_fraction_bps`). #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#scaling) Scaling Cumulative depth volumes are reported in the **output token's external (on-chain) decimals**. The quoter itself operates in Q64.64 (decimals already normalized), so no conversion is needed when interacting with it; you only multiply by `10^decimals` when comparing against human-readable prices. The cumulative-volume scale factor is `10^(max(18, token1.decimals()) − token0.decimals())`. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#prices-and-oracle) Prices & oracle #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#price-provider) Price Provider The on-chain oracle contract bound to a pool. Exposes `getBidAndAskPrice()` (Q64.64). Each pool's provider is returned by `pool.getImmutables()` and surfaced in metadata as `priceProviderAddress`. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#raw-oracle-price) Raw oracle price The bid/ask straight from `getBidAndAskPrice()`. This is what `swap()` and `simulateSwapAndRevert(...)` consume to derive pricing — pass these into on-chain simulation so the quote matches execution. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#bidadj-askadj) bidAdj / askAdj The **fee-adjusted** pool bid/ask returned by the bid/ask quote. Useful as Q64.64 price _limits_, but **not** interchangeable with raw oracle prices for simulation input. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#base-fee) Base fee The spread-derived fee the pool applies, computed from `sqrt(ask / bid)` (in E6). Larger oracle spread → larger base fee. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#swap-mechanics) Swap mechanics #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#zeroforone) zeroForOne Swap direction. `true` = token0 → token1 (price moves down); `false` = token1 → token0 (price moves up). #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#amountspecified) amountSpecified The swap amount (`int128`). **Positive** = exact input; **negative** = exact output. `0` is a no-op (`InvalidAmount` on `swap`, `(0,0)` on simulation). #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#recipient) recipient The address that receives the output tokens. May differ from the caller (`msg.sender`), which is the contract that implements and is charged in the callback. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#amount0delta-amount1delta) amount0Delta / amount1Delta The token balance changes from the **pool's perspective**: positive = the pool receives that token (you owe it), negative = the pool sends that token (to `recipient`). Either may be `0`. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#pricelimitx64) priceLimitX64 Worst marginal pool price you'll accept, Q64.64. The swap fills bin-by-bin and **stops** at the limit — a partial fill when interracting with pool directly. When using router - it reverts instead. Acts as a **floor** when `zeroForOne = true` (no-limit sentinel `0`) and a **ceiling** when `false` (no-limit sentinel `2^128 − 1`). `0` on an upward swap fills nothing. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#swap-callback-metricommswapcallback) Swap callback (`metricOmmSwapCallback`) The settlement hook the pool calls on `msg.sender` mid-swap. The pool sends the output token first, then the callback must transfer the owed input token to the pool (verified via balance check, else `IncorrectDelta`). Deltas are passed as `int256`. Required only when calling the pool directly — the Router implements it for you. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#contracts) Contracts #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#pool-metricommpool) Pool (`MetricOmmPool`) The core AMM contract. Holds liquidity, prices from its Price Provider, and exposes `swap` and `simulateSwapAndRevert`. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#quoter-metricommpoolquoter) Quoter (`MetricOmmPoolQuoter`) Periphery, simulation-only. `quoteSwap` wraps the pool's revert-based simulation and returns deltas normally. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#router-metricommswaprouter) Router (`MetricOmmSwapRouter`) Periphery, execution. Implements the swap callback so integrators can swap with a simple `approve` + call (incl. native-ETH variants and slippage guards). Inherits the Quoter. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#factory-metricommpoolfactory) Factory (`MetricOmmPoolFactory`) Deploys pools (`createPool`) and holds protocol-fee settings. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#simulateswapandrevert) simulateSwapAndRevert Pool function that runs the swap math, then **reverts** with the result. No state persists. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#simulateswap) SimulateSwap The custom error `SimulateSwap(int128 amount0Delta, int128 amount1Delta)` that carries simulation results in the revert data. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#wrappederror) WrappedError `WrappedError(address target, bytes4 selector, bytes reason, …)` wraps an unexpected inner revert so callers can see what failed. [PreviousIntroduction](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj) [NextOracle Basics](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/oracle-basics) Last updated 5 days ago --- # Oracle Basics | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/oracle-basics.md) . The oracle publishes one authoritative **snapshot per block** — a **mid price + spread** (and a volatility field) for every market. Bid/ask are not published directly; they're derived downstream by the Price Provider (for public pools the **AnchoredPriceProvider** clamps the quote into a band around this mid). **Oracle type is chain-dependent:** * **Ethereum (L1) —** `**CompressedOracleV1**`**:** updates are **signature-authorized**. The snapshot is signed by the feed creator (Metric); **anyone can relay a valid signed update** (e.g. with higher gas for priority) — it can't be forged or altered. (Metric may also pre-authorize pusher addresses to push without a per-message signature.) * **L2 — permissionless** `**PythOracle**` **(Pyth Lazer) /** `**ChainlinkOracle**` **(Chainlink Data Streams):** anyone can submit a valid Pyth/Chainlink update. Multiple oracle types coexist; the pool/curator chooses. **Key principles:** * **Recency is enforced at the Price Provider level** (`maxTimeDelta`, bounded `0 < value ≤ 7 days`). Recommended: **same block on Ethereum**, a few blocks on sub-1s L2s. * A trade settles **only** against a sufficiently recent valid update. A swap placed before a valid update for the block — or against a stale price — **reverts**. * **Chainlink sanity check (optional):** the oracle price can be cross-checked against a Chainlink reference feed (`maxClDeviation`). On excessive deviation, **no price is returned → the trade reverts**. * **L2 extra guards:** the Price Provider also checks the **sequencer-uptime feed** (with a grace period) and allows a small `FUTURE_TOLERANCE` for slightly-ahead oracle timestamps. * **Read access (L2 providers):** open reads are disabled (`getOracleData` / `price(feedId)` revert `ReadDisabled`); the price is readable only via the attributed `price(feedId, pool)` path during an active swap, or `integratorPrice` for whitelisted integrators. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/oracle-basics#heartbeat-update) Heartbeat Update * **Frequency:** once per block on Ethereum (on L2 this varies — sometimes several updates per block, depending on gas/volatility). * **Timing:** on average at the **~11th second** of each Ethereum block (≈1s delta from source). * **Gas:** slightly above average (e.g. ~0.15 gwei). * **Payload:** the signed market snapshot — **mid + spread for all markets**. [PreviousGlossary](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary) [NextIntegration guideline for Solvers/Aggregators](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators) Last updated 5 days ago --- # via API | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api.md) . At a high level, integrating via the API follows these steps: ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api#id-1.-discover-available-pools) 1\. Discover Available Pools Query the [metadata endpoint](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata) to retrieve: * Supported trading pairs * Pool addresses * Quoter and token addresses This allows your system to dynamically discover and route to available Metric pools. * * * ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api#id-2.-fetch-current-bid-ask) 2\. Fetch Current Bid / Ask Request the current [bid and ask prices](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask) for a selected pair. * Prices are returned for the **current block** * Depth is returned in addition to prices and can be used to calculate price impact * Returned prices are already normalized for use with Metric’s contracts These prices are used both for quoting and for setting execution limits. * * * ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api#id-3.-execute-the-trade) 3\. Execute the Trade Finally, execute the trade by calling the `swap` function on either the [Router](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router) or the [Pool](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool) . * Supports both **exact-input** and **exact-output** swaps * Uses the same [Q64 price format](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#q64.64) for bid, ask, and price limits * [Price limits](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary#pricelimitx64) protect execution against excessive slippage * * * **Important notice:** Oracle update has to happen before trade execution in order to avoid reverts [PreviousIntegration guideline for Solvers/Aggregators](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators) [NextAPI](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api) Last updated 4 days ago --- # Integration guideline for Solvers/Aggregators | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators.md) . ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators#integration-overview) Integration Overview Metric can be integrated in two ways, depending on latency and trust requirements: #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators#option-1-smart-contract-sdk-integration) Option 1 — Smart Contract / SDK Integration Integrate directly with Metric’s on-chain contracts using the SDK. * Fully trustless and on-chain * Quotes are derived from the **previous block** * Simpler operationally, but prices always lag by one block This approach is suitable for systems where determinism and on-chain guarantees matter more than absolute price freshness. #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators#option-2-api-integration-recommended) Option 2 — API Integration (Recommended) Integrate via the Metric API, which returns pricing and liquidity information **for the current block**. * Quotes are always up-to-date with the active block * Enables better execution quality during periods of high volatility This is the recommended approach for **solvers, aggregators, and professional execution systems** that prioritize the best execution. [PreviousOracle Basics](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/oracle-basics) [Nextvia API](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api) Last updated 5 days ago --- # SDK | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/sdk.md) . Current version of SDK supports liquidity operations and swaps. More functions will be rolled out with time [https://www.npmjs.com/package/@nradko/metricamm-sdk](https://www.npmjs.com/package/@nradko/metricamm-sdk) Last updated 5 months ago --- # API | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api.md) . ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api#metric-api) Metric API **Base URL:** `https://api.metric.xyz` #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api#authentication) Authentication Bid/ask, quote, and routing endpoints require a Bearer token: Copy Authorization: Bearer Trading API keys are issued by the Metric team — [contact us](mailto:hello@metric.xyz) to request one. Some public endpoints (chains, metadata) require no authentication. * * * ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api#supported-chains) Supported Chains Retrieve the list of supported chains and their numeric EVM chain IDs: Copy GET /public/v1/chains Use the returned `chain_id` values as the `{chain_id}` path parameter in all chain-specific endpoints below. [Previousvia API](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api) [NextMetadata](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata) Last updated 5 days ago --- # Metadata | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata.md) . Copy GET /public/v1/evm/{chain_id}/metadata Returns the configured pools on a chain together with their on-chain metadata, token details, fiat prices, and pool state. Results are paginated. **Auth:** none — this is a public endpoint. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata#path-parameters) Path parameters Name Type Description `chain_id` integer Numeric EVM chain id (e.g. `1` for Ethereum mainnet). ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata#query-parameters) Query parameters All optional. Name Type Default Description `offset` integer `0` Index of the first row to return. `count` integer `50` Page size. Clamped to `[1, 500]`. `sortBy` string `tvl` One of `tvl`, `created`, `volume`, `apr`. `include24h` boolean `false` Include the optional `analytics24h` block on each pool. `fiat` string `USD` Fiat currency for priced fields. USD is the primary value. `contractVersion` string `v1` Filter to a single configured pool contract generation. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata#pagination) Pagination Read `nextOffset` from the response and pass it back as `offset` to fetch the next page. `nextOffset` is `null` on the last page. `total` is the full count across all pages. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata#request) Request cURL With analytics Copy curl "https://api.metric.xyz/public/v1/evm/1/metadata?count=50&sortBy=tvl" Copy curl "https://api.metric.xyz/public/v1/evm/1/metadata?include24h=true&count=50" ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata#response) Response `200 OK` — a `PaginatedMetadataResponse` envelope. Field Type Description `data` array The page of pools (see fields below). `total` integer Total pools matching the query, across all pages. `nextOffset` integer | null `offset` for the next page, or `null` if last. Copy { "data": [\ {\ "pair": "ethusdc",\ "chain": "ethereum",\ "contractVersion": "v1",\ "poolAddress": "0xbF48bCf474d57fF82A3215319229e0DE1476A557",\ "priceProviderAddress": "0xbD321D18a7ce5fb91F8b16e026e3258f7b310598",\ "token0": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",\ "token1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",\ "token0Symbol": "WETH",\ "token1Symbol": "USDC",\ "token0Decimals": 18,\ "token1Decimals": 6,\ "token0FiatPrice": 3200.25,\ "token1FiatPrice": 1.0,\ "tvlFiat": 1234.56,\ "creator": "0x0000000000000000000000000000000000000000",\ "adminFeeDestination": "0x0000000000000000000000000000000000000000",\ "classificationTier": "unverified",\ "priceProviderCooldownSecs": 0,\ "depositWhitelistingEnabled": false,\ "swapWhitelistingEnabled": false,\ "poolFactoryAddress": "0x0000000000000000000000000000000000000000",\ "poolDeployerAddress": "0x0000000000000000000000000000000000000000",\ "liquidityAdderAddress": "0x0000000000000000000000000000000000000000",\ "dataProviderAddress": "0x0000000000000000000000000000000000000000",\ "depositAndSwapAllowlistAddress": "0x0000000000000000000000000000000000000000",\ "swapperAddress": "0x0000000000000000000000000000000000000000"\ }\ ], "total": 1, "nextOffset": null } #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata#pool-fields) Pool fields Field Type Notes `pair` string Human-readable pair label, e.g. `ethusdc`. `chain` string Chain name. `contractVersion` string Pool contract generation. `poolAddress` string [Pool contract address](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference) . `priceProviderAddress` string Oracle / [price-provider contract](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference) for the pool. `token0`, `token1` string Token contract addresses. `token0Symbol`, `token1Symbol` string Optional. Omitted when unknown. `token0Decimals`, `token1Decimals` integer Optional. `token0FiatPrice`, `token1FiatPrice` number | null Always present; `null` when no price is available. `tvlFiat` number Optional. Total value locked in `fiat`. `classificationTier` string Pool trust tier, e.g. `unverified`, `standard`. `priceProviderCooldownSecs` integer Time needed to update existing Price Provider `depositWhitelistingEnabled` boolean Whether deposits are allowlist-gated. `swapWhitelistingEnabled` boolean Whether swaps are allowlist-gated. `analytics24h` object Present only when `include24h=true`. `poolFactoryAddress` … `swapperAddress` string [Factory contract](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference) for the pool. Optional fields (`token0Symbol`, `tvlFiat`, `analytics24h`, `priceProviderChange`, allowlist providers, …) are **omitted entirely** when absent — they are not returned as `null`. The two exceptions are `token0FiatPrice` and `token1FiatPrice`, which are always present and may be `null`. Throughout this documentation, `**ethusdc**` is the primary example pair. Any other pair returned by this endpoint can be substituted directly, following the same conventions and integration flow. [PreviousAPI](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api) [NextRetrieve Current Bid and Ask](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask) Last updated 5 days ago --- # Smart Contracts Reference(Deprecated) | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated.md) . Overview of pools is available under: [https://app.gitbook.com/o/4dbAWnxoNFlB3Hmv5Lyu/s/wegByLMQJTopYqrvontp/~/edit/~/changes/31/developers/api#metadata-endpoint](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#metadata-endpoint) [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#ethereum) Ethereum ------------------------------------------------------------------------------------------------------------------------------------------ Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xcB41C10c6414aCbea022c7662df4005dd8FBEF91 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#base) **Base** -------------------------------------------------------------------------------------------------------------------------------------- Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xA6A16C00B7E9DBE1D54acEd7d6FE264fc4732eaF Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#bsc) **BSC** ------------------------------------------------------------------------------------------------------------------------------------ Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xa9a63266bB70eb3419C34C245F4318983f325Bbd Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#arbitrum) **Arbitrum** ---------------------------------------------------------------------------------------------------------------------------------------------- Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x82A562fD9F02d4346B95D3a2a501411979C8F920 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#avax) **Avax** -------------------------------------------------------------------------------------------------------------------------------------- Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x5C1e08DF74a3457648A4C4dc5DC0DE497284c53C Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#polygon) **Polygon** -------------------------------------------------------------------------------------------------------------------------------------------- Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x976c26402E1EC10454c5Fe6D2C9857DD57aE78f3 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#megaeth) **MegaETH** -------------------------------------------------------------------------------------------------------------------------------------------- Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xA6A16C00B7E9DBE1D54acEd7d6FE264fc4732eaF Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#hyperevm) **HyperEVM** ---------------------------------------------------------------------------------------------------------------------------------------------- Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x080b37C6F65cBC231f66016460782158090Fe0F7 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#monad) Monad ------------------------------------------------------------------------------------------------------------------------------------ Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xaF9ADa6b6eC7993CE146f6c0bF98f7211CDfD3e5 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated#abi) **ABI** ------------------------------------------------------------------------------------------------------------------------------------ Pool: 106KB [MetricOmmPool.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FzzY9QjeW3XLNJR5K9rVI%2FMetricOmmPool.json?alt=media&token=8714ff48-0bb3-4805-83c9-0e74190410b6) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FzzY9QjeW3XLNJR5K9rVI%2FMetricOmmPool.json?alt=media&token=8714ff48-0bb3-4805-83c9-0e74190410b6) Router: 35KB [MetricOmmSwapRouter.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FX9RbHfy9ay9bGNFThUKd%2FMetricOmmSwapRouter.json?alt=media&token=2c18fe8a-8df8-483a-8fca-727c8ca3f6d6) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FX9RbHfy9ay9bGNFThUKd%2FMetricOmmSwapRouter.json?alt=media&token=2c18fe8a-8df8-483a-8fca-727c8ca3f6d6) Stateview: 37KB [MetricOmmPoolStateView.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FPx0Fj3FlJECSYxCENwNm%2FMetricOmmPoolStateView.json?alt=media&token=1af20402-aa1a-430f-adc8-fcada864ce83) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FPx0Fj3FlJECSYxCENwNm%2FMetricOmmPoolStateView.json?alt=media&token=1af20402-aa1a-430f-adc8-fcada864ce83) Factory: 26KB [MetricOmmPoolFactory.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FU0kqC6ujk1rX8AX7QYmw%2FMetricOmmPoolFactory.json?alt=media&token=bc69abe7-9176-451e-824c-6823d8e97c4c) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FU0kqC6ujk1rX8AX7QYmw%2FMetricOmmPoolFactory.json?alt=media&token=bc69abe7-9176-451e-824c-6823d8e97c4c) [PreviousAPI(Deprecated)](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated) Last updated 3 months ago --- # Retrieve Current Bid and Ask | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask.md) . Copy GET /public/v1/evm/{chain_id}/{pool_address}/bid_ask Returns the current bid and ask prices for a pool, derived from the latest price-provider data, with optional per-bin depth. **Auth required.** This is a Trading API endpoint. Copy Authorization: Bearer The `pool_address` is the unique identifier used throughout the API. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask#path-parameters) Path parameters Name Type Description `chain_id` integer Numeric EVM chain id. `pool_address` string Pool contract address (`0x…`, 20 bytes). ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask#query-parameters) Query parameters All optional. Name Type Default Description `depth` boolean `true` Include the `depth` order book. Set `false` to omit it (`depth` becomes `null`). ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask#request) Request Copy curl "https://api.metric.xyz/public/v1/evm/1/0xbF48bCf474d57fF82A3215319229e0DE1476A557/bid_ask" \ -H "Authorization: Bearer " ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask#response) Response `200 OK` Copy { "pair": "ethusdc", "poolAddress": "0xbF48bCf474d57fF82A3215319229e0DE1476A557", "bidAdj": "43809995982499961913604", "askAdj": "43845058004094599738265", "totalToken0Available": "7210037341486830593", "totalToken1Available": "19571324046", "serverTs": 1770053095, "depth": { "bids": [\ {\ "binIdx": -1,\ "price": "43750000000000000000000",\ "cumulativeVolume": "5000000000",\ "cumulativeInputVolume": "5000000000",\ "priceImpactE6": "1350"\ }\ ], "asks": [\ {\ "binIdx": 1,\ "price": "43900000000000000000000",\ "cumulativeVolume": "5000000000",\ "cumulativeInputVolume": "5000000000",\ "priceImpactE6": "1252"\ }\ ] } } Field Type Description `pair` string Pair label, e.g. `ethusdc`. `poolAddress` string Pool contract address. `bidAdj` string Fee-adjusted bid price, Q64.64 (see below). `askAdj` string Fee-adjusted ask price, Q64.64. `totalToken0Available` string | null Token0 available for the quote (raw units). `null` if unavailable. `totalToken1Available` string | null Token1 available for the quote (raw units). `serverTs` integer Server Unix timestamp (seconds) when the quote was produced. `depth` object | null Per-bin depth (`bids`, `asks`). `null` when `depth=false`. Each `depth` level (`bids[i]` / `asks[i]`): Field Type Description `binIdx` integer Bin index relative to the current position. `price` string Fee-adjusted price at this bin boundary (Q64.64). `cumulativeVolume` string Cumulative output-token volume from the current position to this boundary (external decimals). `cumulativeInputVolume` string Cumulative input-token amount required to reach this boundary. `priceImpactE6` string Cumulative price impact in E6 units (`1_000_000` = 100%) vs. current bid/ask. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask#depth) Depth Bid depth calculation (ask is symmetric — start from `askAdj` and walk the ask bins the same way). 1. Set `currentPrice = bidAdj`, `remainingVolume = X`. 2. **For each bin**, compute `volumeInThisBin = currentBin.cumulativeVolume − previousBin.cumulativeVolume`, then take **exactly one** of the two cases below: **Case A — the order completes inside this bin** (`remainingVolume ≤ volumeInThisBin`): Copy exitPrice = currentPrice + (currentBin.price − currentPrice) × remainingVolume / volumeInThisBin fillPrice = (currentPrice + exitPrice) / 2 // weighted by remainingVolume → **stop.** **Case B — the order consumes the entire bin** (`remainingVolume > volumeInThisBin`): Copy fillPrice = (currentPrice + currentBin.price) / 2 // weighted by volumeInThisBin currentPrice = currentBin.price remainingVolume -= volumeInThisBin → **continue to the next bin** (repeat step 2). 3. **Final fill price** = volume-weighted average of each bin's recorded `fillPrice`. > Price is linear within a single bin, but not across bins, because bins can vary in size. **Scaling****.** `cumulativeVolume` is a scaled token1 quantity. [PreviousMetadata](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata) [NextFind Best Route](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/find-best-route) Last updated 5 days ago --- # Get Quote | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote.md) . [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote#simulate-swap-quote) Simulate Swap (Quote) ----------------------------------------------------------------------------------------------------------------------------------------------------------------- Two ways to get a quote off-chain (both `eth_call`, no state change): * `**MetricOmmSwapQuoter**` (recommended) — decodes the revert for you and returns `(amountIn, amountOut)` directly. * `**MetricOmmPool.simulateSwapAndRevert**` (low-level) — reverts with the result encoded in the revert data; you decode it yourself. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote#recommended-metricommswapquoter) Recommended: `MetricOmmSwapQuoter` A read-only lens (`eth_call` only) with two flavors, each in exact-input / exact-output and single / multihop forms: * **Live** — uses the pool's on-chain oracle prices, so **you don't supply bid/ask**. * **Hypothetical** — you pass `bidPriceX64` / `askPriceX64` (e.g. to quote against a price you expect). Single-hop: Copy // Live — no prices supplied function quoteLiveExactInSingle(address pool, bool zeroForOne, uint128 amountIn, uint128 priceLimitX64) external returns (uint256 amountIn, uint256 amountOut); function quoteLiveExactOutSingle(address pool, bool zeroForOne, uint128 amountOutDesired, uint128 priceLimitX64) external returns (uint256 amountIn, uint256 amountOut); // Hypothetical — caller-supplied bid/ask function quoteHypotheticalExactInputSingle( address pool, bool zeroForOne, uint128 amountIn, uint128 priceLimitX64, uint128 bidPriceX64, uint128 askPriceX64 ) external returns (uint256 amountIn, uint256 amountOut); function quoteHypotheticalExactOutputSingle( address pool, bool zeroForOne, uint128 amountOutDesired, uint128 priceLimitX64, uint128 bidPriceX64, uint128 askPriceX64 ) external returns (uint256 amountIn, uint256 amountOut); Each has an overload taking `(address recipient, …, bytes extensionData)` for pools whose extensions gate on those fields. **Multihop:** `quoteLiveExactIn` / `quoteLiveExactOut` and `quoteHypotheticalExactInput` / `quoteHypotheticalExactOutput` take a params struct (`pools[]`, `extensionDatas[]`, `zeroForOneBitMap`, amount). **How it works:** the live path drives `pool.swap` and reverts inside the callback with `QuoteSwapResult`; the hypothetical path drives `simulateSwapAndRevert` and reads `SimulateSwap`. The quoter catches both and returns the decoded amounts. Any other inner revert is bubbled up as `WrappedError(address target, bytes4 selector, bytes reason)`. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote#low-level-call-the-pool-directly) Low-level: call the pool directly Copy function simulateSwapAndRevert( address recipient, bool zeroForOne, int128 amountSpecified, uint128 priceLimitX64, uint128 bidPriceX64, uint128 askPriceX64, bytes calldata extensionData ) external returns (int128 amount0Delta, int128 amount1Delta); This always reverts with `SimulateSwap(int128 amount0Delta, int128 amount1Delta)`; you must catch and decode the revert data yourself. Use the quoter unless you need the raw signed deltas. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote#reverts-and-guards) Reverts & guards Condition Result `amountSpecified == 0` reverts `InvalidAmount` `bidPriceX64 == 0` reverts `BidIsZero` `bidPriceX64 > askPriceX64` reverts `BidGreaterThanAsk` inner pool revert (other) bubbled up as `WrappedError` [PreviousSmart Contracts Reference](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference) [NextSwapping via Router](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router) Last updated 4 days ago --- # Swapping via Router | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router.md) . [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router#swapping-via-the-router) Swapping via the Router --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- `MetricOmmSimpleRouter` (periphery) executes ERC-20 swaps through one or more pools and implements the pool's settlement callback internally — you implement nothing. Unlike the low-level pool `swap`, every router entrypoint has **built-in amount-based slippage protection** (`amountOutMinimum` / `amountInMaximum`) plus a `deadline`. > Scope: **ERC-20 routes only.** Per the interface, there is no native ETH, WETH wrap/unwrap, or on-chain quoting here (functions are `payable` only for multicall composition). For quotes, use `MetricOmmSwapQuoter`. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router#prerequisites) Prerequisites * `approve` the router to spend your input token (`tokenIn`) — its callback pulls the token from you during settlement. * Optional: the router supports `**selfPermit**` and `**multicall**`, so you can permit + swap in one transaction (no separate approval tx). ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router#entrypoints) Entrypoints Copy function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); Single-hop params (exact input shown; exact output mirrors it with `amountOut` + `amountInMaximum`): Copy struct ExactInputSingleParams { address pool; address tokenIn; // the router pulls THIS from you in the callback — set it correctly address tokenOut; // informational only; not checked on-chain bool zeroForOne; // true = token0 → token1 uint128 amountIn; uint128 amountOutMinimum; // slippage floor — reverts InsufficientOutput if not met address recipient; // receives the output token uint256 deadline; // reverts TransactionExpired once passed uint128 priceLimitX64; // Q64.64 marginal bound (see sentinels below) bytes extensionData; // forwarded to the pool's swap extension; "0x" if unused } **Returns:** exact-input entrypoints return `amountOut`; exact-output entrypoints return `amountIn` (both `uint256`). ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router#pricelimitx64-single-hop) priceLimitX64 (single-hop) A Q64.64 marginal bound. The sentinel is **direction-checked** — passing the wrong one reverts `InvalidPriceLimitForDirection`: `zeroForOne` Direction No-limit sentinel `true` price down (lower bound) `0` `false` price up (upper bound) `type(uint128).max` (`2^128 − 1`) Multihop entrypoints **omit per-hop price limits** (each hop runs open); slippage is controlled solely by `amountOutMinimum` / `amountInMaximum`. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router#multihop) Multihop `exactInput` / `exactOutput` take a route: * `tokens[]` — the path `[t0, t1, …, tn]`. * `pools[]` — pool between each adjacent pair (`length = tokens.length − 1`). * `extensionDatas[]` — per-pool payload (`length = pools.length`). * `zeroForOneBitMap` — bit `i` is the direction for `pools[i]` (up to 256 hops). Exact-output routes execute **last hop → first**; `amountOut` is `tokens[last]`. **The router does not validate your route.** It does not check pool factory provenance, that each `pool` connects its adjacent path tokens, or that `tokenIn`/`tokenOut` match pool immutables. Supplying a wrong `pool` or `tokenIn` is at your own risk — resolve these from the metadata endpoint. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router#notes) Notes * **Settlement is internal:** the router's callback pulls `tokenIn` from you and the pool sends output to `recipient`. It validates the callback caller (`InvalidCallbackCaller`). * **Errors:** `TransactionExpired`, `InsufficientOutput` (exact-in min), `InputTooHigh` (exact-out max), `InvalidPriceLimitForDirection`, `InvalidPath`, `InvalidSwapDeltas`, `AmountTooLarge`, and the per-hop `InvalidInputAmountAtHop` / `InvalidOutputAmountAtHop`. Pool-level reverts (`BidIsZero`, `BidGreaterThanAsk`, `PoolPaused`) bubble up. The pool prices from its on-chain `priceProvider` at execution time. Sequence an oracle update ahead of the swap (same bundle/block) so it doesn't price stale or revert. [PreviousGet Quote](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote) [NextSwapping directly via pool](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool) Last updated 4 days ago --- # API(Deprecated) | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated.md) . [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#metadata-endpoint) Metadata Endpoint -------------------------------------------------------------------------------------------------------------------------------------- You can retrieve all available trading pairs along with their associated on-chain metadata using the following endpoint: **GET** Copy http://54.199.103.16:8080/ethereum/metadata http://54.199.103.16:8080/base/metadata http://54.199.103.16:8080/bsc/metadata http://54.199.103.16:8080/arbitrum/metadata http://54.199.103.16:8080/avax/metadata http://54.199.103.16:8080/polygon/metadata http://54.199.103.16:8080/megaeth/metadata http://54.199.103.16:8080/hyperevm/metadata http://54.199.103.16:8080/monad/metadata ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#description) Description This endpoint returns a list of supported pairs and the relevant contract addresses required for integration, including pool, price provider, and quoter contracts, as well as the underlying token addresses. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#response-format) Response Format **Content-Type:** `application/json` **Example response:** Copy [\ {\ "pair": "ethusdc",\ "poolAddress": "0xbF48bCf474d57fF82A3215319229e0DE1476A557",\ "priceProvider_address": "0xbD321D18a7ce5fb91F8b16e026e3258f7b310598",\ "quoterAddress": "0x58F9d1865d4Aeb59a9a7Dc68A3b4e0B42D9Ef5eD",\ "token0": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",\ "token1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",\ "cexStep":0.0002,\ "dexStep":0.0\ }\ ] ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#field-definitions) Field Definitions Field Description `pair` Canonical pair identifier (lowercase, no separator). `poolAddress` Address of the Metric liquidity pool for the pair. `priceProvider_address` Address of the active Price Provider used to source reference pricing. `quoterAddress` Address of the quoter contract used for off-chain quoting. `token0` Address of the first token in the pair. `token1` Address of the second token in the pair. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#notes) Notes Throughout the documentation, `**ethusdc**` is used as the primary example pair. Any other supported pair returned by this endpoint can be substituted directly, following the same conventions and integration flow. [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#retrieve-current-bid-and-ask) Retrieve Current Bid and Ask ------------------------------------------------------------------------------------------------------------------------------------------------------------ You can retrieve the current bid and ask prices for a given pair using the following endpoint. Prices are returned based on current data from price provider. On most chains this causes insignificant price delays of below 1 second. On ethereum it currently causes a delay of 12 seconds. We are working to address this with our next update. **GET** Copy http://54.199.103.16:8080/ethereum/0x3221901709F01737a601F9f02a01df6b13b2A6Ff/bid_ask Pool address serves as unique identifier and is used in this api. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#inputs) Inputs Sent as POST(Currently implemented as GET method for simplicity) parameters. Parameter Description `secretKey` Authentication key (will be required later). Currently optional. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#response-format-1) Response Format **Content-Type:** `application/json` **Example response:** Copy { "pair":"ethusdc", "bidAdj":"43809995982499961913604", "askAdj":"43845058004094599738265", "quoteAvailable":true, "totalToken0Available":"7210037341486830593", "totalToken1Available":"19571324046", "latestBlock":24370650, "blockTs":1770053087, "serverTs":1770053095, "quoteExpiration":1770053099, "depth":{} } ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#field-definitions-1) Field Definitions Field Description `pair` Trading pair identifier. `bid` Current bid price (Q64 format). `ask` Current ask price (Q64 format). `quoteAvailable` Indicates whether a quote can be requested for the current block. `totalToken0Available` Total available liquidity for token0. `totalToken1Available` Total available liquidity for token1. `latestBlock` Block number of latest block `blockTs` UNIX timestamp of latest block `serverTs` Current UNIX timestamp on server `quoteExpiration` UNIX timestamp after which the quote is no longer valid. `depth` A dictionary of asks #### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#quoteavailable-semantics) `quoteAvailable` Semantics * `true` — A quote request can be made. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#price-format-q64) Price Format (Q64) Prices are returned in **Q64 fixed-point format**, representing the price of **1 ETH in USD**. To convert to a human-readable value: Copy price = priceX64 / 2^64 With the example values above, this results in approximately: Copy 2965 USD per ETH ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#price-inversion) Price Inversion To determine how much **ETH corresponds to 1 USD**, invert the price using: Copy invertedPriceX64 = 2^128 / priceX64 This yields a value in **ETH per USD (Q64 format)**. To convert to a human-readable number: Copy invertedPrice = invertedPriceX64 / 2^64 Using the example above: Copy ≈ 0.00033726 ETH per USD ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#depth) Depth Bid(asks are the same, we just start with ask and walk across ask bin) **depth price calculation:** Start with _currentPrice = bidAdj, remainingVolume = X_ Walk across bins. For each bin compute: &#xNAN;_volumeInThisBin = currentBin.cumulativeVolume − previousBin.cumulativeVolume_ If _remainingVolume <= volumeInThisBin_ — order completes inside this bin: _exitPrice = currentPrice + (currentBin.price − currentPrice) × remainingVolume / volumeInThisBin_ Record fill price: _(currentPrice + exitPrice) / 2_ weighted by remainingVolume Otherwise — order consumes entire bin: Record fill price: _(currentPrice + currentBin.price) / 2_ (It's linear within bin. But since bins can vary in size it's not linear across several bins.) Update _currentPrice = currentBin.price_, subtract _volumeInThisBin_ from _remainingVolume_, move to next bin Final _fill price = volume-weighted average of each bin's recorded fill price_ ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#usage-notes) Usage Notes * Cumulative volume is a scaled value of token1 to token0. Formula is: 10^(max(18, token1.decimals()) - token0.decimals()) * Q64 pricing internally normalizes token decimals (e.g. ETH: 18 decimals, USDC: 6 decimals). * The **quoter operates directly on Q64 values**, so no conversion is required when interacting with it. * For off-chain price comparisons, human-readable values may be used. * To convert human-readable prices back for calculations, multiply by `10^decimals` of the corresponding token. [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#simulate-the-swap) Simulate the Swap -------------------------------------------------------------------------------------------------------------------------------------- Was used previously before our bid\_ask api had the capacity to return depth and exact prices. Alternatively you can simulate a swap by calling the quoter contract: Copy quoteSwap( address pool, bool zeroForOne, int128 amountSpecified, uint128 priceLimitX64, uint128 bidPriceX64, (optional for api, must use on chain) uint128 askPriceX64,(optional for api, must use on chain) ) This function belongs to a separate smart contract (see **Section 2.4: Quoter Address**) and returns simulated swap results based on current market conditions. Prices are filled automatically based on our price providers. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#direct-contract-call) Direct Contract Call If calling the contract directly, use the `eth_call` RPC method. * The transaction is intentionally reverted during the internal call * Simulation results are returned via emitted logs * No state changes occur * Prices should be retrieved from price provider first ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#api-wrapper) API Wrapper For convenience, Metric exposes an HTTP API that wraps the quoter call: **POST** Copy http://54.199.103.16:8080/ethereum/0x3221901709F01737a601F9f02a01df6b13b2A6Ff/quote ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#inputs-1) Inputs Sent as JSON body parameters. Parameter Type Description `pool` address Pool address. `zeroForOne` bool Swap direction (`true`: token0 → token1). `amountSpecified` string Exact input or output amount (signed). `priceLimitX64` string Price limit in Q64 format. `bidPriceX64` string Current bid price (Q64). `askPriceX64` string Current ask price (Q64). ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#response-format-2) Response Format **Content-Type:** `application/json` **Relevant fields:** Field Description `amount0Delta` Amount of token0 sent (negative) or received (positive) by the pool. `amount1Delta` Amount of token1 sent (negative) or received (positive) by the pool. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#notes-1) Notes * Delta signs follow pool perspective (not trader perspective). * All price inputs must be provided in **Q64 format**. * No additional decimal normalization is required when using the quoter. * Currently API throws http error when trying to swap more tokens than available. This will be improved in the future. To return the quote for as many tokens as can be exchanged [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#check-our-gas-for-reference) Check our gas for reference ---------------------------------------------------------------------------------------------------------------------------------------------------------- Copy http://54.199.103.16:8080/ethereum/gas Response: Copy { "max_priority_fee_per_gas":"1300000000", "base_fee":"48502981", "max_fee_per_gas":"1348502981", "block_number":"24526324" } [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#request-a-signed-oracle-update) Request a Signed Oracle Update ---------------------------------------------------------------------------------------------------------------------------------------------------------------- ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#option-1-higher-fixed-heartbeat-fee-simpler) Option 1 — Higher Fixed Heartbeat Fee (Simpler) As a simpler alternative, the oracle heartbeat can be funded with a **higher default gas price**, removing the need for per-request signing. * Suitable for quick integrations Please contact us to agree on the gas price to be used in this mode. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated#option-2-signed-call-data-long-term) Option 2 — Signed Call Data (Long-Term) Copy http://54.199.103.16:8080/ethereum/0x3221901709F01737a601F9f02a01df6b13b2A6Ff/get_signed_data Address here is poolAddress of the pool **This is only necessary on ethereum.** On other chains we either have 99.99% inclusion or allow the price to survive for one or several more blocks to achieve desired uptime out of the box. As a long-term solution, the API will return: * Signed call data * Oracle contract address This allows integrators to **fully control oracle updates and gas management**. You can pass the data from this API to our oracle forcing an update. Your trade has to follow it in the same block. The oracle already exposes the following interface: Copy interface IUpgrader { function updateBySignature( address feedCreator, uint256 deadline, uint256 newSlotValue, bytes calldata signature ) external returns (bool success); } [PreviousSwapping directly via pool](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool) [NextSmart Contracts Reference(Deprecated)](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated) Last updated 1 month ago --- # Smart Contracts Reference | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference.md) . [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference#supported-chains-ethereum-base-hyperevm-soon) Supported chains: Ethereum, Base, HyperEVM(soon) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- **Deployer (owner):** 0xa9e4513754c3a86e752009d273f0c9eaee6a12a3 **Core** MetricOmmPoolFactory: 0x567C7205107257650dC73a73d87b879a45F5b6F6 MetricOmmPoolDeployer: 0xBe34D0cEb6CF1acbf55dEf35E4dC3e17BDfb6AE4 **Periphery:** LiquidityAdder: 0xA49acb20f33e4FB340f41d949fd7E4c48A242579 DataProvider: 0x803Cb583c1FbE97e9cA7899bE77cC110A78B8737 SwapQuoter: 0x8A45A0239DE0C8f438392f2E5AFcbee316E64965 Router: 0x146D72ad62957F62ABCC14985aBFCC32a785F996 **Extensions:** DepositAllowlist: 0xEd246C7B6963E20aa4fCa4912Af8E2Bff6Ca5f4D SwapAllowlist: 0x54BF5ba3c5C6C513722a54771b2F2A609e2e3A75 OracleValueStopLoss: 0x6063a740034E85d34cC55Bc7069BC7b7cdE888bf PriceVelocityGuard: 0xda4c0860d9fa8d254e425d485BD9C09BD2b051F7 [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference#abi) **ABI** ------------------------------------------------------------------------------------------------------------------------- Pool: 26KB [MetricOmmPool.abi.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FTczO3K6yJiYJwXhUYuS8%2FMetricOmmPool.abi.json?alt=media&token=24d842c3-5182-4b35-8994-38651a3dfd7a) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FTczO3K6yJiYJwXhUYuS8%2FMetricOmmPool.abi.json?alt=media&token=24d842c3-5182-4b35-8994-38651a3dfd7a) Router: 16KB [MetricOmmSimpleRouter.abi.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FyCvSLMTjzxHzOGhyaFyP%2FMetricOmmSimpleRouter.abi.json?alt=media&token=c02b4b62-3fc0-4d70-aae3-0d42bce60277) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FyCvSLMTjzxHzOGhyaFyP%2FMetricOmmSimpleRouter.abi.json?alt=media&token=c02b4b62-3fc0-4d70-aae3-0d42bce60277) Factory: 33KB [MetricOmmPoolFactory.abi.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FGZ3uM7bDMFsJ9GJ5qUw8%2FMetricOmmPoolFactory.abi.json?alt=media&token=ce1bc258-b805-4597-a809-0612ff010bea) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FGZ3uM7bDMFsJ9GJ5qUw8%2FMetricOmmPoolFactory.abi.json?alt=media&token=ce1bc258-b805-4597-a809-0612ff010bea) DataProvider: 10KB [MetricOmmPoolDataProvider.abi.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FIEuUq3u4UB5TAOVym3r5%2FMetricOmmPoolDataProvider.abi.json?alt=media&token=9cd3bfad-26f7-4f15-9fbd-eeff2e085e88) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FIEuUq3u4UB5TAOVym3r5%2FMetricOmmPoolDataProvider.abi.json?alt=media&token=9cd3bfad-26f7-4f15-9fbd-eeff2e085e88) Quoter: 15KB [MetricOmmSwapQuoter.abi.json](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FK3Mbob7wlCkr329isIhm%2FMetricOmmSwapQuoter.abi.json?alt=media&token=37203960-08de-4804-a26f-eef9b068dac6) Download[Open](https://883430748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwegByLMQJTopYqrvontp%2Fuploads%2FK3Mbob7wlCkr329isIhm%2FMetricOmmSwapQuoter.abi.json?alt=media&token=37203960-08de-4804-a26f-eef9b068dac6) [PreviousFind Best Route](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/find-best-route) [NextGet Quote](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote) Last updated 3 days ago --- # Find Best Route | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/find-best-route.md) . Find and price the best execution across direct and one-intermediate-hop paths for an **exact-input or exact-output** swap. Returns one or more routes; the input is split across multiple routes only when the configured thresholds show it reduces price impact. Copy POST /public/v1/evm/{chain_id}/routeAuthorization: Bearer **Auth required.** This is a Trading API endpoint. Copy Authorization: Bearer **Path parameters** Name Type Description `chain_id` integer Numeric EVM chain id. **Request body —** `**RouteRequest**` Field Type Required Description `tokenIn` string yes Input token address. Must differ from `tokenOut`, non-zero. `tokenOut` string yes Output token address. `tradeType` string no `exact_in` (default) or `exact_out`. `amountIn` string for `exact_in` Exact input, raw units (base-10, positive). `amountOut` string for `exact_out` Exact output target, raw units. `maxRoutes` integer no Cap on routes in the plan. `1` = single best route (no split); omitted = configured max. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/find-best-route#request) Request Copy # Route (exact-in) — single & split, one endpoint curl -X POST "https://api.metric.xyz/public/v1/evm/8453/route" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "tokenIn": "0x4200000000000000000000000000000000000006", "tokenOut": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "tradeType": "exact_in", "amountIn": "50000000000000000", "maxRoutes": 4 }' ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/find-best-route#response) Response `200 OK` Copy "tokenIn": "0x4200000000000000000000000000000000000006", "tokenOut": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "tradeType": "exact_in", "amountIn": "50000000000000000", "amountOut": "79489960", "effectivePriceX64": "29326618970", "priceImpactBestRoute": "0.000178", "candidatesConsidered": 4, "routes": [\ {\ "tradeType": "exact_in",\ "routeType": "direct",\ "amountIn": "50000000000000000",\ "amountOut": "79489960",\ "effectivePriceX64": "29326618970",\ "priceImpactE6": "178",\ "legs": [\ {\ "tradeType": "exact_in",\ "poolAddress": "0xa3211DD5f8BA5f8bAd40f8a21F39475fDeAf2c2A",\ "pair": "WETH/USDC",\ "zeroForOne": true,\ "tokenIn": "0x4200000000000000000000000000000000000006",\ "tokenOut": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",\ "amountIn": "50000000000000000",\ "amountOut": "79489960",\ "effectivePriceX64": "29326618970",\ "priceImpactE6": "178",\ "priceLimitX64": "0"\ }\ ]\ }\ ] } Field Type Description `tokenIn` / `tokenOut` string Echoed endpoints (lowercased). `tradeType` string Echoed; tells you which side was fixed. `amountIn` string For `exact_in`, the request; for `exact_out`, the computed required input. `amountOut` string For `exact_in`, total computed output; for `exact_out`, ≈ the requested target. `effectivePriceX64` string Blended execution price for the whole plan, Q64.64. `priceImpactBestRoute` string Best single route's price impact as a **decimal fraction** (`"0.0135"` = 1.35%). `candidatesConsidered` integer Number of candidate paths scored. `routes` array One entry per allocated route (≥1; multiple ⇒ split). **Each** `**routes[]**` **entry** Field Type Description `tradeType` string Echoed. `routeType` string `direct` or `one_hop`. `amountIn` / `amountOut` string Amounts allocated to this route (raw units). `effectivePriceX64` string This route's execution price, Q64.64. `priceImpactE6` string This route's cumulative price impact, E6 (`10000` = 1%). `legs` array Per-leg execution params. **Each leg** Field Type Description `tradeType` string Echoed. `poolAddress` string Pool to swap against. `pair` string Pool pair label. `zeroForOne` boolean Swap direction for this leg. `tokenIn` / `tokenOut` string Leg tokens. For one-hop, leg 2 `amountIn` = leg 1 `amountOut`. `amountIn` / `amountOut` string Leg amounts (raw units). `effectivePriceX64` string Leg execution price `priceImpactE6` string Leg cumulative price impact, E6. `priceLimitX64` string No-limit sentinel for the on-chain swap: `0` when `zeroForOne`, `2^128−1` otherwise. **How routing & splitting are decided** (internal — not all surfaced in the response) 1. Enumerate direct + one-hop candidates; score each by walking `bid_ask` depth bins for the requested amount. 2. Pick the best single route (baseline). If its price impact is below `split_threshold_bps`, return just that. 3. Otherwise greedily allocate across routes by marginal price, subject to `min_improvement_bps`, `min_leg_fraction_bps`, and `maxRoutes`. 4. A split is returned only if it beats the baseline's total output. The chosen `reason` (`below_split_threshold` / `single_route_after_allocation` / `not_better_than_baseline` / `split_applied`) and `splitApplied` are recorded in **logs/traces only**, not the response. **Errors** Status Meaning `400` Invalid body, `tokenIn == tokenOut`, zero address, non-positive amount, or missing `amountIn`/`amountOut` for the `tradeType`. `422` `no_route` (no eligible direct/one-hop path) or `insufficient_liquidity` (no candidate had enough depth). `503` Routing exceeded the 5s deadline. [PreviousRetrieve Current Bid and Ask](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask) [NextSmart Contracts Reference](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference) Last updated 4 days ago --- # Swapping directly via pool | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool.md) . [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool#swap-via-the-pool) Swap via the Pool ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Call `swap` directly on `MetricOmmPool` from a contract that implements `IMetricOmmSwapCallback`. Use this for full control over funding (vault, flash logic, aggregator settlement); otherwise prefer the Router, which handles settlement for you. This is also the **only entrypoint that does both exact-input and exact-output in one function** (via the sign of `amountSpecified`) — `MetricOmmSimpleRouter` splits those into separate `exactInput*` / `exactOutput*` calls. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool#swap-parameters) Swap Parameters Copy function swap( address recipient, // receives the output tokens bool zeroForOne, // true = token0→token1, false = token1→token0 int128 amountSpecified, // positive = exact input, negative = exact output (non-zero) uint128 priceLimitX64, // marginal price bound, Q64.64 bytes calldata callbackData, // forwarded to YOUR swap callback bytes calldata extensionData // forwarded to the pool's swap extensions ) external returns (int128 amount0Delta, int128 amount1Delta); * `amountSpecified == 0` reverts `InvalidAmount`. * `priceLimitX64` is your slippage protection (Q64.64 marginal bound). * `callbackData` is opaque — the pool never reads it; it's handed back to your `metricOmmSwapCallback` so you can route context (payer, leg, funding source). `"0x"` if unused. * `extensionData` is separate: the pool forwards it to its `beforeSwap` / `afterSwap` extension hooks, **not** to your callback. `"0x"` if the pool has no extensions or they need no input. * Reverts `PoolPaused` if the pool is paused. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool#swap-callback) Swap Callback The pool settles Uniswap V3–style. Per swap, in order: 1. The pool computes deltas and **sends the output token to** `**recipient**` (the negative-delta side). 2. It calls `metricOmmSwapCallback` on `msg.sender`. 3. Your callback **transfers the owed input token to the pool** (the positive-delta side). 4. The pool balance-checks repayment and reverts `IncorrectDelta` if you underpaid. Deltas (pool perspective): **positive** → you must send that token to the pool; **negative** → the pool already sent it to `recipient`; either may be `0`. Copy /// @notice Any contract that calls IMetricOmmPool#swap must implement this. interface IMetricOmmSwapCallback { /// @param amount0Delta positive => pool must receive token0 from the payer; negative => pool sent it out /// @param amount1Delta positive => pool must receive token1 from the payer; negative => pool sent it out /// @param callbackData opaque bytes forwarded from the swap call function metricOmmSwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata callbackData ) external; } Your callback **must verify** `**msg.sender**` **is a legitimate Metric pool** before paying — otherwise any contract can call it and drain funds. This pattern lets you source the input however you like (wallet, vault, flash) with no upfront approvals or pre-transfers, and composes with routing/settlement logic. The pool does not pull input tokens — your callback pushes them. The pool prices from its on-chain `priceProvider` at execution time. Sequence an oracle update ahead of the swap (same bundle/block) so it doesn't price stale or revert. [PreviousSwapping via Router](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router) [NextAPI(Deprecated)](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated) Last updated 4 days ago --- # Unknown \# Metric ## Docs - \[Introduction\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/introduction.md): Metric is a DEX built on the active pool standard. Instead of sitting at fixed prices like passive pools, Metric pools follow the market’s real price in real time. - \[Glossary\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary.md): Definitions for the pricing, swap, depth, routing, and contract terms used across these docs. - \[Oracle Basics\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/oracle-basics.md) - \[Integration guideline for Solvers/Aggregators\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators.md): Built for seamless plug-and-play integrations - \[via API\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api.md) - \[SDK\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/sdk.md) - \[API\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api.md) - \[Metadata\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata.md) - \[Retrieve Current Bid and Ask\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask.md) - \[Find Best Route\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/find-best-route.md) - \[Smart Contracts Reference\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference.md) - \[Get Quote\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote.md): Simulate a swap on-chain to get token deltas, without executing or changing state. - \[Swapping via Router\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router.md): Execute swaps through MetricOmmSwapRouter — no callback to implement. - \[Swapping directly via pool\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool.md): Call swap on the pool and settle via the IMetricOmmSwapCallback callback. - \[API(Deprecated)\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated.md) - \[Smart Contracts Reference(Deprecated)\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/introduction.md). # Introduction \*\*How active pools work\*\* Each pool runs on two components. A Price Provider reads an external oracle (Pyth, Chainlink, or custom) and handles the pricing logic. A Liquidity Module holds deposits and tracks the reference price automatically. When the market moves, the pool moves with it. Liquidity stays centered on the real market instead of drifting behind it. \*\*For aggregators and solvers\*\* Routing into Metric means routing into liquidity that is already centered on a real market reference, rather than liquidity that drifts and relies on arbitrage to be corrected after the move. Execution is expressed as a deviation around that reference. When the trade lands better than the route’s expected price, the surplus is captured by the routing stack. \*\*For market makers and propAMMs\*\* Metric is PropAMM-on-demand. You control bid, ask, and spread behavior through a Price Provider, and Metric handles the pool and distribution. No need to rebuild the oracle and pool stack. \*\*For RWA issuers\*\* Any asset with a primary price set off-chain gets a persistent on-chain venue that quotes against the live reference feed from launch. This covers tokenized equities, treasuries, commodities, FX, and any other asset with a reliable reference price. Every pool is composable across DeFi, so tokenized assets can be used as collateral, integrated into yield strategies, or plugged into structured products natively. \*\*For liquidity providers\*\* LPs benefit from reduced impermanent loss and a significantly improved liquidity management workflow. There is no longer a need to run rebalancing scripts or bots that continuously track price movements and re-enter liquidity. \*\*Metric. Everything on-chain, priced to reality.\*\* --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary.md). # Glossary ### Price formats & units #### Q64.64 Fixed-point number format used for all prices. The integer is the real value × 2^64; convert to human-readable with \`value / 2^64\`. A price is token0 expressed in token1 units (e.g. 1 ETH in USDC). Decimals are normalized internally, so no manual decimal adjustment is needed when feeding values back into the contracts. #### E6 "Parts per million" fixed-point: \`1\_000\_000\` = 100%, \`10\_000\` = 1%. Used for \`priceImpactE6\` and internal fee math (\`baseFeeE6\`). Note: the routing API's per-leg \`priceImpactE6\` is a raw E6 string, while the split response's top-level \`priceImpactBestRoute\` is the same quantity as a \*\*decimal fraction\*\* (\`0.01\` = 1%). #### bps (basis points) \`1 bps = 0.01% = 100 E6\`. Used for split-routing thresholds (\`split\_threshold\_bps\`, \`min\_improvement\_bps\`, \`min\_leg\_fraction\_bps\`). #### Scaling Cumulative depth volumes are reported in the \*\*output token's external (on-chain) decimals\*\*. The quoter itself operates in Q64.64 (decimals already normalized), so no conversion is needed when interacting with it; you only multiply by \`10^decimals\` when comparing against human-readable prices. The cumulative-volume scale factor is \`10^(max(18, token1.decimals()) − token0.decimals())\`. ### Prices & oracle #### Price Provider The on-chain oracle contract bound to a pool. Exposes \`getBidAndAskPrice()\` (Q64.64). Each pool's provider is returned by \`pool.getImmutables()\` and surfaced in metadata as \`priceProviderAddress\`. #### Raw oracle price The bid/ask straight from \`getBidAndAskPrice()\`. This is what \`swap()\` and \`simulateSwapAndRevert(...)\` consume to derive pricing — pass these into on-chain simulation so the quote matches execution. #### bidAdj / askAdj The \*\*fee-adjusted\*\* pool bid/ask returned by the bid/ask quote. Useful as Q64.64 price \*limits\*, but \*\*not\*\* interchangeable with raw oracle prices for simulation input. #### Base fee The spread-derived fee the pool applies, computed from \`sqrt(ask / bid)\` (in E6). Larger oracle spread → larger base fee. ### Swap mechanics #### zeroForOne Swap direction. \`true\` = token0 → token1 (price moves down); \`false\` = token1 → token0 (price moves up). #### amountSpecified The swap amount (\`int128\`). \*\*Positive\*\* = exact input; \*\*negative\*\* = exact output. \`0\` is a no-op (\`InvalidAmount\` on \`swap\`, \`(0,0)\` on simulation). #### recipient The address that receives the output tokens. May differ from the caller (\`msg.sender\`), which is the contract that implements and is charged in the callback. #### amount0Delta / amount1Delta The token balance changes from the \*\*pool's perspective\*\*: positive = the pool receives that token (you owe it), negative = the pool sends that token (to \`recipient\`). Either may be \`0\`. #### priceLimitX64 Worst marginal pool price you'll accept, Q64.64. The swap fills bin-by-bin and \*\*stops\*\* at the limit — a partial fill when interracting with pool directly. When using router - it reverts instead. Acts as a \*\*floor\*\* when \`zeroForOne = true\` (no-limit sentinel \`0\`) and a \*\*ceiling\*\* when \`false\` (no-limit sentinel \`2^128 − 1\`). \`0\` on an upward swap fills nothing. #### Swap callback (\`metricOmmSwapCallback\`) The settlement hook the pool calls on \`msg.sender\` mid-swap. The pool sends the output token first, then the callback must transfer the owed input token to the pool (verified via balance check, else \`IncorrectDelta\`). Deltas are passed as \`int256\`. Required only when calling the pool directly — the Router implements it for you. ### Contracts #### Pool (\`MetricOmmPool\`) The core AMM contract. Holds liquidity, prices from its Price Provider, and exposes \`swap\` and \`simulateSwapAndRevert\`. #### Quoter (\`MetricOmmPoolQuoter\`) Periphery, simulation-only. \`quoteSwap\` wraps the pool's revert-based simulation and returns deltas normally. #### Router (\`MetricOmmSwapRouter\`) Periphery, execution. Implements the swap callback so integrators can swap with a simple \`approve\` + call (incl. native-ETH variants and slippage guards). Inherits the Quoter. #### Factory (\`MetricOmmPoolFactory\`) Deploys pools (\`createPool\`) and holds protocol-fee settings. #### simulateSwapAndRevert Pool function that runs the swap math, then \*\*reverts\*\* with the result. No state persists. #### SimulateSwap The custom error \`SimulateSwap(int128 amount0Delta, int128 amount1Delta)\` that carries simulation results in the revert data. #### WrappedError \`WrappedError(address target, bytes4 selector, bytes reason, …)\` wraps an unexpected inner revert so callers can see what failed. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/oracle-basics.md). # Oracle Basics The oracle publishes one authoritative \*\*snapshot per block\*\* — a \*\*mid price + spread\*\* (and a volatility field) for every market. Bid/ask are not published directly; they're derived downstream by the Price Provider (for public pools the \*\*AnchoredPriceProvider\*\* clamps the quote into a band around this mid). \*\*Oracle type is chain-dependent:\*\* \* \*\*Ethereum (L1) — \`CompressedOracleV1\`:\*\* updates are \*\*signature-authorized\*\*. The snapshot is signed by the feed creator (Metric); \*\*anyone can relay a valid signed update\*\* (e.g. with higher gas for priority) — it can't be forged or altered. (Metric may also pre-authorize pusher addresses to push without a per-message signature.) \* \*\*L2 — permissionless \`PythOracle\` (Pyth Lazer) / \`ChainlinkOracle\` (Chainlink Data Streams):\*\* anyone can submit a valid Pyth/Chainlink update. Multiple oracle types coexist; the pool/curator chooses. \*\*Key principles:\*\* \* \*\*Recency is enforced at the Price Provider level\*\* (\`maxTimeDelta\`, bounded \`0 < value ≤ 7 days\`). Recommended: \*\*same block on Ethereum\*\*, a few blocks on sub-1s L2s. \* A trade settles \*\*only\*\* against a sufficiently recent valid update. A swap placed before a valid update for the block — or against a stale price — \*\*reverts\*\*. \* \*\*Chainlink sanity check (optional):\*\* the oracle price can be cross-checked against a Chainlink reference feed (\`maxClDeviation\`). On excessive deviation, \*\*no price is returned → the trade reverts\*\*. \* \*\*L2 extra guards:\*\* the Price Provider also checks the \*\*sequencer-uptime feed\*\* (with a grace period) and allows a small \`FUTURE\_TOLERANCE\` for slightly-ahead oracle timestamps. \* \*\*Read access (L2 providers):\*\* open reads are disabled (\`getOracleData\` / \`price(feedId)\` revert \`ReadDisabled\`); the price is readable only via the attributed \`price(feedId, pool)\` path during an active swap, or \`integratorPrice\` for whitelisted integrators. ### Heartbeat Update \* \*\*Frequency:\*\* once per block on Ethereum (on L2 this varies — sometimes several updates per block, depending on gas/volatility). \* \*\*Timing:\*\* on average at the \*\*\\~11th second\*\* of each Ethereum block (≈1s delta from source). \* \*\*Gas:\*\* slightly above average (e.g. \\~0.15 gwei). \* \*\*Payload:\*\* the signed market snapshot — \*\*mid + spread for all markets\*\*. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/via-api.md). # via API At a high level, integrating via the API follows these steps: ### 1. Discover Available Pools Query the \[metadata endpoint\](/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata.md) to retrieve: \* Supported trading pairs \* Pool addresses \* Quoter and token addresses This allows your system to dynamically discover and route to available Metric pools. \*\*\* ### 2. Fetch Current Bid / Ask Request the current \[bid and ask prices\](/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask.md) for a selected pair. \* Prices are returned for the \*\*current block\*\* \* Depth is returned in addition to prices and can be used to calculate price impact \* Returned prices are already normalized for use with Metric’s contracts These prices are used both for quoting and for setting execution limits. \*\*\* ### 3. Execute the Trade Finally, execute the trade by calling the \`swap\` function on either the \[Router \](/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router.md)or the \[Pool\](/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool.md). \* Supports both \*\*exact-input\*\* and \*\*exact-output\*\* swaps \* Uses the same \[Q64 price format\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators/pages/324yI42UQErLVlAM9lbk#q64.64) for bid, ask, and price limits \* \[Price limits\](/metric/RSm94m71kqtGICv4iKRj/app/glossary.md#pricelimitx64) protect execution against excessive slippage \*\*\* \*\*Important notice:\*\* Oracle update has to happen before trade execution in order to avoid reverts --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators.md). # Integration guideline for Solvers/Aggregators ### Integration Overview Metric can be integrated in two ways, depending on latency and trust requirements: #### Option 1 — Smart Contract / SDK Integration Integrate directly with Metric’s on-chain contracts using the SDK. \* Fully trustless and on-chain \* Quotes are derived from the \*\*previous block\*\* \* Simpler operationally, but prices always lag by one block This approach is suitable for systems where determinism and on-chain guarantees matter more than absolute price freshness. #### Option 2 — API Integration (Recommended) Integrate via the Metric API, which returns pricing and liquidity information \*\*for the current block\*\*. \* Quotes are always up-to-date with the active block \* Enables better execution quality during periods of high volatility This is the recommended approach for \*\*solvers, aggregators, and professional execution systems\*\* that prioritize the best execution. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/sdk.md). # SDK Current version of SDK supports liquidity operations and swaps. More functions will be rolled out with time --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api.md). # API ### Metric API \*\*Base URL:\*\* \`https://api.metric.xyz\` #### Authentication Bid/ask, quote, and routing endpoints require a Bearer token: {% code overflow="wrap" %} \`\`\` Authorization: Bearer \`\`\` {% endcode %} {% hint style="info" %} Trading API keys are issued by the Metric team — \[contact us\](mailto:hello@metric.xyz) to request one. {% endhint %} Some public endpoints (chains, metadata) require no authentication. \*\*\* ### Supported Chains Retrieve the list of supported chains and their numeric EVM chain IDs: {% code overflow="wrap" %} \`\`\` GET /public/v1/chains \`\`\` {% endcode %} Use the returned \`chain\_id\` values as the \`{chain\_id}\` path parameter in all chain-specific endpoints below. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/metadata.md). # Metadata \`\`\` GET /public/v1/evm/{chain\_id}/metadata \`\`\` Returns the configured pools on a chain together with their on-chain metadata, token details, fiat prices, and pool state. Results are paginated. {% hint style="info" %} \*\*Auth:\*\* none — this is a public endpoint. {% endhint %} ### Path parameters | Name | Type | Description | | ---------- | ------- | ----------------------------------------------------- | | \`chain\_id\` | integer | Numeric EVM chain id (e.g. \`1\` for Ethereum mainnet). | ### Query parameters All optional. | Name | Type | Default | Description | | ----------------- | ------- | ------- | ---------------------------------------------------------- | | \`offset\` | integer | \`0\` | Index of the first row to return. | | \`count\` | integer | \`50\` | Page size. Clamped to \`\[1, 500\]\`. | | \`sortBy\` | string | \`tvl\` | One of \`tvl\`, \`created\`, \`volume\`, \`apr\`. | | \`include24h\` | boolean | \`false\` | Include the optional \`analytics24h\` block on each pool. | | \`fiat\` | string | \`USD\` | Fiat currency for priced fields. USD is the primary value. | | \`contractVersion\` | string | \`v1\` | Filter to a single configured pool contract generation. | ### Pagination Read \`nextOffset\` from the response and pass it back as \`offset\` to fetch the next page. \`nextOffset\` is \`null\` on the last page. \`total\` is the full count across all pages. ### Request {% tabs %} {% tab title="cURL" %} \`\`\`bash curl "https://api.metric.xyz/public/v1/evm/1/metadata?count=50&sortBy=tvl" \`\`\` {% endtab %} {% tab title="With analytics" %} \`\`\`bash curl "https://api.metric.xyz/public/v1/evm/1/metadata?include24h=true&count=50" \`\`\` {% endtab %} {% endtabs %} ### Response \`200 OK\` — a \`PaginatedMetadataResponse\` envelope. | Field | Type | Description | | ------------ | --------------- | ------------------------------------------------- | | \`data\` | array | The page of pools (see fields below). | | \`total\` | integer | Total pools matching the query, across all pages. | | \`nextOffset\` | integer \\| null | \`offset\` for the next page, or \`null\` if last. | \`\`\`json { "data": \[\ {\ "pair": "ethusdc",\ "chain": "ethereum",\ "contractVersion": "v1",\ "poolAddress": "0xbF48bCf474d57fF82A3215319229e0DE1476A557",\ "priceProviderAddress": "0xbD321D18a7ce5fb91F8b16e026e3258f7b310598",\ "token0": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",\ "token1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",\ "token0Symbol": "WETH",\ "token1Symbol": "USDC",\ "token0Decimals": 18,\ "token1Decimals": 6,\ "token0FiatPrice": 3200.25,\ "token1FiatPrice": 1.0,\ "tvlFiat": 1234.56,\ "creator": "0x0000000000000000000000000000000000000000",\ "adminFeeDestination": "0x0000000000000000000000000000000000000000",\ "classificationTier": "unverified",\ "priceProviderCooldownSecs": 0,\ "depositWhitelistingEnabled": false,\ "swapWhitelistingEnabled": false,\ "poolFactoryAddress": "0x0000000000000000000000000000000000000000",\ "poolDeployerAddress": "0x0000000000000000000000000000000000000000",\ "liquidityAdderAddress": "0x0000000000000000000000000000000000000000",\ "dataProviderAddress": "0x0000000000000000000000000000000000000000",\ "depositAndSwapAllowlistAddress": "0x0000000000000000000000000000000000000000",\ "swapperAddress": "0x0000000000000000000000000000000000000000"\ }\ \], "total": 1, "nextOffset": null } \`\`\` #### Pool fields | Field | Type | Notes | | --------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------- | | \`pair\` | string | Human-readable pair label, e.g. \`ethusdc\`. | | \`chain\` | string | Chain name. | | \`contractVersion\` | string | Pool contract generation. | | \`poolAddress\` | string | \[Pool contract address\](/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference.md). | | \`priceProviderAddress\` | string | Oracle / \[price-provider contract\](/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference.md) for the pool. | | \`token0\`, \`token1\` | string | Token contract addresses. | | \`token0Symbol\`, \`token1Symbol\` | string | Optional. Omitted when unknown. | | \`token0Decimals\`, \`token1Decimals\` | integer | Optional. | | \`token0FiatPrice\`, \`token1FiatPrice\` | number \\| null | Always present; \`null\` when no price is available. | | \`tvlFiat\` | number | Optional. Total value locked in \`fiat\`. | | \`classificationTier\` | string | Pool trust tier, e.g. \`unverified\`, \`standard\`. | | \`priceProviderCooldownSecs\` | integer | Time needed to update existing Price Provider | | \`depositWhitelistingEnabled\` | boolean | Whether deposits are allowlist-gated. | | \`swapWhitelistingEnabled\` | boolean | Whether swaps are allowlist-gated. | | \`analytics24h\` | object | Present only when \`include24h=true\`. | | \`poolFactoryAddress\` … \`swapperAddress\` | string | \[Factory contract\](/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference.md) for the pool. | {% hint style="warning" %} Optional fields (\`token0Symbol\`, \`tvlFiat\`, \`analytics24h\`, \`priceProviderChange\`, allowlist providers, …) are \*\*omitted entirely\*\* when absent — they are not returned as \`null\`. The two exceptions are \`token0FiatPrice\` and \`token1FiatPrice\`, which are always present and may be \`null\`. {% endhint %} {% hint style="info" %} Throughout this documentation, \*\*\`ethusdc\`\*\* is the primary example pair. Any other pair returned by this endpoint can be substituted directly, following the same conventions and integration flow. {% endhint %} --- # Introduction | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/introduction.md) . **How active pools work** Each pool runs on two components. A Price Provider reads an external oracle (Pyth, Chainlink, or custom) and handles the pricing logic. A Liquidity Module holds deposits and tracks the reference price automatically. When the market moves, the pool moves with it. Liquidity stays centered on the real market instead of drifting behind it. **For aggregators and solvers** Routing into Metric means routing into liquidity that is already centered on a real market reference, rather than liquidity that drifts and relies on arbitrage to be corrected after the move. Execution is expressed as a deviation around that reference. When the trade lands better than the route’s expected price, the surplus is captured by the routing stack. **For market makers and propAMMs** Metric is PropAMM-on-demand. You control bid, ask, and spread behavior through a Price Provider, and Metric handles the pool and distribution. No need to rebuild the oracle and pool stack. **For RWA issuers** Any asset with a primary price set off-chain gets a persistent on-chain venue that quotes against the live reference feed from launch. This covers tokenized equities, treasuries, commodities, FX, and any other asset with a reliable reference price. Every pool is composable across DeFi, so tokenized assets can be used as collateral, integrated into yield strategies, or plugged into structured products natively. **For liquidity providers** LPs benefit from reduced impermanent loss and a significantly improved liquidity management workflow. There is no longer a need to run rebalancing scripts or bots that continuously track price movements and re-enter liquidity. **Metric. Everything on-chain, priced to reality.** [NextGlossary](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary) Last updated 3 days ago --- # Oracle Basics | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/oracle-basics.md) . The oracle publishes one authoritative **snapshot per block** — a **mid price + spread** (and a volatility field) for every market. Bid/ask are not published directly; they're derived downstream by the Price Provider (for public pools the **AnchoredPriceProvider** clamps the quote into a band around this mid). **Oracle type is chain-dependent:** * **Ethereum (L1) —** `**CompressedOracleV1**`**:** updates are **signature-authorized**. The snapshot is signed by the feed creator (Metric); **anyone can relay a valid signed update** (e.g. with higher gas for priority) — it can't be forged or altered. (Metric may also pre-authorize pusher addresses to push without a per-message signature.) * **L2 — permissionless** `**PythOracle**` **(Pyth Lazer) /** `**ChainlinkOracle**` **(Chainlink Data Streams):** anyone can submit a valid Pyth/Chainlink update. Multiple oracle types coexist; the pool/curator chooses. **Key principles:** * **Recency is enforced at the Price Provider level** (`maxTimeDelta`, bounded `0 < value ≤ 7 days`). Recommended: **same block on Ethereum**, a few blocks on sub-1s L2s. * A trade settles **only** against a sufficiently recent valid update. A swap placed before a valid update for the block — or against a stale price — **reverts**. * **Chainlink sanity check (optional):** the oracle price can be cross-checked against a Chainlink reference feed (`maxClDeviation`). On excessive deviation, **no price is returned → the trade reverts**. * **L2 extra guards:** the Price Provider also checks the **sequencer-uptime feed** (with a grace period) and allows a small `FUTURE_TOLERANCE` for slightly-ahead oracle timestamps. * **Read access (L2 providers):** open reads are disabled (`getOracleData` / `price(feedId)` revert `ReadDisabled`); the price is readable only via the attributed `price(feedId, pool)` path during an active swap, or `integratorPrice` for whitelisted integrators. ### [](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers#heartbeat-update) Heartbeat Update * **Frequency:** once per block on Ethereum (on L2 this varies — sometimes several updates per block, depending on gas/volatility). * **Timing:** on average at the **~11th second** of each Ethereum block (≈1s delta from source). * **Gas:** slightly above average (e.g. ~0.15 gwei). * **Payload:** the signed market snapshot — **mid + spread for all markets**. [PreviousGlossary](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/app/glossary) [NextIntegration guideline for Solvers/Aggregators](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/aggregators-solvers/integration-guideline-for-solvers-aggregators) Last updated 6 days ago --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference.md). # Smart Contracts Reference ## Supported chains: Ethereum, Base, HyperEVM(soon) \*\*Deployer (owner):\*\* 0xa9e4513754c3a86e752009d273f0c9eaee6a12a3 \*\*Core\*\*\\ MetricOmmPoolFactory: 0x567C7205107257650dC73a73d87b879a45F5b6F6\\ MetricOmmPoolDeployer: 0xBe34D0cEb6CF1acbf55dEf35E4dC3e17BDfb6AE4 \*\*Periphery:\*\*\\ LiquidityAdder:\\ 0xA49acb20f33e4FB340f41d949fd7E4c48A242579\\ DataProvider:\\ 0x803Cb583c1FbE97e9cA7899bE77cC110A78B8737\\ SwapQuoter:\\ 0x8A45A0239DE0C8f438392f2E5AFcbee316E64965\\ Router:\\ 0x146D72ad62957F62ABCC14985aBFCC32a785F996 \*\*Extensions:\*\*\\ DepositAllowlist:\\ 0xEd246C7B6963E20aa4fCa4912Af8E2Bff6Ca5f4D\\ SwapAllowlist:\\ 0x54BF5ba3c5C6C513722a54771b2F2A609e2e3A75\\ OracleValueStopLoss:\\ 0x6063a740034E85d34cC55Bc7069BC7b7cdE888bf\\ PriceVelocityGuard:\\ 0xda4c0860d9fa8d254e425d485BD9C09BD2b051F7 ## \*\*ABI\*\* Pool: {% file src="/files/0sm4D0arwjxZLRl81mBW" %} Router: {% file src="/files/vKt6ExfeefZrN3o3wpGh" %} Factory: {% file src="/files/IZ5bHCmv7R8oWqrt0vaX" %} DataProvider: {% file src="/files/vUTSBkGN6ObSoWj5a6wY" %} Quoter: {% file src="/files/0i9ChKrdTv7w9fwtgwOa" %} --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated.md). # API(Deprecated) ## Metadata Endpoint You can retrieve all available trading pairs along with their associated on-chain metadata using the following endpoint: \*\*GET\*\* \`\`\` http://54.199.103.16:8080/ethereum/metadata http://54.199.103.16:8080/base/metadata http://54.199.103.16:8080/bsc/metadata http://54.199.103.16:8080/arbitrum/metadata http://54.199.103.16:8080/avax/metadata http://54.199.103.16:8080/polygon/metadata http://54.199.103.16:8080/megaeth/metadata http://54.199.103.16:8080/hyperevm/metadata http://54.199.103.16:8080/monad/metadata \`\`\` ### Description This endpoint returns a list of supported pairs and the relevant contract addresses required for integration, including pool, price provider, and quoter contracts, as well as the underlying token addresses. ### Response Format \*\*Content-Type:\*\* \`application/json\` \*\*Example response:\*\* \`\`\`json \[\ {\ "pair": "ethusdc",\ "poolAddress": "0xbF48bCf474d57fF82A3215319229e0DE1476A557",\ "priceProvider\_address": "0xbD321D18a7ce5fb91F8b16e026e3258f7b310598",\ "quoterAddress": "0x58F9d1865d4Aeb59a9a7Dc68A3b4e0B42D9Ef5eD",\ "token0": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",\ "token1": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",\ "cexStep":0.0002,\ "dexStep":0.0\ }\ \] \`\`\` ### Field Definitions | Field | Description | | ----------------------- | ---------------------------------------------------------------------- | | \`pair\` | Canonical pair identifier (lowercase, no separator). | | \`poolAddress\` | Address of the Metric liquidity pool for the pair. | | \`priceProvider\_address\` | Address of the active Price Provider used to source reference pricing. | | \`quoterAddress\` | Address of the quoter contract used for off-chain quoting. | | \`token0\` | Address of the first token in the pair. | | \`token1\` | Address of the second token in the pair. | ### Notes Throughout the documentation, \*\*\`ethusdc\`\*\* is used as the primary example pair.\\ Any other supported pair returned by this endpoint can be substituted directly, following the same conventions and integration flow. ## Retrieve Current Bid and Ask You can retrieve the current bid and ask prices for a given pair using the following endpoint. Prices are returned based on current data from price provider. On most chains this causes insignificant price delays of below 1 second. On ethereum it currently causes a delay of 12 seconds. We are working to address this with our next update. \*\*GET\*\* \`\`\` http://54.199.103.16:8080/ethereum/0x3221901709F01737a601F9f02a01df6b13b2A6Ff/bid\_ask \`\`\` Pool address serves as unique identifier and is used in this api. ### Inputs Sent as POST(Currently implemented as GET method for simplicity) parameters. | Parameter | Description | | ----------- | ---------------------------------------------------------------- | | \`secretKey\` | Authentication key (will be required later). Currently optional. | ### Response Format \*\*Content-Type:\*\* \`application/json\` \*\*Example response:\*\* \`\`\`json { "pair":"ethusdc", "bidAdj":"43809995982499961913604", "askAdj":"43845058004094599738265", "quoteAvailable":true, "totalToken0Available":"7210037341486830593", "totalToken1Available":"19571324046", "latestBlock":24370650, "blockTs":1770053087, "serverTs":1770053095, "quoteExpiration":1770053099, "depth":{} } \`\`\` ### Field Definitions | Field | Description | | ---------------------- | ----------------------------------------------------------------- | | \`pair\` | Trading pair identifier. | | \`bid\` | Current bid price (Q64 format). | | \`ask\` | Current ask price (Q64 format). | | \`quoteAvailable\` | Indicates whether a quote can be requested for the current block. | | \`totalToken0Available\` | Total available liquidity for token0. | | \`totalToken1Available\` | Total available liquidity for token1. | | \`latestBlock\` | Block number of latest block | | \`blockTs\` | UNIX timestamp of latest block | | \`serverTs\` | Current UNIX timestamp on server | | \`quoteExpiration\` | UNIX timestamp after which the quote is no longer valid. | | \`depth\` | A dictionary of asks | #### \`quoteAvailable\` Semantics \* \`true\` — A quote request can be made. ### Price Format (Q64) Prices are returned in \*\*Q64 fixed-point format\*\*, representing the price of \*\*1 ETH in USD\*\*. To convert to a human-readable value: \`\`\` price = priceX64 / 2^64 \`\`\` With the example values above, this results in approximately: \`\`\` 2965 USD per ETH \`\`\` ### Price Inversion To determine how much \*\*ETH corresponds to 1 USD\*\*, invert the price using: \`\`\` invertedPriceX64 = 2^128 / priceX64 \`\`\` This yields a value in \*\*ETH per USD (Q64 format)\*\*. To convert to a human-readable number: \`\`\` invertedPrice = invertedPriceX64 / 2^64 \`\`\` Using the example above: \`\`\` ≈ 0.00033726 ETH per USD \`\`\` ### Depth \\ Bid(asks are the same, we just start with ask and walk across ask bin) \*\*depth price calculation:\*\* Start with \*currentPrice = bidAdj, remainingVolume = X\* Walk across bins. For each bin compute:\\ \\&#xNAN;\*volumeInThisBin = currentBin.cumulativeVolume − previousBin.cumulativeVolume\* If \*remainingVolume <= volumeInThisBin\* — order completes inside this bin: \*exitPrice = currentPrice + (currentBin.price − currentPrice) × remainingVolume / volumeInThisBin\* Record fill price: \*(currentPrice + exitPrice) / 2\* weighted by remainingVolume Otherwise — order consumes entire bin: Record fill price: \*(currentPrice + currentBin.price) / 2\* (It's linear within bin. But since bins can vary in size it's not linear across several bins.) Update \*currentPrice = currentBin.price\*, subtract \*volumeInThisBin\* from \*remainingVolume\*, move to next bin Final \*fill price = volume-weighted average of each bin's recorded fill price\* ### Usage Notes \* Cumulative volume is a scaled value of token1 to token0. Formula is:\\ 10^(max(18, token1.decimals()) - token0.decimals()) \* Q64 pricing internally normalizes token decimals (e.g. ETH: 18 decimals, USDC: 6 decimals). \* The \*\*quoter operates directly on Q64 values\*\*, so no conversion is required when interacting with it. \* For off-chain price comparisons, human-readable values may be used. \* To convert human-readable prices back for calculations, multiply by \`10^decimals\` of the corresponding token. ## Simulate the Swap Was used previously before our bid\\\_ask api had the capacity to return depth and exact prices. Alternatively you can simulate a swap by calling the quoter contract: \`\`\` quoteSwap( address pool, bool zeroForOne, int128 amountSpecified, uint128 priceLimitX64, uint128 bidPriceX64, (optional for api, must use on chain) uint128 askPriceX64,(optional for api, must use on chain) ) \`\`\` This function belongs to a separate smart contract (see \*\*Section 2.4: Quoter Address\*\*) and returns simulated swap results based on current market conditions. Prices are filled automatically based on our price providers. ### Direct Contract Call If calling the contract directly, use the \`eth\_call\` RPC method. \* The transaction is intentionally reverted during the internal call \* Simulation results are returned via emitted logs \* No state changes occur \* Prices should be retrieved from price provider first ### API Wrapper For convenience, Metric exposes an HTTP API that wraps the quoter call: \*\*POST\*\* \`\`\` http://54.199.103.16:8080/ethereum/0x3221901709F01737a601F9f02a01df6b13b2A6Ff/quote \`\`\` ### Inputs Sent as JSON body parameters. | Parameter | Type | Description | | ----------------- | ------- | ----------------------------------------- | | \`pool\` | address | Pool address. | | \`zeroForOne\` | bool | Swap direction (\`true\`: token0 → token1). | | \`amountSpecified\` | string | Exact input or output amount (signed). | | \`priceLimitX64\` | string | Price limit in Q64 format. | | \`bidPriceX64\` | string | Current bid price (Q64). | | \`askPriceX64\` | string | Current ask price (Q64). | ### Response Format \*\*Content-Type:\*\* \`application/json\` \*\*Relevant fields:\*\* | Field | Description | | -------------- | -------------------------------------------------------------------- | | \`amount0Delta\` | Amount of token0 sent (negative) or received (positive) by the pool. | | \`amount1Delta\` | Amount of token1 sent (negative) or received (positive) by the pool. | ### Notes \* Delta signs follow pool perspective (not trader perspective). \* All price inputs must be provided in \*\*Q64 format\*\*. \* No additional decimal normalization is required when using the quoter. \* Currently API throws http error when trying to swap more tokens than available. This will be improved in the future. To return the quote for as many tokens as can be exchanged ## Check our gas for reference \`\`\` http://54.199.103.16:8080/ethereum/gas \`\`\` Response: \`\`\`json { "max\_priority\_fee\_per\_gas":"1300000000", "base\_fee":"48502981", "max\_fee\_per\_gas":"1348502981", "block\_number":"24526324" } \`\`\` ## Request a Signed Oracle Update ### Option 1 — Higher Fixed Heartbeat Fee (Simpler) As a simpler alternative, the oracle heartbeat can be funded with a \*\*higher default gas price\*\*, removing the need for per-request signing. \* Suitable for quick integrations Please contact us to agree on the gas price to be used in this mode. ### Option 2 — Signed Call Data (Long-Term) \`\`\` http://54.199.103.16:8080/ethereum/0x3221901709F01737a601F9f02a01df6b13b2A6Ff/get\_signed\_data \`\`\` Address here is poolAddress of the pool \*\*This is only necessary on ethereum.\*\* On other chains we either have 99.99% inclusion or allow the price to survive for one or several more blocks to achieve desired uptime out of the box. As a long-term solution, the API will return: \* Signed call data \* Oracle contract address This allows integrators to \*\*fully control oracle updates and gas management\*\*. You can pass the data from this API to our oracle forcing an update. Your trade has to follow it in the same block. The oracle already exposes the following interface: \`\`\`solidity interface IUpgrader { function updateBySignature( address feedCreator, uint256 deadline, uint256 newSlotValue, bytes calldata signature ) external returns (bool success); } \`\`\` --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/retrieve-current-bid-and-ask.md). # Retrieve Current Bid and Ask \`\`\` GET /public/v1/evm/{chain\_id}/{pool\_address}/bid\_ask \`\`\` Returns the current bid and ask prices for a pool, derived from the latest price-provider data, with optional per-bin depth. {% hint style="warning" %} \*\*Auth required.\*\* This is a Trading API endpoint. \`\`\` Authorization: Bearer \`\`\` {% endhint %} The \`pool\_address\` is the unique identifier used throughout the API. ### Path parameters | Name | Type | Description | | -------------- | ------- | ---------------------------------------- | | \`chain\_id\` | integer | Numeric EVM chain id. | | \`pool\_address\` | string | Pool contract address (\`0x…\`, 20 bytes). | ### Query parameters All optional. | Name | Type | Default | Description | | ------- | ------- | ------- | -------------------------------------------------------------------------------- | | \`depth\` | boolean | \`true\` | Include the \`depth\` order book. Set \`false\` to omit it (\`depth\` becomes \`null\`). | ### Request \`\`\`bash curl "https://api.metric.xyz/public/v1/evm/1/0xbF48bCf474d57fF82A3215319229e0DE1476A557/bid\_ask" \\ -H "Authorization: Bearer " \`\`\` ### Response \`200 OK\` \`\`\`json { "pair": "ethusdc", "poolAddress": "0xbF48bCf474d57fF82A3215319229e0DE1476A557", "bidAdj": "43809995982499961913604", "askAdj": "43845058004094599738265", "totalToken0Available": "7210037341486830593", "totalToken1Available": "19571324046", "serverTs": 1770053095, "depth": { "bids": \[\ {\ "binIdx": -1,\ "price": "43750000000000000000000",\ "cumulativeVolume": "5000000000",\ "cumulativeInputVolume": "5000000000",\ "priceImpactE6": "1350"\ }\ \], "asks": \[\ {\ "binIdx": 1,\ "price": "43900000000000000000000",\ "cumulativeVolume": "5000000000",\ "cumulativeInputVolume": "5000000000",\ "priceImpactE6": "1252"\ }\ \] } } \`\`\` | Field | Type | Description | | ---------------------- | -------------- | ------------------------------------------------------------------ | | \`pair\` | string | Pair label, e.g. \`ethusdc\`. | | \`poolAddress\` | string | Pool contract address. | | \`bidAdj\` | string | Fee-adjusted bid price, Q64.64 (see below). | | \`askAdj\` | string | Fee-adjusted ask price, Q64.64. | | \`totalToken0Available\` | string \\| null | Token0 available for the quote (raw units). \`null\` if unavailable. | | \`totalToken1Available\` | string \\| null | Token1 available for the quote (raw units). | | \`serverTs\` | integer | Server Unix timestamp (seconds) when the quote was produced. | | \`depth\` | object \\| null | Per-bin depth (\`bids\`, \`asks\`). \`null\` when \`depth=false\`. | Each \`depth\` level (\`bids\[i\]\` / \`asks\[i\]\`): | Field | Type | Description | | ----------------------- | ------- | ---------------------------------------------------------------------------------------------- | | \`binIdx\` | integer | Bin index relative to the current position. | | \`price\` | string | Fee-adjusted price at this bin boundary (Q64.64). | | \`cumulativeVolume\` | string | Cumulative output-token volume from the current position to this boundary (external decimals). | | \`cumulativeInputVolume\` | string | Cumulative input-token amount required to reach this boundary. | | \`priceImpactE6\` | string | Cumulative price impact in E6 units (\`1\_000\_000\` = 100%) vs. current bid/ask. | ### Depth Bid depth calculation (ask is symmetric — start from \`askAdj\` and walk the ask bins the same way). 1. Set \`currentPrice = bidAdj\`, \`remainingVolume = X\`. 2. \*\*For each bin\*\*, compute \`volumeInThisBin = currentBin.cumulativeVolume − previousBin.cumulativeVolume\`, then take \*\*exactly one\*\* of the two cases below: \*\*Case A — the order completes inside this bin\*\* (\`remainingVolume ≤ volumeInThisBin\`): \`\`\` exitPrice = currentPrice + (currentBin.price − currentPrice) × remainingVolume / volumeInThisBin fillPrice = (currentPrice + exitPrice) / 2 // weighted by remainingVolume \`\`\` → \*\*stop.\*\* \*\*Case B — the order consumes the entire bin\*\* (\`remainingVolume > volumeInThisBin\`): \`\`\` fillPrice = (currentPrice + currentBin.price) / 2 // weighted by volumeInThisBin currentPrice = currentBin.price remainingVolume -= volumeInThisBin \`\`\` → \*\*continue to the next bin\*\* (repeat step 2). 3. \*\*Final fill price\*\* = volume-weighted average of each bin's recorded \`fillPrice\`. > Price is linear within a single bin, but not across bins, because bins can vary in size. {% hint style="info" %} \[\*\*Scaling\*\*\](broken://pages/Gvu6za4NSW93D4pWPhdu#scaling)\*\*.\*\* \`cumulativeVolume\` is a scaled token1 quantity. {% endhint %} --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/get-quote.md). # Get Quote ## Simulate Swap (Quote) Two ways to get a quote off-chain (both \`eth\_call\`, no state change): \* \*\*\`MetricOmmSwapQuoter\`\*\* (recommended) — decodes the revert for you and returns \`(amountIn, amountOut)\` directly. \* \*\*\`MetricOmmPool.simulateSwapAndRevert\`\*\* (low-level) — reverts with the result encoded in the revert data; you decode it yourself. ### Recommended: \`MetricOmmSwapQuoter\` A read-only lens (\`eth\_call\` only) with two flavors, each in exact-input / exact-output and single / multihop forms: \* \*\*Live\*\* — uses the pool's on-chain oracle prices, so \*\*you don't supply bid/ask\*\*. \* \*\*Hypothetical\*\* — you pass \`bidPriceX64\` / \`askPriceX64\` (e.g. to quote against a price you expect). Single-hop: \`\`\`solidity // Live — no prices supplied function quoteLiveExactInSingle(address pool, bool zeroForOne, uint128 amountIn, uint128 priceLimitX64) external returns (uint256 amountIn, uint256 amountOut); function quoteLiveExactOutSingle(address pool, bool zeroForOne, uint128 amountOutDesired, uint128 priceLimitX64) external returns (uint256 amountIn, uint256 amountOut); // Hypothetical — caller-supplied bid/ask function quoteHypotheticalExactInputSingle( address pool, bool zeroForOne, uint128 amountIn, uint128 priceLimitX64, uint128 bidPriceX64, uint128 askPriceX64 ) external returns (uint256 amountIn, uint256 amountOut); function quoteHypotheticalExactOutputSingle( address pool, bool zeroForOne, uint128 amountOutDesired, uint128 priceLimitX64, uint128 bidPriceX64, uint128 askPriceX64 ) external returns (uint256 amountIn, uint256 amountOut); \`\`\` Each has an overload taking \`(address recipient, …, bytes extensionData)\` for pools whose extensions gate on those fields. \*\*Multihop:\*\* \`quoteLiveExactIn\` / \`quoteLiveExactOut\` and \`quoteHypotheticalExactInput\` / \`quoteHypotheticalExactOutput\` take a params struct (\`pools\[\]\`, \`extensionDatas\[\]\`, \`zeroForOneBitMap\`, amount). \*\*How it works:\*\* the live path drives \`pool.swap\` and reverts inside the callback with \`QuoteSwapResult\`; the hypothetical path drives \`simulateSwapAndRevert\` and reads \`SimulateSwap\`. The quoter catches both and returns the decoded amounts. Any other inner revert is bubbled up as \`WrappedError(address target, bytes4 selector, bytes reason)\`. ### Low-level: call the pool directly \`\`\`solidity function simulateSwapAndRevert( address recipient, bool zeroForOne, int128 amountSpecified, uint128 priceLimitX64, uint128 bidPriceX64, uint128 askPriceX64, bytes calldata extensionData ) external returns (int128 amount0Delta, int128 amount1Delta); \`\`\` This always reverts with \`SimulateSwap(int128 amount0Delta, int128 amount1Delta)\`; you must catch and decode the revert data yourself. Use the quoter unless you need the raw signed deltas. ### Reverts & guards | Condition | Result | | --------------------------- | ---------------------------- | | \`amountSpecified == 0\` | reverts \`InvalidAmount\` | | \`bidPriceX64 == 0\` | reverts \`BidIsZero\` | | \`bidPriceX64 > askPriceX64\` | reverts \`BidGreaterThanAsk\` | | inner pool revert (other) | bubbled up as \`WrappedError\` | --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference-deprecated.md). # Smart Contracts Reference(Deprecated) Overview of pools is available under: \[https://app.gitbook.com/o/4dbAWnxoNFlB3Hmv5Lyu/s/wegByLMQJTopYqrvontp/\\~/edit/\\~/changes/31/developers/api#metadata-endpoint\](/metric/RSm94m71kqtGICv4iKRj/developers/api-deprecated.md#metadata-endpoint) ## Ethereum Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xcB41C10c6414aCbea022c7662df4005dd8FBEF91 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*Base\*\* Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xA6A16C00B7E9DBE1D54acEd7d6FE264fc4732eaF Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*BSC\*\* Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xa9a63266bB70eb3419C34C245F4318983f325Bbd Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*Arbitrum\*\* Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x82A562fD9F02d4346B95D3a2a501411979C8F920 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*Avax\*\* Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x5C1e08DF74a3457648A4C4dc5DC0DE497284c53C Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*Polygon\*\* Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x976c26402E1EC10454c5Fe6D2C9857DD57aE78f3 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*MegaETH\*\* Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xA6A16C00B7E9DBE1D54acEd7d6FE264fc4732eaF Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*HyperEVM\*\* Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0x080b37C6F65cBC231f66016460782158090Fe0F7 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## Monad Factory Address: 0xe22F9fc0f04486dE25ed6CF1800a4a47aFD82e0C State View Address: 0xe6b102a2aea65b9b59e4F8B86B38E221886675A8 Router Address: 0xaF9ADa6b6eC7993CE146f6c0bF98f7211CDfD3e5 Pool Deployer Address: 0x0f732971a3503afee276782173170D1F1154d4c1 ## \*\*ABI\*\* Pool: {% file src="/files/U136yq63upFtc60hRSe1" %} Router: {% file src="/files/DYx9G0xpgOWAvx5Z09YS" %} Stateview: {% file src="/files/HrpcKtkT8gjhVs9aZGEQ" %} Factory: {% file src="/files/R5WYd7bJ9lbrz9cjlRDp" %} --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-via-router.md). # Swapping via Router ## Swapping via the Router \`MetricOmmSimpleRouter\` (periphery) executes ERC-20 swaps through one or more pools and implements the pool's settlement callback internally — you implement nothing. Unlike the low-level pool \`swap\`, every router entrypoint has \*\*built-in amount-based slippage protection\*\* (\`amountOutMinimum\` / \`amountInMaximum\`) plus a \`deadline\`. > Scope: \*\*ERC-20 routes only.\*\* Per the interface, there is no native ETH, WETH wrap/unwrap, or on-chain quoting here (functions are \`payable\` only for multicall composition). For quotes, use \`MetricOmmSwapQuoter\`. ### Prerequisites \* \`approve\` the router to spend your input token (\`tokenIn\`) — its callback pulls the token from you during settlement. \* Optional: the router supports \*\*\`selfPermit\`\*\* and \*\*\`multicall\`\*\*, so you can permit + swap in one transaction (no separate approval tx). ### Entrypoints \`\`\`solidity function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); \`\`\` Single-hop params (exact input shown; exact output mirrors it with \`amountOut\` + \`amountInMaximum\`): \`\`\`solidity struct ExactInputSingleParams { address pool; address tokenIn; // the router pulls THIS from you in the callback — set it correctly address tokenOut; // informational only; not checked on-chain bool zeroForOne; // true = token0 → token1 uint128 amountIn; uint128 amountOutMinimum; // slippage floor — reverts InsufficientOutput if not met address recipient; // receives the output token uint256 deadline; // reverts TransactionExpired once passed uint128 priceLimitX64; // Q64.64 marginal bound (see sentinels below) bytes extensionData; // forwarded to the pool's swap extension; "0x" if unused } \`\`\` \*\*Returns:\*\* exact-input entrypoints return \`amountOut\`; exact-output entrypoints return \`amountIn\` (both \`uint256\`). ### priceLimitX64 (single-hop) A Q64.64 marginal bound. The sentinel is \*\*direction-checked\*\* — passing the wrong one reverts \`InvalidPriceLimitForDirection\`: | \`zeroForOne\` | Direction | No-limit sentinel | | ------------ | ------------------------ | --------------------------------- | | \`true\` | price down (lower bound) | \`0\` | | \`false\` | price up (upper bound) | \`type(uint128).max\` (\`2^128 − 1\`) | Multihop entrypoints \*\*omit per-hop price limits\*\* (each hop runs open); slippage is controlled solely by \`amountOutMinimum\` / \`amountInMaximum\`. ### Multihop \`exactInput\` / \`exactOutput\` take a route: \* \`tokens\[\]\` — the path \`\[t0, t1, …, tn\]\`. \* \`pools\[\]\` — pool between each adjacent pair (\`length = tokens.length − 1\`). \* \`extensionDatas\[\]\` — per-pool payload (\`length = pools.length\`). \* \`zeroForOneBitMap\` — bit \`i\` is the direction for \`pools\[i\]\` (up to 256 hops). Exact-output routes execute \*\*last hop → first\*\*; \`amountOut\` is \`tokens\[last\]\`. {% hint style="warning" %} \*\*The router does not validate your route.\*\* It does not check pool factory provenance, that each \`pool\` connects its adjacent path tokens, or that \`tokenIn\`/\`tokenOut\` match pool immutables. Supplying a wrong \`pool\` or \`tokenIn\` is at your own risk — resolve these from the metadata endpoint. {% endhint %} ### Notes \* \*\*Settlement is internal:\*\* the router's callback pulls \`tokenIn\` from you and the pool sends output to \`recipient\`. It validates the callback caller (\`InvalidCallbackCaller\`). \* \*\*Errors:\*\* \`TransactionExpired\`, \`InsufficientOutput\` (exact-in min), \`InputTooHigh\` (exact-out max), \`InvalidPriceLimitForDirection\`, \`InvalidPath\`, \`InvalidSwapDeltas\`, \`AmountTooLarge\`, and the per-hop \`InvalidInputAmountAtHop\` / \`InvalidOutputAmountAtHop\`. Pool-level reverts (\`BidIsZero\`, \`BidGreaterThanAsk\`, \`PoolPaused\`) bubble up. {% hint style="warning" %} The pool prices from its on-chain \`priceProvider\` at execution time. Sequence an oracle update ahead of the swap (same bundle/block) so it doesn't price stale or revert. {% endhint %} --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/smart-contracts-reference/swapping-directly-via-pool.md). # Swapping directly via pool ## Swap via the Pool Call \`swap\` directly on \`MetricOmmPool\` from a contract that implements \`IMetricOmmSwapCallback\`. Use this for full control over funding (vault, flash logic, aggregator settlement); otherwise prefer the Router, which handles settlement for you. This is also the \*\*only entrypoint that does both exact-input and exact-output in one function\*\* (via the sign of \`amountSpecified\`) — \`MetricOmmSimpleRouter\` splits those into separate \`exactInput\*\` / \`exactOutput\*\` calls. ### Swap Parameters \`\`\`solidity function swap( address recipient, // receives the output tokens bool zeroForOne, // true = token0→token1, false = token1→token0 int128 amountSpecified, // positive = exact input, negative = exact output (non-zero) uint128 priceLimitX64, // marginal price bound, Q64.64 bytes calldata callbackData, // forwarded to YOUR swap callback bytes calldata extensionData // forwarded to the pool's swap extensions ) external returns (int128 amount0Delta, int128 amount1Delta); \`\`\` \* \`amountSpecified == 0\` reverts \`InvalidAmount\`. \* \`priceLimitX64\` is your slippage protection (Q64.64 marginal bound). \* \`callbackData\` is opaque — the pool never reads it; it's handed back to your \`metricOmmSwapCallback\` so you can route context (payer, leg, funding source). \`"0x"\` if unused. \* \`extensionData\` is separate: the pool forwards it to its \`beforeSwap\` / \`afterSwap\` extension hooks, \*\*not\*\* to your callback. \`"0x"\` if the pool has no extensions or they need no input. \* Reverts \`PoolPaused\` if the pool is paused. ### Swap Callback The pool settles Uniswap V3–style. Per swap, in order: 1. The pool computes deltas and \*\*sends the output token to \`recipient\`\*\* (the negative-delta side). 2. It calls \`metricOmmSwapCallback\` on \`msg.sender\`. 3. Your callback \*\*transfers the owed input token to the pool\*\* (the positive-delta side). 4. The pool balance-checks repayment and reverts \`IncorrectDelta\` if you underpaid. Deltas (pool perspective): \*\*positive\*\* → you must send that token to the pool; \*\*negative\*\* → the pool already sent it to \`recipient\`; either may be \`0\`. \`\`\`solidity /// @notice Any contract that calls IMetricOmmPool#swap must implement this. interface IMetricOmmSwapCallback { /// @param amount0Delta positive => pool must receive token0 from the payer; negative => pool sent it out /// @param amount1Delta positive => pool must receive token1 from the payer; negative => pool sent it out /// @param callbackData opaque bytes forwarded from the swap call function metricOmmSwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata callbackData ) external; } \`\`\` {% hint style="danger" %} Your callback \*\*must verify \`msg.sender\` is a legitimate Metric pool\*\* before paying — otherwise any contract can call it and drain funds. {% endhint %} {% hint style="info" %} This pattern lets you source the input however you like (wallet, vault, flash) with no upfront approvals or pre-transfers, and composes with routing/settlement logic. The pool does not pull input tokens — your callback pushes them. {% endhint %} {% hint style="warning" %} The pool prices from its on-chain \`priceProvider\` at execution time. Sequence an oracle update ahead of the swap (same bundle/block) so it doesn't price stale or revert. {% endhint %} --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/find-best-route.md). # Find Best Route Find and price the best execution across direct and one-intermediate-hop paths for an \*\*exact-input or exact-output\*\* swap. Returns one or more routes; the input is split across multiple routes only when the configured thresholds show it reduces price impact. {% code overflow="wrap" %} \`\`\` POST /public/v1/evm/{chain\_id}/routeAuthorization: Bearer \`\`\` {% endcode %} {% hint style="warning" %} \*\*Auth required.\*\* This is a Trading API endpoint. \`\`\` Authorization: Bearer \`\`\` {% endhint %} \*\*Path parameters\*\* | Name | Type | Description | | ---------- | ------- | --------------------- | | \`chain\_id\` | integer | Numeric EVM chain id. | \*\*Request body — \`RouteRequest\`\*\* | Field | Type | Required | Description | | ----------- | ------- | --------------- | ---------------------------------------------------------------------------------------- | | \`tokenIn\` | string | yes | Input token address. Must differ from \`tokenOut\`, non-zero. | | \`tokenOut\` | string | yes | Output token address. | | \`tradeType\` | string | no | \`exact\_in\` (default) or \`exact\_out\`. | | \`amountIn\` | string | for \`exact\_in\` | Exact input, raw units (base-10, positive). | | \`amountOut\` | string | for \`exact\_out\` | Exact output target, raw units. | | \`maxRoutes\` | integer | no | Cap on routes in the plan. \`1\` = single best route (no split); omitted = configured max. | ### Request \`\`\`bash # Route (exact-in) — single & split, one endpoint curl -X POST "https://api.metric.xyz/public/v1/evm/8453/route" \\ -H "Authorization: Bearer " \\ -H "Content-Type: application/json" \\ -d '{ "tokenIn": "0x4200000000000000000000000000000000000006", "tokenOut": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "tradeType": "exact\_in", "amountIn": "50000000000000000", "maxRoutes": 4 }' \`\`\` ### Response \`200 OK\` \`\`\`json "tokenIn": "0x4200000000000000000000000000000000000006", "tokenOut": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", "tradeType": "exact\_in", "amountIn": "50000000000000000", "amountOut": "79489960", "effectivePriceX64": "29326618970", "priceImpactBestRoute": "0.000178", "candidatesConsidered": 4, "routes": \[\ {\ "tradeType": "exact\_in",\ "routeType": "direct",\ "amountIn": "50000000000000000",\ "amountOut": "79489960",\ "effectivePriceX64": "29326618970",\ "priceImpactE6": "178",\ "legs": \[\ {\ "tradeType": "exact\_in",\ "poolAddress": "0xa3211DD5f8BA5f8bAd40f8a21F39475fDeAf2c2A",\ "pair": "WETH/USDC",\ "zeroForOne": true,\ "tokenIn": "0x4200000000000000000000000000000000000006",\ "tokenOut": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",\ "amountIn": "50000000000000000",\ "amountOut": "79489960",\ "effectivePriceX64": "29326618970",\ "priceImpactE6": "178",\ "priceLimitX64": "0"\ }\ \]\ }\ \] } \`\`\` | Field | Type | Description | | ---------------------- | ------- | ------------------------------------------------------------------------------------------ | | \`tokenIn\` / \`tokenOut\` | string | Echoed endpoints (lowercased). | | \`tradeType\` | string | Echoed; tells you which side was fixed. | | \`amountIn\` | string | For \`exact\_in\`, the request; for \`exact\_out\`, the computed required input. | | \`amountOut\` | string | For \`exact\_in\`, total computed output; for \`exact\_out\`, ≈ the requested target. | | \`effectivePriceX64\` | string | Blended execution price for the whole plan, \[Q64.64\](broken://pages/Gvu6za4NSW93D4pWPhdu). | | \`priceImpactBestRoute\` | string | Best single route's price impact as a \*\*decimal fraction\*\* (\`"0.0135"\` = 1.35%). | | \`candidatesConsidered\` | integer | Number of candidate paths scored. | | \`routes\` | array | One entry per allocated route (≥1; multiple ⇒ split). | \*\*Each \`routes\[\]\` entry\*\* | Field | Type | Description | | ------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | \`tradeType\` | string | Echoed. | | \`routeType\` | string | \`direct\` or \`one\_hop\`. | | \`amountIn\` / \`amountOut\` | string | Amounts allocated to this route (raw units). | | \`effectivePriceX64\` | string | This route's execution price, \[Q64.64\](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/api/pages/Gvu6za4NSW93D4pWPhdu#q64.64). | | \`priceImpactE6\` | string | This route's cumulative price impact, E6 (\`10000\` = 1%). | | \`legs\` | array | Per-leg execution params. | \*\*Each leg\*\* | Field | Type | Description | | ------------------------ | ------- | ------------------------------------------------------------------------------------ | | \`tradeType\` | string | Echoed. | | \`poolAddress\` | string | Pool to swap against. | | \`pair\` | string | Pool pair label. | | \`zeroForOne\` | boolean | Swap direction for this leg. | | \`tokenIn\` / \`tokenOut\` | string | Leg tokens. For one-hop, leg 2 \`amountIn\` = leg 1 \`amountOut\`. | | \`amountIn\` / \`amountOut\` | string | Leg amounts (raw units). | | \`effectivePriceX64\` | string | Leg execution price | | \`priceImpactE6\` | string | Leg cumulative price impact, E6. | | \`priceLimitX64\` | string | No-limit sentinel for the on-chain swap: \`0\` when \`zeroForOne\`, \`2^128−1\` otherwise. | \*\*How routing & splitting are decided\*\* (internal — not all surfaced in the response) 1. Enumerate direct + one-hop candidates; score each by walking \`bid\_ask\` depth bins for the requested amount. 2. Pick the best single route (baseline). If its price impact is below \`split\_threshold\_bps\`, return just that. 3. Otherwise greedily allocate across routes by marginal price, subject to \`min\_improvement\_bps\`, \`min\_leg\_fraction\_bps\`, and \`maxRoutes\`. 4. A split is returned only if it beats the baseline's total output. The chosen \`reason\` (\`below\_split\_threshold\` / \`single\_route\_after\_allocation\` / \`not\_better\_than\_baseline\` / \`split\_applied\`) and \`splitApplied\` are recorded in \*\*logs/traces only\*\*, not the response. \*\*Errors\*\* | Status | Meaning | | ------ | ------------------------------------------------------------------------------------------------------------------------------ | | \`400\` | Invalid body, \`tokenIn == tokenOut\`, zero address, non-positive amount, or missing \`amountIn\`/\`amountOut\` for the \`tradeType\`. | | \`422\` | \`no\_route\` (no eligible direct/one-hop path) or \`insufficient\_liquidity\` (no candidate had enough depth). | | \`503\` | Routing exceeded the 5s deadline. | --- # SDK | Metric For the complete documentation index, see [llms.txt](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/llms.txt) . This page is also available as [Markdown](https://oracle-based-omm.gitbook.io/metric/RSm94m71kqtGICv4iKRj/developers/sdk.md) . Current version of SDK supports liquidity operations and swaps. More functions will be rolled out with time [https://www.npmjs.com/package/@nradko/metricamm-sdk](https://www.npmjs.com/package/@nradko/metricamm-sdk) Last updated 5 months ago ---