| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
The data must be fetched from on-chain calls or from subgraphs. Centralised api calls are only accepted if there is no other way of obtaining that data (eg off-chain gauge weights).
Our goal is to display minimum attainable yield values for all listed projects:
An adaptor is just a javascript (or typescript) file that exports an async function that returns an array of objects that represent pools of a protocol. The pools follow the following schema (all values are just examples):
interface Pool {
pool: string;
chain: string;
project: string;
symbol: string;
tvlUsd: number; // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd
apyBase?: number;
apyReward?: number;
pricePerShare?: number; // underlying assets per share (e.g. ERC-4626 convertToAssets / 1 share); NOT a USD price. Omit when not applicable.
rewardTokens?: Array<string>;
underlyingTokens?: Array<string>;
poolMeta?: string;
url?: string;
token?: string; // the pool's token contract address (e.g. the LP token or receipt token address)
searchTokenOverride?: string; // override token used for search/display matching (see below)
isIntrinsicSource?: boolean; // marks LST/LRT/yield-bearing stablecoin primitives used for intrinsic APY linkage
// optional lending protocol specific fields:
apyBaseBorrow?: number;
apyRewardBorrow?: number;
totalSupplyUsd?: number;
supplyCapUsd?: number; // protocol supply cap in USD at sample-time price; omit when uncapped (e.g. aave supplyCap of 0), never emit 0
totalBorrowUsd?: number;
availableBorrowUsd?: number; // current available borrow liquidity in USD, accounting for caps and constraints; do not zero solely because borrowable is false
borrowToken?: string; // underlying token address/string the borrower receives; not a debt receipt token
ltv?: number; // btw [0, 1]
borrowable?: boolean; // whether a new borrow can be opened right now for this asset
}token — The pool's token contract address as a single hex string (e.g. the LP token, vault receipt token, or staked asset address). Stored on config.token and exposed by the yields API as poolTokenAddress. Drives holder analytics (the holder pipeline reads config.token to look up on-chain holders) and downstream features that need a single canonical token per pool. Currently optional but will eventually be required for all adapters.
How it gets populated (see src/handlers/triggerAdaptor.js):
When is it null? Whenever the adapter doesn't set it and the pool id has no 0x address — typically API-driven adapters that use UUIDs as pool ids, or non-EVM chains (Solana, Cosmos, etc.) where addresses aren't 0x…. For those, set token explicitly.
Edge cases — set token explicitly when:
Borrow / CDP pools — pass token: null. When the position is debt against collateral (Morpho Blue borrow markets, Liquity v1/v2 Troves, Liquity v2 stability pools, MakerDAO/Sky vaults, etc.), there is no transferable ERC-20 representing the user's position 1:1, so there are no holders to track and no canonical "pool token". The pool id in these adapters typically points at a market/vault/join contract (e.g. morpho-blue-${uniqueKey}-${chain}, the trove manager, an ilk join), and letting the fallback regex grab that address would surface a misleading value as poolTokenAddress and pollute holder analytics. Setting token: null explicitly suppresses the fallback and signals "no token" to downstream consumers.
ERC-4626-style "Earn" / vault pools on the same protocols (e.g. Morpho Blue MetaMorpho vaults, Liquity v2 stability-pool wrappers via 4626) do have a receipt token — for those, set token to the share-token address and don't pass null.
searchTokenOverride — Used for LSTs (Liquid Staking Tokens), LRTs (Liquid Restaking Tokens), and similar derivative tokens where the pool's token address differs from the underlying token. When set, this address is used instead of the underlying token for search and display matching. Only set this if the default matching produces incorrect results.
isIntrinsicSource — Set to true only for LST, LRT, or yield-bearing stablecoin primitives whose APY should be used as intrinsic APY for downstream pools. Example: Lido stETH APY can be linked as intrinsic APY for an Aave stETH/wstETH market. If an adapter lists multiple bridged versions with the same intrinsic APY, set this only on the canonical deployment.
{
pool: "0x3ed3b47dd13ec9a98b44e6204a523e766b225811-ethereum", // unique identifier for the pool in the form of: `${ReceivedTokenAddress}-${chain}`.toLowerCase()
chain: "Ethereum", // chain where the pool is (needs to match the `name` field in here https://api.llama.fi/chains)
project: 'aave', // protocol (using the slug again)
symbol: "USDT", // symbol of the tokens in pool, can be a single symbol if pool is single-sided or multiple symbols (eg: USDT-ETH) if it's an LP
tvlUsd: 1000.1, // number representing current USD TVL in pool
apyBase: 0.5, // APY from pool fees/supplying in %
apyReward: 0.7, // APY from pool LM rewards in %
rewardTokens: ['0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9'], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards)
underlyingTokens: ['0xdAC17F958D2ee523a2206206994597C13D831ec7'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum
poolMeta: "V3 market", // A string value which can stand for any specific details of a pool position, market, fee tier, lock duration, specific strategy etc
isIntrinsicSource: true, // only for LST/LRT/yield-bearing stablecoin primitives used for intrinsic APY linkage
};A note on how to set apy related fields: - if a pool's apy only consists of a base component, provide `apyBase` and omit `apyReward` (or set to null) [and vice versa] - if a pool's apy consists of both, provide both fields - if you are unsure/your data source doesn't contain a detailed breakdown, then provide an `apy` field indicating the total apy and omit the `apyBase` and `apyReward` fields (or set to null)
DefiLlama only displays pools with >10k TVL, so pools with less TVL than that will appear on the adapter but not on defillama
Make sure you're running the command inside the src/adaptors folder, not in the project root folder.
That page has stricter filters than other pages, only pools with >1M TVL and on audited protocols are included there.
module.exports = {
protocolId: '294', // id from https://api.llama.fi/protocols for this adapter's exact slug
timetravel: false,
apy: apy, // Main function, returns pools
url: 'https://example.com/pools', // Link to page with pools (Only required if you do not provide url's for each pool)
};protocolId is required and must match the protocol id from https://api.llama.fi/protocols, using the adapter folder name as the protocol slug. Store it as a string. The adapter test fails if the folder name has no exact protocol slug match, if protocolId is missing, or if it does not equal the matched protocol's id.
An example of the most basic adaptor is the following for Anchor on terra:
const utils = require('../utils');
const poolsFunction = async () => {
const apyData = await utils.getData(
'https://api.anchorprotocol.com/api/v1/market/ust'
);
const dataTvl = await utils.getData(
'https://api.anchorprotocol.com/api/v1/deposit'
);
const ustPool = {
pool: 'terra1hzh9vpxhsk8253se0vv5jj6etdvxu3nv8z07zu',
chain: utils.formatChain('terra'),
project: 'anchor',
symbol: 'UST',
tvlUsd: Number(dataTvl.total_ust_deposits) / 1e6,
apy: apyData.deposit_apy * 100,
};
return [ustPool]; // Anchor only has a single pool with APY
};
module.exports = {
protocolId: '294',
timetravel: false,
apy: poolsFunction,
url: 'https://app.anchorprotocol.com/#/earn',
};You can find examples for a bunch of other protocols in the src/adaptors/ folder, and if you have any questions feel free to ask them on our discord.
| Back | FazBrowse Home | New Git URL |