Skip to main content

Metric DEX API on Ethereum — Trades, New Liquidity Pools and Token Prices

Metric is a DEX for "active" liquidity pools. Each liquidity pool has a price provider that sets a bid, an ask and a reference price from oracles, on-chain data or custom rules, and the liquidity pool holds liquidity in ranges around that quote. Trades move the price only relative to the reference, so Metric liquidity pools follow off-chain markets: stablecoin pairs, crypto majors, and tokenized gold and stocks. Bitquery decodes every Metric swap on Ethereum into the same cubes as every other DEX, with protocol family Metric and protocol name metric_v1. Every example below runs in the IDE on a free account.

How to get Metric data​

  • Live and recent trades with USD price and trader: the Crypto Trades API (Trading.Trades) with Market: { Network: "Ethereum", Protocol: "metric_v1" }. The Trading cube keeps about the last 30 days.
  • Full history and per-swap detail: the chain cubes EVM(network: eth) { DEXTrades } and DEXTradeByTokens with Trade.Dex.ProtocolName: "metric_v1".
  • New liquidity pools: the PoolCreated event of the Metric pool factory 0x2a53833cc95548cf52c7b159110e22d3a9018f32 in the Events cube.
  • Token price and OHLC on Metric: Trading.Pairs filtered to metric_v1.

Live Metric trades on Ethereum​

A stream of every Metric swap on Ethereum with the trader, amounts, USD values and the liquidity pool address. Pair.Pool.Address is the liquidity pool and Pair.Market.Address the Metric factory.

Run this query in the IDE

subscription {
Trading {
Trades(
where: {Pair: {Market: {Network: {is: "Ethereum"}, Protocol: {is: "metric_v1"}}}}
) {
Block {
Time
}
Side
Trader {
Address
}
Amounts {
Base
Quote
}
AmountsInUsd {
Base
}
Price
PriceInUsd
Pair {
Currency {
Symbol
Id
}
QuoteCurrency {
Symbol
Id
}
Pool {
Address
}
}
TransactionHeader {
Hash
}
}
}
}

Latest Metric swaps with full history​

The DEXTrades cube on network: eth goes back further than the Trading cube and returns both sides of each swap. Dex.SmartContract is the liquidity pool and Transaction.From the account that sent the swap.

Run this query in the IDE

{
EVM(network: eth) {
DEXTrades(
where: {Trade: {Dex: {ProtocolName: {is: "metric_v1"}}}}
limit: {count: 20}
orderBy: {descending: Block_Time}
) {
Block {
Time
Number
}
Trade {
Dex {
SmartContract
}
Buy {
Currency {
Symbol
SmartContract
}
Amount
AmountInUSD
}
Sell {
Currency {
Symbol
SmartContract
}
Amount
AmountInUSD
}
}
Transaction {
From
Hash
}
}
}
}

Top Metric liquidity pools by 24-hour volume​

Group DEXTradeByTokens by liquidity pool and token pair to rank Metric liquidity pools by trade count and USD volume. Trade.Currency and Side.Currency are the two tokens of the liquidity pool. DEXTradeByTokens holds every trade twice, once from each token's side; the Side.Type: buy filter keeps one of the two, so each liquidity pool shows two rows, one per trade direction, and their sum is the liquidity pool's volume without double counting. The since_relative filter keeps the window at the last 24 hours.

Run this query in the IDE

{
EVM(network: eth) {
DEXTradeByTokens(
where: {Trade: {Dex: {ProtocolName: {is: "metric_v1"}}, Side: {Type: {is: buy}}}, Block: {Time: {since_relative: {hours_ago: 24}}}}
orderBy: {descendingByField: "volumeUsd"}
limit: {count: 20}
) {
Trade {
Dex {
SmartContract
}
Currency {
Symbol
SmartContract
}
Side {
Currency {
Symbol
SmartContract
}
}
}
trades: count
traders: uniq(of: Transaction_From)
volumeUsd: sum(of: Trade_Side_AmountInUSD)
}
}
}

Trades in one Metric liquidity pool​

Put the liquidity pool address in Dex.SmartContract. The example is the USDC/USDT liquidity pool 0xaef2ad7abb651945e6d24276715f25bded0ad41e.

Run this query in the IDE

{
EVM(network: eth) {
DEXTrades(
where: {Trade: {Dex: {SmartContract: {is: "0xaef2ad7abb651945e6d24276715f25bded0ad41e"}}}}
limit: {count: 20}
orderBy: {descending: Block_Time}
) {
Block {
Time
}
Trade {
Buy {
Currency {
Symbol
}
Amount
AmountInUSD
Price
}
Sell {
Currency {
Symbol
}
Amount
AmountInUSD
}
}
Transaction {
From
Hash
}
}
}
}

New Metric liquidity pools​

Every Metric liquidity pool on Ethereum is created by the factory 0x2a53833cc95548cf52c7b159110e22d3a9018f32, which emits PoolCreated. The event arguments include poolAddress, token0, token1, poolIdx (the liquidity pool's number in the factory), admin and priceProvider (the contract that sets the liquidity pool's quotes), followed by the fee settings. The window is the last 30 days; widen days_ago for older liquidity pools.

Run this query in the IDE

{
EVM(network: eth) {
Events(
where: {Log: {SmartContract: {is: "0x2a53833cc95548cf52c7b159110e22d3a9018f32"}, Signature: {Name: {is: "PoolCreated"}}}, Block: {Time: {since_relative: {days_ago: 30}}}}
limit: {count: 20}
orderBy: {descending: Block_Time}
) {
Block {
Time
}
Transaction {
Hash
From
}
Arguments {
Name
Value {
... on EVM_ABI_Address_Value_Arg {
address
}
... on EVM_ABI_BigInt_Value_Arg {
bigInteger
}
}
}
}
}
}

To follow new liquidity pools as they are created, change the opening { to subscription { and drop the Block filter, limit and orderBy.

Token price on Metric​

Trading.Pairs gives the USD price of a token on each Metric liquidity pool as OHLC candles. The example is PAXG (tokenized gold, 0x45804880de22913dafe09f4980848ece6ecbaf78) on Ethereum, one-minute candles (Duration: 60 seconds), latest first. IsQuotedInUsd: true returns the price in USD instead of in the quote token.

Run this query in the IDE

{
Trading {
Pairs(
where: {Token: {Address: {is: "0x45804880de22913dafe09f4980848ece6ecbaf78"}, Network: {is: "Ethereum"}}, Market: {Protocol: {is: "metric_v1"}}, Interval: {Time: {Duration: {eq: 60}}}, Price: {IsQuotedInUsd: true}}
limit: {count: 10}
orderBy: {descending: Block_Time}
) {
Block {
Time
}
Token {
Symbol
Address
}
QuoteToken {
Symbol
}
Pool {
Address
}
Price {
Ohlc {
Open
High
Low
Close
}
}
Volume {
Usd
}
}
}
}

Hourly PAXG OHLC on Metric from the chain cube​

For candles older than the Trading cube keeps, build them from DEXTradeByTokens. Trade.Currency is the token you price; the PriceInUSD filter drops zero-price rows that would pull the low to zero.

Run this query in the IDE

{
EVM(network: eth) {
DEXTradeByTokens(
where: {Trade: {Dex: {ProtocolName: {is: "metric_v1"}}, Currency: {SmartContract: {is: "0x45804880de22913dafe09f4980848ece6ecbaf78"}}, PriceInUSD: {gt: 0}}, Block: {Time: {since_relative: {days_ago: 3}}}}
orderBy: {descendingByField: "Block_Time"}
limit: {count: 72}
) {
Block {
Time(interval: {count: 1, in: hours})
}
Trade {
open: PriceInUSD(minimum: Block_Number)
high: PriceInUSD(maximum: Trade_PriceInUSD)
low: PriceInUSD(minimum: Trade_PriceInUSD)
close: PriceInUSD(maximum: Block_Number)
}
volumeUsd: sum(of: Trade_Side_AmountInUSD)
trades: count
}
}
}

Metric on other chains​

Bitquery decodes Metric on other EVM chains too, for example BSC, Base, Arbitrum, Polygon (Matic) and Robinhood Chain. The Trading cube queries above work on any of them by changing Network, and the DEXTrades queries by changing network: (for example bsc, base, arbitrum, matic). The Metric factory has the same address, 0x2a53833cc95548cf52c7b159110e22d3a9018f32, on these chains, so the new liquidity pools query works there too. This query lists the chains where Metric trades in the last 24 hours, with the factory address on each:

Run this query in the IDE

{
Trading {
Trades(
where: {Pair: {Market: {Protocol: {is: "metric_v1"}}}, Block: {Time: {since_relative: {hours_ago: 24}}}}
orderBy: {descendingByField: "count"}
limit: {count: 20}
) {
Pair {
Market {
Network
Address
}
}
count
}
}
}

Fields​

FieldCubeWhat it holds
Trade.Dex.ProtocolNameDEXTrades, DEXTradeByTokensmetric_v1
Trade.Dex.ProtocolFamilyDEXTrades, DEXTradeByTokensMetric
Trade.Dex.SmartContractDEXTrades, DEXTradeByTokensThe Metric liquidity pool address
Trade.Dex.OwnerAddressDEXTrades, DEXTradeByTokensThe Metric factory 0x2a53833cc95548cf52c7b159110e22d3a9018f32
Trade.Buy / Trade.SellDEXTradesThe two tokens of the swap with amount, USD amount and price
Transaction.Fromall EVM cubesThe account that sent the swap
Pair.Market.AddressTradingThe Metric factory
Pair.Pool.AddressTradingThe Metric liquidity pool address
Trader.AddressTradingThe trader of the swap
Price.OhlcTrading.PairsOpen, high, low and close of the token in the interval
poolAddress, token0, token1, priceProviderEvents (PoolCreated)The new liquidity pool, its two tokens and its price provider

Pitfalls​

  • Price comes from the price provider, not the reserves. A Metric liquidity pool quotes around its reference price, so a large swap moves the price much less than it would on a constant-product liquidity pool. Read the price from trades (Trade.PriceInUSD, Price.Ohlc), not from the reserve ratio.
  • Don't sum both sides for volume. Each swap has a buy side and a sell side of the same USD value. On DEXTradeByTokens, keep one side with Side.Type, as in the top liquidity pools query.
  • Each PoolCreated row is one liquidity pool. Arguments with an empty Name are packed configuration values; take the liquidity pool from poolAddress.
  • The Trading cube keeps about 30 days. For older trades and candles use DEXTrades and DEXTradeByTokens.

Frequently Asked Questions

How do I get Metric DEX trades on Ethereum?

Use Trading.Trades with Market Network Ethereum and Protocol metric_v1 for live and recent trades with USD values, or EVM(network: eth) DEXTrades with Trade.Dex.ProtocolName metric_v1 for full history.

How do I find new Metric liquidity pools?

Query the Events cube for PoolCreated on the Metric factory 0x2a53833cc95548cf52c7b159110e22d3a9018f32. The poolAddress argument is the new liquidity pool, and token0 and token1 are its tokens.

Which chains does Bitquery cover Metric on?

Ethereum and other EVM chains such as BSC, Base, Arbitrum, Polygon and Robinhood Chain. Run the trades-by-chain query on this page for the current list.

Build with Bitquery

Ready to run this in production?

Get an API key and run these queries in minutes, or talk to us about plans and enterprise delivery.