How to write dimensions adapters
Last updated
Was this helpful?
Last updated
Was this helpful?
This guide will help you create adapters for DefiLlama's various dashboards, including , , , , , , and others.
An adapter is some code that:
Collects data on a protocol by calling some endpoints or making blockchain calls
Computes a response and returns it
It's a TypeScript file that exports an async function which takes a FetchOptions object containing:
startTimestamp: Unix timestamp for start of period
endTimestamp: Unix timestamp for end of period
startBlock: Block number corresponding to start timestamp
endBlock: Block number corresponding to end timestamp
createBalances: Helper function to track token balances
api: Helper for making contract calls
getLogs: Helper for fetching event logs
The function returns an object with metrics (like fees, volume, etc.) for that time range.
DefiLlama's dashboards track various metrics (dimensions) for DeFi protocols. Each dashboard focuses on specific dimensions:
Dexs dashboard: Tracks trading volume from DEXs (spot/swaps)
Fees dashboard: Tracks fees and revenue from all types of protocols
Aggregators dashboard: Tracks volume from DEX aggregators
Derivatives dashboard: Tracks volume from derivatives protocols
Bridge Aggregators dashboard: Tracks volume from bridge aggregators
Options dashboard: Tracks notional and premium volume from options DEXs
To add your protocol to any dashboard, follow these steps:
Create a new file at [dashboard]/yourProtocolName/index.ts
or [dashboard]/yourProtocolName.ts
(where [dashboard]
is the relevant folder like fees
, dexs
, aggregators
, aggregator-derivatives
, bridge-aggregators
, options
, etc.)
Implement your adapter following the guidelines in this document
Test your adapter using npm test [dashboard] yourProtocolName
Submit a PR! A llama will review it and merge it. Once merged, it can take up to 24h to be available in the dashboard
Let's start with a simple, complete example of a fees adapter:
The object exported by your adapter file defines its behavior. The main configuration object holds a version
key and an adapter
key.
The adapter
object contains chain-specific configurations, keyed by CHAIN.<ChainName>
. Each chain configuration is a BaseAdapter
object.
The BaseAdapter
includes several important properties:
fetch: The core async function that returns different dimensions of a protocol. The dimensions returned depend on which dashboard you're targeting (e.g., dailyVolume
for the dexs dashboard, dailyFees
for the fees dashboard). See "Core Dimensions" below.
start: The earliest timestamp (as YYYY-MM-DD or unix timestamp) we can pass to the fetch function. This tells our servers how far back we can get historical data.
runAtCurrTime: (Optional, defaults to false
) Boolean flag. Set to true
if the adapter can only return the latest data (e.g., last 24h) and cannot reliably use the startTimestamp
and endTimestamp
passed to fetch
.
meta: (Optional) Object containing metadata about the adapter, including:
methodology: Object describing how different dimensions are calculated. See "Metadata and Methodology" below.
hallmarks: Set of events that significantly affected protocol data (displayed on the chart).
Test your adapter locally before submitting a PR:
To test at specific day (unix format or yyyy-mm-dd):
This checks if your adapter correctly returns data for the requested time period.
The top-level version
key specifies the adapter version:
Version 2 (Recommended): version: 2
. These adapters accept arbitrary start and end timestamps as input to fetch
, allowing for flexible time ranges.
Version 1: version: 1
. Use this only if your fetch
function can run for fixed time periods only (00:00 to 23:59 of a given day), typically because the underlying data source only provides daily data.
Your fetch
function should return an object containing properties corresponding to the metrics (dimensions) relevant to the dashboard you are targeting. All dimensions should be returned as balance objects (Object<string>
) where keys are the token identifiers (e.g., ethereum:0x...
) and values are the raw amounts (no decimal adjustments).
Minimum Requirements: To be listed, your adapter must provide accurate
dailyFees
anddailyRevenue
dimensions. Other daily dimensions likedailyHoldersRevenue
are highly encouraged for better insights but are secondary. Cumulativetotal*
dimensions are deprecated and should not be used.
Here are the standard dimensions grouped by dashboard type:
Dexs, Dex Aggregators, and Derivatives Dimensions:
dailyVolume
: (Required for these dashboards) Trading volume for the period.
Options Dimensions:
dailyNotionalVolume
: Notional volume of options contracts traded/settled.
dailyPremiumVolume
: Premium volume collected/paid.
Fees Dimensions:
dailyFees
: (Required) All fees and value collected from all sources (users, LPs, yield generation, liquid staking rewards, etc.), excluding direct transaction/gas costs paid by users to the network. This represents the total value flow into the protocol's ecosystem due to its operation.
dailyUserFees
: (Optional, but helpful) The portion of dailyFees
directly paid by end-users (e.g., swap fees, borrow interest, liquidation penalties, marketplace commissions paid by buyers/sellers).
dailyRevenue
: (Required) The portion of dailyFees
kept by the protocol entity itself, distributed either to the treasury (dailyProtocolRevenue
) or governance token holders (dailyHoldersRevenue
).
dailyRevenue = dailyProtocolRevenue + dailyHoldersRevenue
dailyProtocolRevenue
: (Optional, clarifies revenue split) The portion of dailyRevenue
allocated to the protocol's treasury or core team.
dailyHoldersRevenue
: (Optional, but important for protocols distributing to holders) The portion of dailyRevenue
distributed to governance token holders (e.g., via staking rewards, buybacks, burns).
dailySupplySideRevenue
: (Optional, but helpful) The portion of dailyFees
distributed to liquidity providers, lenders, or other suppliers of capital/resources essential to the protocol's function.
dailyBribeRevenue
: (Optional, specific use case) Governance token paid as bribe/incentive for token holder action.
dailyTokenTax
: (Optional, specific use case) Fees generated from a tax applied to token transfers.
Fee/Revenue Attribution Examples by Protocol Type:
If you are unsure how to classify fees and revenues, refer to this table or ask on Discord:
UserFees
Swap fees paid by users
Interest paid by borrowers
Gas fees paid by users
Fees paid by users
Fees paid by users
Interest paid by borrowers
% of rewards paid to protocol
Paid management + performance fees
Fees paid by users
Fees
=UserFees
=UserFees
=UserFees
=UserFees
UserFees + burn/mint fees
=UserFees
Staking rewards
Yield
=UserFees
Revenue
% of swap fees going to protocol governance
% of interest going to protocol governance
Burned coins (fees-sequencerCosts for rollups)
Marketplace revenue + creator earnings
Protocol governance revenue
=ProtocolRevenue
=ProtocolRevenue
=ProtocolRevenue
=ProtocolRevenue
ProtocolRevenue
% of swap fees going to treasury
% of interest going to protocol
*
Marketplace revenue
Value going to treasury
Interest going to treasury
=UserFees
=UserFees
% of fees going to treasury
HoldersRevenue
Money going to gov token holders
*
*
*
Value going to gov token holders
*
*
*
% of fees going to token holders
SupplySideRevenue
LPs revenue
Interest paid to lenders
*
*
LP revenue
*
Revenue earned by stETH holders
Yield excluding protocol fees
LPs revenue
Notes:
Protocol governance includes treasury + gov token holders.
Revenue = HoldersRevenue + ProtocolRevenue
.Asterisk (*) indicates typically not applicable or zero for that category.
Building the fetch
function is the core task. Here's a breakdown:
Define Start Dates: For each chain, find your protocol's deployment date to set the start
property. This enables proper data backfilling.
Choose Data Source(s): Select the appropriate method(s) to retrieve the necessary data for calculating dimensions. Common approaches are detailed below.
Choose the appropriate data source based on your protocol's architecture. The fetch
function receives an options
object containing helper utilities like createBalances
, getLogs
, api
(for contract calls), queryDuneSql
, etc.
Ideal for tracking specific events that generate fees or volume:
Track tokens received by protocol treasury/fee addresses:
Fast queries for protocols with well-maintained subgraphs:
Examples:
For complex queries or when direct blockchain access is too expensive:
For protocols where data is accessible through view functions or requires multiple contract interactions:
Always include a methodology
object within the meta
property of your BaseAdapter
to explain how your metrics are calculated. This is crucial for transparency.
If your adapter cannot reliably calculate a specific dimension (e.g., totalVolume
is unavailable), omit that key from the returned object in your fetch
function. Do not return it with a value of 0
or undefined
if the data is truly missing or unknown.
Use the BigNumber
library (available via options.createBalances()
or direct import) for mathematical operations involving token amounts, especially when dealing with different decimals or potentially large/small numbers, to avoid JavaScript precision issues.
DeFiLlama provides numerous helper functions to simplify common tasks in adapter development. These are available either via direct import or through the options
object passed to your fetch
function.
These helpers provide high-level abstractions for common DeFi protocol archetypes.
uniV2Exports
/ getUniV2LogAdapter
: Generates adapter configurations for Uniswap V2-style DEXes across multiple chains.
Examples:
uniV3Exports
: Creates adapters for Uniswap V3-style DEXes, supporting variable fees and multiple pools.
Example:
compoundV2Export
: Creates an adapter for Compound V2-like protocols, taking config parameters and returning an object that tracks fees, revenue, and distribution among holders and suppliers.
Example:
Functions for tracking native and ERC20 token movements.
addTokensReceived
: Tracks ERC20 token transfers received by specified addresses. Supports filtering by sender/receiver and custom token transformations. Uses indexer first, then logs.
addGasTokensReceived
: Tracks native token transfers (like ETH) received by specified multisig addresses.
getETHReceived
: Tracks native token transfers on EVM chains via Allium DB queries.
getSolanaReceived
: Fetches token transfers to specified Solana addresses, allows blacklisting senders/signers.
Functions for querying EVM logs and indexers.
getLogs
(Available via options.getLogs
): Retrieves event logs based on filters (target, signature, topics).
queryIndexer
: Executes queries against DeFi Llama's indexers (transfers, events, etc.).
Functions for querying external data platforms.
queryDuneSql
(Available via options.queryDuneSql
): Executes SQL queries against Dune Analytics.
queryAllium
(Available via options.queryAllium
): Queries the Allium database.
Helpers tailored for specific chains or L2s.
fetchTransactionFees
(Available via options.fetchTransactionFees
): Retrieves total native token transaction fees burned/collected by the network.
Utility functions for common adapter patterns.
startOfDay
(Available via options.startOfDay
): Converts options.endTimestamp
to 00:00:00 UTC for data sources requiring exact day timestamps.
You can find the full source code for these helper functions in the DeFi Llama GitHub repository:
The majority of adapters for DefiLlama dashboards are contributed and maintained by their respective communities, with all changes being coordinated through the .
Fork the repository
Identify Supported Chains: Determine which blockchains your protocol runs on by referencing the file. You'll need a BaseAdapter
entry for each chain.
Example:
Example:
Example:
Example:
(V2-style)
(V3-style)
- Contains functions like addTokensReceived, getETHReceived, etc.
- Contains uniV2Exports, uniV3Exports
- Contains compoundV2Export
- Contains querySubgraph
- Contains getGraphDimensions2