Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Reading Protocol State

The VifReader contract provides gas-efficient methods for reading the Vif protocol state off-chain. Use it to query order book data, market information, and user positions.

Overview

VifReader is designed for off-chain reads via Etherscan, block explorers, or RPC calls. Most methods are gas-unbounded and should not be used in transactions.

Use VifReader to:
  • Query order book depth and liquidity
  • Read specific offers and their owners
  • Get market configurations
  • List all active markets
  • Check authorizations and fees

Setup

Before reading market data, you must register the market pair:

updateMarkets

updateMarkets(
  address token0,
  address token1,
  uint64 units0,
  uint64 units1,
  uint16 tickSpacing
)

Registers both directions of a market pair (e.g., WETH/USDC and USDC/WETH). The tokens are automatically ordered, so you can pass them in any order.

Behavior:
  • Adds the market pair if either direction is active
  • Removes the pair if both directions become inactive
  • Must be called before using book reading functions

Reading the Order Book

packedOfferList

packedOfferList(
  bytes32 marketId,
  uint40 fromId,
  uint256 maxOffers
) → (
  uint40 nextOfferId,
  uint40[] offerIds,
  uint256[] offers,
  address[] owners
)

Returns a paginated list of offers from the order book.

Parameters:
  • marketId: Market identifier
  • fromId: Offer ID to start from (0 for beginning)
  • maxOffers: Maximum number of offers to return
Returns:
  • nextOfferId: Next offer ID for pagination (0 if end reached)
  • offerIds: Array of offer IDs
  • offers: Array of packed offer data (use LibOffer.unpack to decode)
  • owners: Array of offer owner addresses
Use for:
  • Building order book displays
  • Paginating through all offers
  • Finding user's active offers

packedBook

packedBook(
  bytes32 marketId,
  uint24 fromPricePoint,
  uint24 maxPricePoints
) → (
  uint24 nextPricePoint,
  uint256[] offerListsPacked
)

Returns aggregated offer list data at each price level.

Parameters:
  • marketId: Market identifier
  • fromPricePoint: Index to start from (0 for best price)
  • maxPricePoints: Maximum price levels to return
Returns:
  • nextPricePoint: Next price index for pagination
  • offerListsPacked: Array of packed offer list data (contains head, tail, total volume, offer count, tick)
Use for:
  • Getting market depth overview
  • Displaying price levels with aggregated volume
  • Analyzing liquidity distribution

offerListEndPoints

offerListEndPoints(
  bytes32 marketId,
  uint40 fromId,
  uint256 maxOffers
) → (
  uint40 startId,
  uint256 length
)

Calculates pagination endpoints for offer lists.

Parameters:
  • marketId: Market identifier
  • fromId: Starting offer ID
  • maxOffers: Maximum offers to count
Returns:
  • startId: Actual starting offer ID
  • length: Number of offers available (capped at maxOffers)
Use for:
  • Determining pagination boundaries
  • Calculating total offer counts

Reading Individual Offers

offer

offer(
  bytes32 marketId,
  uint40 offerId
) → (
  OfferUnpacked memory offer,
  address owner
)

Returns unpacked offer details with owner address.

Returns an OfferUnpacked struct containing:
  • gives: Amount offered (in units)
  • received: Amount received from fills (in units)
  • next: Next offer ID in list
  • prev: Previous offer ID in list
  • expiry: Expiration timestamp (0 = never)
  • provision: Provision amount (in provision units)
  • maker: Offer owner address
  • isActive: Whether offer is in the book
  • tick: Price level
Use for:
  • Checking specific offer details
  • Monitoring offer status
  • Calculating claimable amounts

offerPacked

offerPacked(
  bytes32 marketId,
  uint40 offerId
) → (
  uint256 offer,
  address owner
)

Returns packed offer data as a single uint256 (more gas efficient).

Use for:
  • Gas-efficient offer queries
  • Batch reading offers
  • Off-chain processing (unpack the uint256 using LibOffer.unpack)

Reading Markets

market

market(
  bytes32 marketId
) → Market memory

Returns complete market configuration.

Returns a Market struct containing:
  • outboundToken: Token makers are selling
  • inboundToken: Token makers are buying
  • outboundUnits: Unit size for outbound amounts
  • inboundUnits: Unit size for inbound amounts
  • tickSpacing: Minimum tick distance
  • fee: Protocol fee in basis points
  • active: Whether market is active
  • minOutboundUnits: Minimum offer size
Use for:
  • Getting market parameters
  • Calculating unit conversions
  • Checking market status

openMarkets

openMarkets() → OpenMarketsResult[]

Returns all registered active market pairs.

Returns array of OpenMarketsResult containing:
  • market01: First direction market data
  • market10: Second direction market data
Use for:
  • Discovering all available markets
  • Building market selection UIs
  • Market analytics

openMarkets (paginated)

openMarkets(
  uint256 from,
  uint256 maxLength
) → OpenMarketsResult[]

Returns a page of active markets.

Parameters:
  • from: Index to start from
  • maxLength: Maximum markets to return
Use for:
  • On-chain market queries
  • Paginated market loading

openMarketsLength

openMarketsLength() → uint256

Returns the total number of registered market pairs.

Use for:
  • Calculating pagination
  • Counting active markets

Authorization & Fees

isAuthorized

isAuthorized(
  address authorizer,
  address authorized
) → bool

Checks if an address is authorized to act on behalf of another.

Parameters:
  • authorizer: The user granting permission
  • authorized: The address that may have permission (typically a router)
Returns:
  • true if authorized address can act for authorizer
  • false otherwise
Use for:
  • Verifying router permissions
  • Checking operator status
  • Authorization debugging

authorizerNonce

authorizerNonce(
  address authorizer
) → uint256

Returns the current nonce for EIP-712 signature-based authorization.

Use for:
  • Building authorization signatures
  • Nonce management
  • Replay attack prevention

fees

fees(
  address token
) → uint256

Returns accumulated protocol fees for a token.

Use for:
  • Checking fee reserves
  • Protocol analytics
  • Fee monitoring

minProvision

minProvision() → uint24

Returns the global minimum provision requirement (in provision units).

Use for:
  • Calculating provision amounts for expiring offers
  • Validating offer parameters
  • Cost estimation

Protocol Status

isPaused

isPaused() → bool

Returns whether the Vif contract is currently paused.

Use for:
  • Checking if trading is available
  • UI state management
  • Error handling

isBlacklisted

isBlacklisted(
  address user
) → bool

Returns whether a user is blacklisted from using the protocol.

Parameters:
  • user: Address to check
Use for:
  • Access control validation
  • User status verification
  • Security checks

Reading from the Vif Contract Directly

The VifReader contract wraps many Vif contract functions for convenience, but you can also read directly from the Vif contract:

Tree Reading

treeFor(bytes32 marketId) - Returns the tick tree structure for a market

Use to:

  • Find best prices
  • Traverse price levels
  • Check active ticks

Offer List Reading

offerList(bytes32 marketId, uint24 index) - Returns offer list at a specific price index

offerListPacked(bytes32 marketId, uint24 index) - Returns packed offer list data

Use to:

  • Get offers at specific price
  • Check liquidity at price level
  • Read head/tail pointers

Delta Reading

deltaOf(address token) (via LibDeltasExt) - Returns current flash accounting delta for a token

Use to:

  • Monitor transient balances
  • Debug settlement issues
  • Track debt/credit state

Best Practices

For Off-Chain Applications

  1. Use VifReader for all queries - It provides convenient aggregation and pagination
  2. Register markets first - Always call updateMarkets before reading book data
  3. Paginate large queries - Use fromId and maxOffers parameters to avoid timeouts
  4. Cache results - Order book data can be cached and invalidated on events
  5. Listen to events - Subscribe to Vif events to know when to refresh data

For On-Chain Applications

  1. Avoid unbounded methods - Never call openMarkets() or large packedOfferList queries in transactions
  2. Use specific queries - Read individual offers or markets rather than lists
  3. Consider gas costs - Even "view" functions cost gas in transactions
  4. Validate data - Always check isActive status on offers and markets

For UI Development

  1. Progressive loading - Load best prices first, then paginate deeper levels
  2. Event-driven updates - Refresh only affected price levels when offers change
  3. Error handling - Handle cases where markets aren't registered or offers don't exist
  4. Format units - Remember to multiply packed units by market unit sizes

Common Use Cases

Building an Order Book Display

  1. Call updateMarkets to register the market pair
  2. Use packedBook to get aggregated depth at each price level
  3. Use packedOfferList to get individual offers if needed
  4. Listen to NewOffer, MarketOrder, OfferCancelled events
  5. Refresh affected price levels on events

Showing User Portfolio

  1. Get all markets with openMarkets()
  2. For each market, call packedOfferList with reasonable pagination
  3. Filter offers by user address from the owners array
  4. Display offer details using returned packed data
  5. Monitor OfferClaimed and OfferUpdated events for the user

Market Analytics

  1. Use openMarkets() to discover all markets
  2. For each market, read market() to get configuration
  3. Use packedBook to calculate total liquidity
  4. Check fees() for each token to see protocol revenue
  5. Track MarketOrder events to measure trading volume

Price Monitoring

  1. Register target markets with updateMarkets
  2. Read best price using Vif's treeFor and finding first cursor
  3. Subscribe to NewOffer and MarketOrder events
  4. Re-read best price when events indicate price may have changed
  5. Use packedBook to get spread between best bid and ask

Related Concepts