Skip to content

Commit

Permalink
feat(curve): Eliminate Curve static pool definitions (Zapper-fi#954)
Browse files Browse the repository at this point in the history
  • Loading branch information
immasandwich committed Jul 29, 2022
1 parent 0a99285 commit e5866a4
Show file tree
Hide file tree
Showing 142 changed files with 8,522 additions and 24,059 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { BASTION_PROTOCOL_DEFINITION } from '../bastion-protocol.definition';
import { BastionProtocolContractFactory } from '../contracts';
import { BastionProtocolContractFactory, BastionProtocolSwap } from '../contracts';

const appId = BASTION_PROTOCOL_DEFINITION.id;
const groupId = BASTION_PROTOCOL_DEFINITION.groups.swap.id;
Expand All @@ -22,24 +22,16 @@ export class AuroraBastionProtocolSwapTokenFetcher implements PositionFetcher<Ap
private readonly bastionProtocolContractFactory: BastionProtocolContractFactory,
) {}

async getLPTokenPrice({ tokens, reserves, poolContract, multicall, supply }) {
const virtualPriceRaw = await multicall.wrap(poolContract).getVirtualPrice();
const virtualPrice = Number(virtualPriceRaw) / 10 ** 18;
const reservesUSD = tokens.map((t, i) => reserves[i] * t.price);
const liquidity = reservesUSD.reduce((total, r) => total + r, 0);
return virtualPrice > 0 ? virtualPrice * (liquidity / supply) : liquidity / supply;
}

async getPositions() {
const poolDefinitions: CurvePoolDefinition[] = [
{
queryKey: 'cusdccusdt',
label: 'cUSDC/cUSDT Pool',
swapAddress: '0x6287e912a9ccd4d5874ae15d3c89556b2a05f080',
tokenAddress: '0x0039f0641156cac478b0debab086d78b66a69a01',
coinAddresses: ['0x845e15a441cfc1871b7ac610b0e922019bad9826', '0xe5308dc623101508952948b141fd9eabd3337d99'],
},
];
const appTokenDefinition = [

const dependencies = [
{
appId,
groupIds: [
Expand All @@ -51,38 +43,29 @@ export class AuroraBastionProtocolSwapTokenFetcher implements PositionFetcher<Ap
network,
},
];
return this.curvePoolTokenHelper.getTokens({

return this.curvePoolTokenHelper.getTokens<BastionProtocolSwap>({
network,
appId,
groupId,
appTokenDependencies: appTokenDefinition,
resolvePoolDefinitions: async () => poolDefinitions,
dependencies: dependencies,
poolDefinitions: poolDefinitions,
resolvePoolContract: ({ network, definition }) =>
this.bastionProtocolContractFactory.bastionProtocolSwap({ address: definition.swapAddress, network }),
resolvePoolTokenContract: ({ network, definition }) =>
this.bastionProtocolContractFactory.erc20({ network, address: definition.tokenAddress }),
resolvePoolCoinAddresses: ({ multicall, poolContract }) =>
Promise.all([multicall.wrap(poolContract).getToken(0), multicall.wrap(poolContract).getToken(1)]),
resolvePoolReserves: ({ multicall, poolContract }) =>
Promise.all([
multicall
.wrap(poolContract)
.getTokenBalance(0)
.then(v => v.toString()),
multicall
.wrap(poolContract)
.getTokenBalance(1)
.then(v => v.toString()),
]),
resolvePoolVolume: undefined,
resolvePoolReserves: async ({ definition, multicall, poolContract }) =>
Promise.all(definition.coinAddresses.map((_, i) => multicall.wrap(poolContract).getTokenBalance(i))),
resolvePoolFee: ({ multicall, poolContract }) =>
multicall
.wrap(poolContract)
.swapStorage()
.then(r => r.swapFee),
resolvePoolTokenPrice: this.getLPTokenPrice,
resolvePoolTokenSymbol: ({ multicall, poolTokenContract }) => multicall.wrap(poolTokenContract).symbol(),
resolvePoolTokenSupply: ({ multicall, poolTokenContract }) => multicall.wrap(poolTokenContract).totalSupply(),
resolvePoolTokenPrice: async ({ tokens, reserves, poolContract, multicall, supply }) => {
const virtualPriceRaw = await multicall.wrap(poolContract).getVirtualPrice();
const virtualPrice = Number(virtualPriceRaw) / 10 ** 18;
const reservesUSD = tokens.map((t, i) => reserves[i] * t.price);
const liquidity = reservesUSD.reduce((total, r) => total + r, 0);
return virtualPrice > 0 ? virtualPrice * (liquidity / supply) : liquidity / supply;
},
});
}
}
2 changes: 2 additions & 0 deletions src/apps/compound/helper/compound.supply.token-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export class CompoundSupplyTokenHelper {
const label = getDisplayLabel
? await getDisplayLabel({ contract, multicall, underlyingToken })
: underlyingToken.symbol;
const labelDetailed = symbol;
const secondaryLabel = buildDollarDisplayItem(underlyingToken.price);
const tertiaryLabel = `${(supplyApy * 100).toFixed(3)}% APY`;
const images = [getTokenImg(underlyingToken.address, network)];
Expand Down Expand Up @@ -174,6 +175,7 @@ export class CompoundSupplyTokenHelper {

displayProps: {
label,
labelDetailed,
secondaryLabel,
tertiaryLabel,
images,
Expand Down
49 changes: 8 additions & 41 deletions src/apps/curve/arbitrum/curve.balance-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { presentBalanceFetcherResponse } from '~app-toolkit/helpers/presentation/balance-fetcher-response.present';
import { BalanceFetcher } from '~balance/balance-fetcher.interface';
import { isClaimable } from '~position/position.utils';
import { Network } from '~types/network.interface';

import { CurveChildLiquidityGauge, CurveContractFactory, CurveRewardsOnlyGauge } from '../contracts';
import { CURVE_DEFINITION } from '../curve.definition';
import { CurveGaugeDefaultContractPositionBalanceHelper } from '../helpers/curve.gauge.default.contract-position-balance-helper';

const network = Network.ARBITRUM_MAINNET;

@Register.BalanceFetcher(CURVE_DEFINITION.id, Network.ARBITRUM_MAINNET)
export class ArbitrumCurveBalanceFetcher implements BalanceFetcher {
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(CurveContractFactory) private readonly curveContractFactory: CurveContractFactory,
@Inject(CurveGaugeDefaultContractPositionBalanceHelper)
private readonly curveGaugeDefaultContractPositionBalanceHelper: CurveGaugeDefaultContractPositionBalanceHelper,
) {}

private async getPoolTokenBalances(address: string) {
Expand All @@ -28,50 +28,17 @@ export class ArbitrumCurveBalanceFetcher implements BalanceFetcher {
});
}

private async getRewardsOnlyGaugeStakedBalances(address: string) {
return this.appToolkit.helpers.singleStakingContractPositionBalanceHelper.getBalances<CurveRewardsOnlyGauge>({
private async getStakedBalances(address: string) {
return this.curveGaugeDefaultContractPositionBalanceHelper.getBalances({
address,
appId: CURVE_DEFINITION.id,
groupId: CURVE_DEFINITION.groups.farm.id,
network,
farmFilter: v => v.dataProps.implementation === 'rewards-only-gauge',
resolveContract: ({ address, network }) => this.curveContractFactory.curveRewardsOnlyGauge({ address, network }),
resolveStakedTokenBalance: ({ contract, address, multicall }) => multicall.wrap(contract).balanceOf(address),
resolveRewardTokenBalances: ({ contract, address, multicall, contractPosition }) => {
const rewardTokens = contractPosition.tokens.filter(isClaimable);
const wrappedContract = multicall.wrap(contract);
return Promise.all(rewardTokens.map(v => wrappedContract.claimable_reward_write(address, v.address)));
},
});
}

private async getChildLiquidityGaugeStakedBalances(address: string) {
return this.appToolkit.helpers.singleStakingContractPositionBalanceHelper.getBalances<CurveChildLiquidityGauge>({
address,
appId: CURVE_DEFINITION.id,
groupId: CURVE_DEFINITION.groups.farm.id,
network,
farmFilter: v => v.dataProps.implementation === 'child-liquidity-gauge',
resolveContract: ({ address, network }) =>
this.curveContractFactory.curveChildLiquidityGauge({ address, network }),
resolveStakedTokenBalance: ({ contract, address, multicall }) => multicall.wrap(contract).balanceOf(address),
resolveRewardTokenBalances: async ({ contract, address, multicall, contractPosition }) => {
const rewardTokens = contractPosition.tokens.filter(isClaimable);
const otherRewardTokens = rewardTokens.filter(v => v.symbol !== 'CRV');

return Promise.all([
multicall.wrap(contract).callStatic.claimable_tokens(address),
...otherRewardTokens.map(v => multicall.wrap(contract).claimable_reward(address, v.address)),
]);
},
});
}

async getBalances(address: string) {
const [poolTokenBalances, rewardOnlyGaugeStakedBalances, childLiquidityGaugeStakedBalances] = await Promise.all([
const [poolTokenBalances, stakedBalances] = await Promise.all([
this.getPoolTokenBalances(address),
this.getRewardsOnlyGaugeStakedBalances(address),
this.getChildLiquidityGaugeStakedBalances(address),
this.getStakedBalances(address),
]);

return presentBalanceFetcherResponse([
Expand All @@ -81,7 +48,7 @@ export class ArbitrumCurveBalanceFetcher implements BalanceFetcher {
},
{
label: 'Staked',
assets: [...rewardOnlyGaugeStakedBalances, ...childLiquidityGaugeStakedBalances],
assets: stakedBalances,
},
]);
}
Expand Down
95 changes: 0 additions & 95 deletions src/apps/curve/arbitrum/curve.farm.contract-position-fetcher.ts

This file was deleted.

28 changes: 28 additions & 0 deletions src/apps/curve/arbitrum/curve.gauge.contract-position-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Inject } from '@nestjs/common';

import { Register } from '~app-toolkit/decorators';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { ContractPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { CURVE_DEFINITION } from '../curve.definition';
import { CurveGaugeDefaultContractPositionHelper } from '../helpers/curve.gauge.default.contract-position-helper';

const appId = CURVE_DEFINITION.id;
const groupId = CURVE_DEFINITION.groups.gauge.id;
const network = Network.ARBITRUM_MAINNET;

@Register.ContractPositionFetcher({ appId, groupId, network })
export class ArbitrumCurveGaugeContractPositionFetcher implements PositionFetcher<ContractPosition> {
constructor(
@Inject(CurveGaugeDefaultContractPositionHelper)
private readonly curveGaugeDefaultContractPositionHelper: CurveGaugeDefaultContractPositionHelper,
) {}

async getPositions() {
return this.curveGaugeDefaultContractPositionHelper.getPositions({
network,
crvTokenAddress: '0x11cdb42b0eb46d95f990bedd4695a6e3fa034978',
});
}
}
37 changes: 0 additions & 37 deletions src/apps/curve/arbitrum/curve.pool.definitions.ts

This file was deleted.

0 comments on commit e5866a4

Please sign in to comment.