LFJ Developer Docs
  • Liquidity Book
  • Introduction
  • LB V2.2 Key Changes
  • Guides
    • Swap Tokens
    • Add/Remove Liquidity
    • Tracking Volume
    • Tracking Pool Balances
    • Finding The Best Quote
    • Byte32 Decoding
    • Price From Bin Id
    • Bin Id From Price
    • Finding Liquidity Depth
    • User Balances
  • Concepts
    • Concentrated Liquidity
    • Bin Math
    • Bin Liquidity
    • Swaps
    • Fees
    • Oracle
  • Contracts
    • Interfaces
      • ILBLegacyFactory
      • ILBLegacyToken
      • ILBLegacyPair
      • ILBLegacyRouter
      • ILBFlashLoanCallback
      • IPendingOwnable
      • IJoeFactory
      • IJoePair
      • IJoeRouter01
      • IJoeRouter02
      • IWNATIVE
      • ILBFactory
      • ILBHooks
      • ILBPair
      • ILBRouter
      • ILBToken
    • Libraries
      • Math
        • BitMath
        • Encoded
        • LiquidityConfigurations
        • PackedUint128Math
        • SafeCast
        • SampleMath
        • TreeMath
        • Uint128x128Math
        • Uint256x256Math
      • BinHelper
      • Clone
      • Constants
      • FeeHelper
      • Hooks
      • ImmutableClone
      • JoeLibrary
      • OracleHelper
      • PairParameterHelper
      • PriceHelper
      • ReentrancyGuardUpgradeable
      • TokenHelper
    • LBBaseHooks
    • LBFactory
    • LBPair
    • LBQuoter
    • LBRouter
    • LBToken
  • Deployment Addresses
    • Avalanche C-Chain
    • Fuji Testnet
    • Arbitrum One
    • Binance Smart Chain
    • Binance Smart Chain Testnet
    • Ethereum Mainnet
    • Monad Testnet
  • SDK
    • Introduction
    • Making a Trade
    • Adding Liquidity
    • Removing Liquidity
  • Audits
  • AMM
    • Joe V1 Contracts
    • Joe V1 Audits
  • LFJ DEX API
    • Dex Analytics
    • Pools
    • Rewards
    • User
    • User Lifetime Stats
    • Vaults
    • Models
  • LFJ Aggregator API
    • Default
    • Models
Powered by GitBook
On this page
  • LBPairCreated
  • Swap
  1. Guides

Tracking Volume

Each market has its own LBPair contract with its own address. These are created by the LBFactory contract.

The general approach is to track all LBPairs created by the LBFactory and then track all Swap events emitted by the LBPair.

LBPairCreated

The LBPairCreated event is emitted by the LBFactory when new LBPair is created. Pools are uniquely identified within factories by pid.

    // ILBFactory.sol
    event LBPairCreated(
        IERC20 indexed tokenX, 
        IERC20 indexed tokenY, 
        uint256 indexed binStep, 
        ILBPair LBPair, 
        uint256 pid
    );

Below is code example to extract the LBPair, tokenX, tokenY addresses, pid, and binstep.

function handleLBPairCreated(event: LBPairCreated): void {

  const lbPair = new LBPair(
    event.params.pid,
    event.params.LBPair.toHexString(), 
    event.params.tokenX.toHexString(), 
    event.params.tokenY.toHexString(), 
    event.params.binStep
  )

  lbPair.save()
}

Swap

The Swap event is emitted by LBPairs when tokens are swapped.

  • Volume traded is tracked by amountsIn, amountsOut, which are tuple [amountX, amountY] encoded into byte32.

  • Fees paid by Traders to Liquidity Providers are tracked in totalFees, while fees paid by Liquidity Providers to Protocol are tracked in protocolFees. They are tuple [feeX, feeY] encoded into byte32.

  • See Byte32 Decoding for more details.

  • The active bin when the swap has finished is tracked by id, which is the Bin ID in integer.

    // ILBPair.sol
    event Swap(
        address indexed sender,
        address indexed to,
        uint24 id,
        bytes32 amountsIn,
        bytes32 amountsOut,
        uint24 volatilityAccumulator,
        bytes32 totalFees,
        bytes32 protocolFees
    );

Below are code example to get the price, and amounts swapped.

export function handleSwap(event: Swap): void {

  // We can get the tokenX and tokenY from the LBPair
  const lbPair = LBPair.load(event.address.toHexString())
  const tokenX = lbPair.tokenX
  const tokenY = lbPair.tokenY

  // We can infer the price of 1 tokenY = __ tokenX 
  // from the binstep and the active Bin Id
  const price = getPriceOfBin(
    BigInt.fromString(event.params.id.toString()),
    lbPair.binStep,
    tokenX,
    tokenY
  )

  // NOTE: reverse bytes to convert to big endianness
  event.params.amountsIn.reverse()
  event.params.amountsOut.reverse()

  // amountsIn is [amountX, amountY] packed into byte32
  const amountInX = decodeX(event.params.amountsIn)
  const amountInY = decodeY(event.params.amountsIn)
  const amountOutX = decodeX(event.params.amountsOut)
  const amountOutY = decodeY(event.params.amountsOut)

}

// Assemblyscript API
// https://thegraph.com/docs/en/developing/assemblyscript-api/
function decodeX(packedAmounts: Bytes): BigInt {
  // Read the right 128 bits of the 256 bits
  return BigInt.fromUnsignedBytes(packedAmounts).bitAnd(BigInt.fromI32(2).pow(128).minus(BigInt.fromI32(1)))
}

function decodeY(packedAmounts: Bytes): BigInt {
  // Read the left 128 bits of the 256 bits
  return BigInt.fromUnsignedBytes(packedAmounts).rightShift(128)
}
PreviousAdd/Remove LiquidityNextTracking Pool Balances

Last updated 9 days ago