Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
feat(llama-airforce): Add uauraBAL and migrate to templates (#1317)
Browse files Browse the repository at this point in the history
  • Loading branch information
immasandwich authored Aug 31, 2022
1 parent 6c83f4b commit 1aff357
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 135 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,61 @@ import { Inject } from '@nestjs/common';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { ContractPosition } from '~position/position.interface';
import { isClaimable } from '~position/position.utils';
import { GetTokenBalancesParams } from '~position/template/contract-position.template.types';
import { MerkleTemplateContractPositionFetcher } from '~position/template/merkle.template.contract-position-fetcher';
import { Network } from '~types/network.interface';

import { LlamaAirforceContractFactory, LlamaAirforceMerkleDistributor } from '../contracts';
import { LLAMA_AIRFORCE_DEFINITION } from '../llama-airforce.definition';

import { EthereumLlamaAirforceMerkleCache } from './llama-airforce.merkle-cache';

const appId = LLAMA_AIRFORCE_DEFINITION.id;
const groupId = LLAMA_AIRFORCE_DEFINITION.groups.airdrop.id;
const network = Network.ETHEREUM_MAINNET;

@Register.ContractPositionFetcher({ appId, groupId, network, options: { excludeFromTvl: true } })
export class EthereumLlamaAirforceAirdropContractPositionFetcher implements PositionFetcher<ContractPosition> {
constructor(@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit) {}

async getPositions() {
return this.appToolkit.helpers.merkleContractPositionHelper.getContractPositions({
address: '0xa83043df401346a67eddeb074679b4570b956183', // Merkle Claim
appId,
groupId,
network,
dependencies: [{ appId, groupIds: [LLAMA_AIRFORCE_DEFINITION.groups.vault.id], network }],
rewardTokenAddresses: [
'0x83507cc8c8b67ed48badd1f59f684d5d02884c81', // uCRV
'0xf964b0e3ffdea659c44a5a52bc0b82a24b89ce0e', // uFXS
'0x8659fc767cad6005de79af65dafe4249c57927af', // uCVX
],
});
export class EthereumLlamaAirforceAirdropContractPositionFetcher extends MerkleTemplateContractPositionFetcher<LlamaAirforceMerkleDistributor> {
appId = appId;
groupId = groupId;
network = network;
groupLabel = 'Airdrop';
merkleAddress = '0xa83043df401346a67eddeb074679b4570b956183';

constructor(
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit,
@Inject(LlamaAirforceContractFactory) protected readonly contractFactory: LlamaAirforceContractFactory,
@Inject(EthereumLlamaAirforceMerkleCache) private readonly merkleCache: EthereumLlamaAirforceMerkleCache,
) {
super(appToolkit);
}

getContract(address: string): LlamaAirforceMerkleDistributor {
return this.contractFactory.llamaAirforceMerkleDistributor({ address, network: this.network });
}

async getRewardTokenAddresses() {
return [
'0x83507cc8c8b67ed48badd1f59f684d5d02884c81', // uCRV
'0xf964b0e3ffdea659c44a5a52bc0b82a24b89ce0e', // uFXS
'0x8659fc767cad6005de79af65dafe4249c57927af', // uCVX
];
}

async getTokenBalancesPerPosition({
address,
contractPosition,
contract,
}: GetTokenBalancesParams<LlamaAirforceMerkleDistributor>) {
const rewardToken = contractPosition.tokens.find(isClaimable)!;
const rewardsData = await this.merkleCache.getClaim(rewardToken.address, address);
if (!rewardsData) return [0];

const { index, amount } = rewardsData;
const isClaimed = await contract.isClaimed(index);
if (isClaimed) return [0];

return [amount];
}
}
138 changes: 76 additions & 62 deletions src/apps/llama-airforce/ethereum/llama-airforce.vault.token-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,82 +3,96 @@ import { Inject } from '@nestjs/common';
import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { CURVE_DEFINITION } from '~apps/curve';
import { PIREX_DEFINITION } from '~apps/pirex';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { AppTokenTemplatePositionFetcher } from '~position/template/app-token.template.position-fetcher';
import {
GetDataPropsParams,
GetDisplayPropsParams,
GetPricePerShareParams,
GetUnderlyingTokensParams,
} from '~position/template/app-token.template.types';
import { Network } from '~types';

import { LlamaAirforceContractFactory, LlamaAirforceUnionVault, LlamaAirforceUnionVaultPirex } from '../contracts';
import { LlamaAirforceContractFactory, LlamaAirforceUnionVault } from '../contracts';
import { LLAMA_AIRFORCE_DEFINITION } from '../llama-airforce.definition';

export type LlamaAirforceVaultTokenDataProps = {
reserve: number;
liquidity: number;
};

const appId = LLAMA_AIRFORCE_DEFINITION.id;
const groupId = LLAMA_AIRFORCE_DEFINITION.groups.vault.id;
const network = Network.ETHEREUM_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network })
export class EthereumLlamaAirforceVaultTokenFetcher implements PositionFetcher<AppTokenPosition> {
export class EthereumLlamaAirforceVaultTokenFetcher extends AppTokenTemplatePositionFetcher<
LlamaAirforceUnionVault,
LlamaAirforceVaultTokenDataProps
> {
appId = appId;
groupId = groupId;
network = network;
groupLabel = 'Vaults';

constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(LlamaAirforceContractFactory) private readonly llamaAirforceContractFactory: LlamaAirforceContractFactory,
) {}
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit,
@Inject(LlamaAirforceContractFactory) protected readonly contractFactory: LlamaAirforceContractFactory,
) {
super(appToolkit);
}

getContract(address: string): LlamaAirforceUnionVault {
return this.contractFactory.llamaAirforceUnionVault({ address, network: this.network });
}

getAddresses() {
return [
'0x83507cc8c8b67ed48badd1f59f684d5d02884c81', // uCRV
'0xf964b0e3ffdea659c44a5a52bc0b82a24b89ce0e', // uFXS
'0x8659fc767cad6005de79af65dafe4249c57927af', // uCVX
'0xd6fc1ecd9965ba9cac895654979564a291c74c29', // uauraBAL
];
}

async getUnderlyingTokenAddresses({
address,
contract,
multicall,
}: GetUnderlyingTokensParams<LlamaAirforceUnionVault>) {
if (address === '0x8659fc767cad6005de79af65dafe4249c57927af') {
const pirexContract = this.contractFactory.llamaAirforceUnionVaultPirex({ address, network: this.network });
return multicall.wrap(pirexContract).asset();
}

return contract.underlying();
}

async getPricePerShare({ contract, appToken, multicall }: GetPricePerShareParams<LlamaAirforceUnionVault>) {
if (appToken.address === '0x8659fc767cad6005de79af65dafe4249c57927af') {
const pirexContract = this.contractFactory.llamaAirforceUnionVaultPirex({
address: appToken.address,
network: this.network,
});

const reserveRaw = await multicall.wrap(pirexContract).totalAssets();
const reserve = Number(reserveRaw) / 10 ** appToken.tokens[0].decimals;
return reserve / appToken.supply;
}

async getUnionVaults() {
return await this.appToolkit.helpers.vaultTokenHelper.getTokens<LlamaAirforceUnionVault>({
appId,
groupId,
network,
dependencies: [
{ appId: CURVE_DEFINITION.id, groupIds: [CURVE_DEFINITION.groups.pool.id], network },
{ appId: PIREX_DEFINITION.id, groupIds: [PIREX_DEFINITION.groups.vault.id], network },
],
resolveContract: ({ address, network }) =>
this.llamaAirforceContractFactory.llamaAirforceUnionVault({ address, network }),
resolveVaultAddresses: async () => [
'0x83507cc8c8b67ed48badd1f59f684d5d02884c81', // uCRV
'0xf964b0e3ffdea659c44a5a52bc0b82a24b89ce0e', // uFXS
'0x8659fc767cad6005de79af65dafe4249c57927af', // uCVX
],
resolveUnderlyingTokenAddress: async ({ contract, multicall }) => multicall.wrap(contract).underlying(),
resolvePricePerShare: async ({ reserve, supply }) => reserve / supply,
resolveReserve: async ({ multicall, contract, underlyingToken }) =>
multicall
.wrap(contract)
.totalUnderlying()
.then(v => Number(v) / 10 ** underlyingToken.decimals),
resolvePrimaryLabel: ({ underlyingToken }) => `${getLabelFromToken(underlyingToken)} Pounder`,
});
const reserveRaw = await contract.totalUnderlying();
const reserve = Number(reserveRaw) / 10 ** appToken.tokens[0].decimals;
return reserve / appToken.supply;
}

async getUnionPirexVaults() {
return await this.appToolkit.helpers.vaultTokenHelper.getTokens<LlamaAirforceUnionVaultPirex>({
appId,
groupId,
network,
dependencies: [
{ appId: CURVE_DEFINITION.id, groupIds: [CURVE_DEFINITION.groups.pool.id], network },
{ appId: PIREX_DEFINITION.id, groupIds: [PIREX_DEFINITION.groups.vault.id], network },
],
resolveContract: ({ address, network }) =>
this.llamaAirforceContractFactory.llamaAirforceUnionVaultPirex({ address, network }),
resolveVaultAddresses: async () => [
'0x83507cc8c8b67ed48badd1f59f684d5d02884c81', // uCRV
'0xf964b0e3ffdea659c44a5a52bc0b82a24b89ce0e', // uFXS
'0x8659fc767cad6005de79af65dafe4249c57927af', // uCVX
],
resolveUnderlyingTokenAddress: async ({ contract, multicall }) => multicall.wrap(contract).asset(),
resolvePricePerShare: async ({ reserve, supply }) => reserve / supply,
resolveReserve: async ({ multicall, contract, underlyingToken }) =>
multicall
.wrap(contract)
.totalAssets()
.then(v => Number(v) / 10 ** underlyingToken.decimals),
resolvePrimaryLabel: ({ underlyingToken }) => `${getLabelFromToken(underlyingToken)} Pounder`,
});
async getDataProps({
appToken,
}: GetDataPropsParams<LlamaAirforceUnionVault>): Promise<LlamaAirforceVaultTokenDataProps> {
const reserve = appToken.pricePerShare[0] * appToken.supply;
const liquidity = reserve * appToken.price;
return { reserve, liquidity };
}

async getPositions() {
const [unionVaults, unionPirexVaults] = await Promise.all([this.getUnionVaults(), this.getUnionPirexVaults()]);
return [...unionVaults, ...unionPirexVaults];
async getLabel({ appToken }: GetDisplayPropsParams<LlamaAirforceUnionVault, LlamaAirforceVaultTokenDataProps>) {
return `${getLabelFromToken(appToken.tokens[0])} Pounder`;
}
}
2 changes: 0 additions & 2 deletions src/apps/llama-airforce/llama-airforce.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Register } from '~app-toolkit/decorators';
import { AbstractApp } from '~app/app.dynamic-module';

import { LlamaAirforceContractFactory } from './contracts';
import { EthereumLlamaAirforceAirdropContractPositionBalanceFetcher } from './ethereum/llama-airforce.airdrop.contract-position-balance-fetcher';
import { EthereumLlamaAirforceAirdropContractPositionFetcher } from './ethereum/llama-airforce.airdrop.contract-position-fetcher';
import { EthereumLlamaAirforceMerkleCache } from './ethereum/llama-airforce.merkle-cache';
import { EthereumLlamaAirforceVaultTokenFetcher } from './ethereum/llama-airforce.vault.token-fetcher';
Expand All @@ -16,7 +15,6 @@ import { LlamaAirforceAppDefinition, LLAMA_AIRFORCE_DEFINITION } from './llama-a
// Ethereum
EthereumLlamaAirforceMerkleCache,
EthereumLlamaAirforceAirdropContractPositionFetcher,
EthereumLlamaAirforceAirdropContractPositionBalanceFetcher,
EthereumLlamaAirforceVaultTokenFetcher,
],
})
Expand Down

0 comments on commit 1aff357

Please sign in to comment.