Skip to main content

Example: Query Engine vs. Uniswap v2 Subgraph

To illustrate the differences between the subgraph and Query Engine approaches, take 24h volume on a Uniswap V2 fork:

event Swap(
address indexed sender,
uint amount0In, uint amount1In,
uint amount0Out, uint amount1Out,
address indexed to
);
Network IDTransaction HashEvent Emitter (Contract Address)Event NameEvent Data (JSONB in Postgres/Query Engine)senderamount0Inamount1Inamount0Outamount1Outto
10xbbafabd4e4833c016c04a4ef875d8e892ed7ff7fa820532d2f09a5e86ba4f2740xb4e16d0168e52d35cacd2c6185b44281ec28c9dcTrade{"sender":0x7a25.., "amount0In": 100000000000000000,"amount0Out": 163428202, "amount1Out": 0, ...}0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D010000000000000000016342820200x5083b16dA538c5022744526122243cF3BDDb3bF2
.................................

Query Engine with PostgreSQL

  • On new protocol event
    • Decode and import into database

Reporting API

  • On new protocol event
    • Rerun query for 24 hour volume

Subgraph

A rough sketch of how the Uniswap V2 subgraph will import data is as follows:

  • When I get a new block (or if I have not caught up to present block)
  • Fetch new block
  • Run any block handlers
  • Run and event log handlers
  • Update a row storing the 24hr volume for a Uniswap pair
export function handleSwap(event: Swap): void {

// only accounts for volume through white listed tokens

let trackedAmountUSD = getTrackedVolumeUSD(
amount0Total, token0 as Token, amount1Total, token1 as Token, pair as Pair)

 uniswapDayData.dailyVolumeUSD = uniswapDayData.dailyVolumeUSD.plus(trackedAmountUSD)
 uniswapDayData.dailyVolumeETH = uniswapDayData.dailyVolumeETH.plus(trackedAmountETH)
 uniswapDayData.dailyVolumeUntracked = uniswapDayData.dailyVolumeUntracked.plus(derivedAmountUSD)
 uniswapDayData.save()
 …
}