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

feat(curve): Eliminate Curve static pool definitions #954

Merged
merged 50 commits into from
Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
273252c
feat(curve): Refactor names for stable and crypto pools
immasandwich Jul 25, 2022
e60b4e1
feat(curve): Add Curve registry for pools and API for gauges
immasandwich Jul 26, 2022
7712337
feat(curve): Refactor away static definitions in Arbitrum integration
immasandwich Jul 26, 2022
149abc5
feat(curve): Eliminate dependencies on old APY routes
immasandwich Jul 26, 2022
8e29cd4
feat(curve): Apply on-chain registry strategies to Avalanche
immasandwich Jul 26, 2022
c3c18f7
feat(curve): Make myself sick a little but move factory calls to the …
immasandwich Jul 26, 2022
427ec28
feat(curve): Remove GaugeType
immasandwich Jul 26, 2022
6e0d94b
feat(curve): And apply the same to Fantom
immasandwich Jul 26, 2022
92e6cea
feat(curve): Remove unnecessary dependency on pool tokens from gauges
immasandwich Jul 26, 2022
3160ce7
feat(curve): Progress towards migrating Ethereum to the same strategy
immasandwich Jul 26, 2022
6669ec9
feat(curve): Migrate Ethereum factory pools
immasandwich Jul 26, 2022
24ea41c
feat(curve): Pools populating in Ethereum
immasandwich Jul 27, 2022
44a49a1
feat(curve): Super simple Arbitrum Curve pool token fetcher
immasandwich Jul 27, 2022
76a75c7
feat(curve): Messy, but most chains migrated to very simple default p…
immasandwich Jul 27, 2022
11ec803
feat(curve): Delete a lot of unused helpers
immasandwich Jul 27, 2022
c51fe5a
feat(curve): Remove a lot of unused contracts
immasandwich Jul 27, 2022
7dc93ba
feat(curve): Simplify side chain farms
immasandwich Jul 27, 2022
f380d7e
feat(curve): Detect gauge types from on-chain data
immasandwich Jul 27, 2022
49f807f
feat(curve): More helpers removed, farms working
immasandwich Jul 28, 2022
3cb36e6
feat(curve): Almost done
immasandwich Jul 28, 2022
dfc760c
feat(curve): More moving enums
immasandwich Jul 28, 2022
61bf5a8
feat(curve): Match implementation
immasandwich Jul 28, 2022
18d12fa
Merge remote-tracking branch 'origin/main' into curve-refactor
immasandwich Jul 28, 2022
59bb1ca
feat(curve): Abstract price for Velodrome
immasandwich Jul 28, 2022
5952a67
feat(curve): Fix Velodrome price
immasandwich Jul 28, 2022
9150e28
feat(curve): Almost there
immasandwich Jul 28, 2022
f8261f7
feat(curve): Another clean up for Bastion
immasandwich Jul 28, 2022
c95d72a
feat(curve): Rename classes to match gauge naming
immasandwich Jul 28, 2022
d889d0f
feat(curve): Fix meta pool boolean
immasandwich Jul 28, 2022
d0da8d2
feat(curve): Add a minimum liquidity
immasandwich Jul 28, 2022
79a862f
feat(curve): Add static definitions for legacy rewards only gauges
immasandwich Jul 28, 2022
1bc62b6
feat(curve): I am fucking done
immasandwich Jul 28, 2022
a8155c4
feat(curve): Give Curve child liquidity gauges first class treatment
immasandwich Jul 28, 2022
2e375c4
feat(curve): Re-enable all providers
immasandwich Jul 28, 2022
22c9a3f
feat(curve): Fix virtual price, pool detailed, gauges, etc
immasandwich Jul 29, 2022
dd7dff7
feat(curve): Support multiple gauges in data props
immasandwich Jul 29, 2022
d3a7f8c
feat(curve): Determine whether pool is crypto or stable according to …
immasandwich Jul 29, 2022
b47d440
feat(curve): Logic flow
immasandwich Jul 29, 2022
626a2ec
feat(curve): Filter correctly
immasandwich Jul 29, 2022
5f50972
feat(curve): Remove gas from registry contracts
immasandwich Jul 29, 2022
cca8cba
feat(curve): Move types
immasandwich Jul 29, 2022
c6b1835
feat(curve): Rename files
immasandwich Jul 29, 2022
8b2aa70
feat(curve): Rename gauge balance helper method
immasandwich Jul 29, 2022
8b8ec36
feat(curve): Re-add caching for gauges
immasandwich Jul 29, 2022
15c5af3
feat(curve): Rename version to gauge type
immasandwich Jul 29, 2022
70326c7
feat(curve): Move metapool detection into pool helper
immasandwich Jul 29, 2022
49811a1
feat(curve): Fix reference
immasandwich Jul 29, 2022
68bddc9
feat(curve): Fix Saddle
immasandwich Jul 29, 2022
ac116a2
feat(curve): Gauge addresses
immasandwich Jul 29, 2022
45a4330
Merge branch 'main' into curve-refactor
immasandwich Jul 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

Loading