This repository contains adapters for discovering token prices from various DeFi protocols. These adapters are specifically designed to fetch token prices for reward vault staking tokens and incentive tokens, which are essential for correctly calculating APRs (Annual Percentage Rates) displayed on Berachain Reward Vaults.
The adapters in this repository follow a common interface defined by the BaseAdapter
class. Each adapter is responsible for:
- Fetching staking tokens from reward vaults
- Getting prices for these staking tokens (used to calculate TVL and BGT APRs)
- Retrieving incentive/reward tokens
- Obtaining prices for incentive tokens (used to calculate reward rate and boost APRs)
This standardized approach allows for consistent and accurate APR calculations across different protocols by ensuring all token prices are properly discovered.
You do not need to add your vault here if your vault's underlying staking token:
- Comes from a Pool created in Hub
- Comes from Kodiak Island
- Comes from Kodiak V2
In these cases, Hub already has the necessary price information for these tokens.
You do not need to implement the getIncentiveTokenPrices
function if your token is already:
- Listed on Hub
- Listed on Kodiak
If your token is not listed on Hub or Kodiak but is tracked by Coingecko:
- Add your token information to the Berachain Metadata repo with the Coingecko ID
- Hub will automatically fetch your token prices using the Coingecko API
# Install dependencies
npm install
To test an adapter, use the following command:
npm run test:adapter -- <path-to-adapter-file>
For example:
npm run test:adapter -- src/vaults/examples/wbera-lbgt-vault-adapter.ts
This will:
- Load the adapter from the specified file
- Execute the adapter's methods to fetch token information and prices
- Display the results in the console
To create a new adapter for a specific protocol, follow these steps:
Create a new TypeScript file in the appropriate directory, e.g., src/vaults/your-protocol/your-adapter.ts
.
Your adapter must extend the BaseAdapter
class and implement all required methods:
import { BaseAdapter, Token, TokenPrice } from "../../types";
export class YourProtocolAdapter extends BaseAdapter {
constructor() {
super({
name: "Give a name",
description?: "Give a description",
enabled?: true,
});
}
/**
* Get staking tokens from reward vaults
* These tokens are used to calculate TVL for APR calculations
*/
async getRewardVaultStakingTokens(): Promise<Token[]> {
// Implement to return staking tokens
// Example:
return [
{
address: "0xv1...",
symbol: "VAULT1-LP-TOKEN",
name: "Vault1 LP Token",
decimals: 18,
chainId: 80094,
},
{
address: "0xv2...",
symbol: "VAULT2-LP-TOKEN",
name: "Vault2 LP Token",
decimals: 18,
chainId: 80094,
},
];
}
/**
* Get prices for staking tokens
* These prices are used to calculate TVL for APR calculations
*/
async getRewardVaultStakingTokenPrices(
stakingTokens: Token[]
): Promise<TokenPrice[]> {
// Implement to return token prices
// Example:
return [
{
address: "0xv1...",
price: 1.23,
timestamp: Date.now(),
},
{
address: "0xv2...",
price: 4.56,
timestamp: Date.now(),
},
];
}
/**
* Get incentive/reward tokens
* These tokens are used to calculate reward value for APR calculations
*/
async getIncentiveTokens(): Promise<Token[]> {
// Implement to return incentive tokens
return [];
}
/**
* Get prices for incentive tokens
* These prices are used to calculate reward value for APR calculations
*
* Note: You don't need to implement this if your token is already listed on Hub or Kodiak,
* or if it's tracked by Coingecko (in which case, add it to the Berachain Metadata repo)
*/
async getIncentiveTokenPrices(
incentiveTokens: Token[]
): Promise<TokenPrice[]> {
// Implement to return incentive token prices
return [];
}
}
Each token should have the following properties:
-
address
: The token's contract address -
symbol
: The token's symbol -
name
: The token's full name -
decimals
: The number of decimal places for the token -
chainId
: 80094
Each token price should have:
-
address
: The token's contract address (matching the token object) -
price
: The price in USD -
timestamp
: When the price was fetched (in milliseconds)
- For staking tokens that are LP tokens, the price should represent the TVL of the pool divided by the LP token supply
- For incentive tokens, only include tokens that don't already have prices on https://hub.berachain.com/vaults
- Accurate token prices are critical for correct APR calculations
- Make sure to handle errors gracefully and provide meaningful error messages
After implementing your adapter, test it using the command:
npm run test:adapter -- src/vaults/your-protocol/your-adapter.ts
Export your package class in src/index.ts
to ensure that it is importable by the users of this package.
// ...
// add your adapter to the imports
import { YourProtocolAdapter } from "./vaults/your-protocol/YourProtocolAdapter";
// add it to the list of exports
export { ..., YourProtocolAdapter };
Make sure your branch is ready for merging! Be sure to build everything locally with npm build
, lint with npm run lint
and format with npm run format
. We run CI checks before merging, so doing these steps will save everyone time.
src/
├── types/ # Type definitions and interfaces
├── utils/ # Utility functions and test scripts
└── vaults/ # Adapter implementations
├── examples/ # Example adapters
└── your-protocol/ # Your custom adapters
- Fork or clone the repository
- Create a feature branch:
git checkout -b feature/your-adapter
- Implement your adapter
- Test your adapter
- Commit your changes:
git commit -m 'Add adapter for Your Protocol'
- Push the commit:
git push origin feature/your-adapter
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.