This repository has been archived by the owner on Jan 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 382
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
134 changed files
with
49,912 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { Inject } from '@nestjs/common'; | ||
|
||
import { SingleStakingContractPositionBalanceHelper, TokenBalanceHelper } from '~app-toolkit'; | ||
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 { CurveContractFactory, CurveGaugeV2 } from '../contracts'; | ||
import { CURVE_DEFINITION } from '../curve.definition'; | ||
|
||
@Register.BalanceFetcher(CURVE_DEFINITION.id, Network.ARBITRUM_MAINNET) | ||
export class ArbitrumCurveBalanceFetcher implements BalanceFetcher { | ||
constructor( | ||
@Inject(TokenBalanceHelper) private readonly tokenBalanceHelper: TokenBalanceHelper, | ||
@Inject(CurveContractFactory) private readonly curveContractFactory: CurveContractFactory, | ||
@Inject(SingleStakingContractPositionBalanceHelper) | ||
private readonly singleStakingContractPositionBalanceHelper: SingleStakingContractPositionBalanceHelper, | ||
) {} | ||
|
||
private async getPoolTokenBalances(address: string) { | ||
return this.tokenBalanceHelper.getTokenBalances({ | ||
network: Network.ARBITRUM_MAINNET, | ||
appId: CURVE_DEFINITION.id, | ||
groupId: CURVE_DEFINITION.groups.pool.id, | ||
address, | ||
}); | ||
} | ||
|
||
private async getStakedBalances(address: string) { | ||
return this.singleStakingContractPositionBalanceHelper.getBalances<CurveGaugeV2>({ | ||
address, | ||
appId: CURVE_DEFINITION.id, | ||
groupId: CURVE_DEFINITION.groups.farm.id, | ||
network: Network.ARBITRUM_MAINNET, | ||
resolveContract: ({ address, network }) => this.curveContractFactory.curveGaugeV2({ 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))); | ||
}, | ||
}); | ||
} | ||
|
||
async getBalances(address: string) { | ||
const [poolTokenBalances, stakedBalances] = await Promise.all([ | ||
this.getPoolTokenBalances(address), | ||
this.getStakedBalances(address), | ||
]); | ||
|
||
return presentBalanceFetcherResponse([ | ||
{ | ||
label: 'Pools', | ||
assets: poolTokenBalances, | ||
}, | ||
{ | ||
label: 'Staked', | ||
assets: stakedBalances, | ||
}, | ||
]); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
src/apps/curve/arbitrum/curve.farm.contract-position-fetcher.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { Inject } from '@nestjs/common'; | ||
|
||
import { SingleStakingFarmContractPositionHelper } from '~app-toolkit'; | ||
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 { CurveContractFactory, CurveGaugeV2 } from '../contracts'; | ||
import { CURVE_DEFINITION } from '../curve.definition'; | ||
import { CurveGaugeV2RewardTokenStrategy } from '../helpers/curve.gauge-v2.reward-token-strategy'; | ||
import { CurveGaugeV2RoiStrategy } from '../helpers/curve.gauge-v2.roi-strategy'; | ||
|
||
import { CURVE_V1_POOL_DEFINITIONS, CURVE_V2_POOL_DEFINITIONS } from './curve.pool.definitions'; | ||
|
||
const appId = CURVE_DEFINITION.id; | ||
const groupId = CURVE_DEFINITION.groups.farm.id; | ||
const network = Network.ARBITRUM_MAINNET; | ||
|
||
@Register.ContractPositionFetcher({ appId, groupId, network }) | ||
export class ArbitrumCurveFarmContractPositionFetcher implements PositionFetcher<ContractPosition> { | ||
constructor( | ||
@Inject(SingleStakingFarmContractPositionHelper) | ||
private readonly singleStakingFarmContractPositionHelper: SingleStakingFarmContractPositionHelper, | ||
@Inject(CurveContractFactory) | ||
private readonly curveContractFactory: CurveContractFactory, | ||
@Inject(CurveGaugeV2RoiStrategy) | ||
private readonly curveGaugeV2RoiStrategy: CurveGaugeV2RoiStrategy, | ||
@Inject(CurveGaugeV2RewardTokenStrategy) | ||
private readonly curveGaugeV2RewardTokenStrategy: CurveGaugeV2RewardTokenStrategy, | ||
) {} | ||
|
||
async getPositions() { | ||
const definitions = [CURVE_V1_POOL_DEFINITIONS, CURVE_V2_POOL_DEFINITIONS].flat().filter(v => !!v.gaugeAddress); | ||
return this.singleStakingFarmContractPositionHelper.getContractPositions<CurveGaugeV2>({ | ||
network, | ||
appId, | ||
groupId, | ||
dependencies: [{ appId: CURVE_DEFINITION.id, groupIds: [CURVE_DEFINITION.groups.pool.id], network }], | ||
resolveFarmAddresses: () => definitions.map(v => v.gaugeAddress ?? null), | ||
resolveFarmContract: ({ address, network }) => this.curveContractFactory.curveGaugeV2({ address, network }), | ||
resolveStakedTokenAddress: ({ contract, multicall }) => multicall.wrap(contract).lp_token(), | ||
resolveRewardTokenAddresses: this.curveGaugeV2RewardTokenStrategy.build(), | ||
resolveIsActive: () => true, | ||
resolveRois: this.curveGaugeV2RoiStrategy.build({ | ||
tokenDefinitions: definitions, | ||
}), | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { CurvePoolDefinition } from '../curve.types'; | ||
|
||
export const CURVE_V1_POOL_DEFINITIONS: CurvePoolDefinition[] = [ | ||
{ | ||
queryKey: '2pool', | ||
label: '2Pool Curve', | ||
swapAddress: '0x7f90122bf0700f9e7e1f688fe926940e8839f353', | ||
tokenAddress: '0x7f90122bf0700f9e7e1f688fe926940e8839f353', | ||
gaugeAddress: '0xbf7e49483881c76487b0989cd7d9a8239b20ca41', | ||
streamAddress: '0xff17560d746f85674fe7629ce986e949602ef948', | ||
}, | ||
{ | ||
queryKey: 'renBTC', | ||
label: 'renBTC Curve', | ||
swapAddress: '0x3e01dd8a5e1fb3481f0f589056b428fc308af0fb', | ||
tokenAddress: '0x3e01dd8a5e1fb3481f0f589056b428fc308af0fb', | ||
gaugeAddress: '0xc2b1df84112619d190193e48148000e3990bf627', | ||
streamAddress: '0x9f86c5142369b1ffd4223e5a2f2005fc66807894', | ||
}, | ||
]; | ||
|
||
export const CURVE_V2_POOL_DEFINITIONS: CurvePoolDefinition[] = [ | ||
{ | ||
queryKey: 'tricrypto', | ||
label: 'TriCrypto Curve', | ||
swapAddress: '0x960ea3e3c7fb317332d990873d354e18d7645590', | ||
tokenAddress: '0x8e0b8c8bb9db49a46697f3a5bb8a308e744821d2', | ||
gaugeAddress: '0x97e2768e8e73511ca874545dc5ff8067eb19b787', | ||
streamAddress: '0x9044e12fb1732f88ed0c93cfa5e9bb9bd2990ce5', | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Inject } from '@nestjs/common'; | ||
|
||
import { Register } from '~app-toolkit/decorators'; | ||
import { PositionFetcher } from '~position/position-fetcher.interface'; | ||
import { AppTokenPosition } from '~position/position.interface'; | ||
import { Network } from '~types/network.interface'; | ||
|
||
import { CURVE_DEFINITION } from '../curve.definition'; | ||
import { CurveFactoryPoolTokenHelper } from '../helpers/curve.factory-pool.token-helper'; | ||
import { CurveV1PoolTokenHelper } from '../helpers/curve.v1-pool.token-helper'; | ||
import { CurveV2PoolTokenHelper } from '../helpers/curve.v2-pool.token-helper'; | ||
|
||
import { CURVE_V1_POOL_DEFINITIONS, CURVE_V2_POOL_DEFINITIONS } from './curve.pool.definitions'; | ||
|
||
const appId = CURVE_DEFINITION.id; | ||
const groupId = CURVE_DEFINITION.groups.pool.id; | ||
const network = Network.ARBITRUM_MAINNET; | ||
|
||
@Register.TokenPositionFetcher({ appId, groupId, network }) | ||
export class ArbitrumCurvePoolTokenFetcher implements PositionFetcher<AppTokenPosition> { | ||
constructor( | ||
@Inject(CurveV1PoolTokenHelper) | ||
private readonly curveV1PoolTokenHelper: CurveV1PoolTokenHelper, | ||
@Inject(CurveV2PoolTokenHelper) | ||
private readonly curveV2PoolTokenHelper: CurveV2PoolTokenHelper, | ||
@Inject(CurveFactoryPoolTokenHelper) | ||
private readonly curveFactoryPoolTokenHelper: CurveFactoryPoolTokenHelper, | ||
) {} | ||
|
||
async getPositions() { | ||
const [v1Pools] = await Promise.all([ | ||
this.curveV1PoolTokenHelper.getTokens({ | ||
network, | ||
appId, | ||
groupId, | ||
poolDefinitions: CURVE_V1_POOL_DEFINITIONS, | ||
statsUrl: 'https://stats.curve.fi/raw-stats-arbitrum/apys.json', | ||
}), | ||
]); | ||
|
||
const [v2Pools, v2FactoryPools] = await Promise.all([ | ||
this.curveV2PoolTokenHelper.getTokens({ | ||
network, | ||
appId, | ||
groupId, | ||
poolDefinitions: CURVE_V2_POOL_DEFINITIONS, | ||
statsUrl: 'https://stats.curve.fi/raw-stats-arbitrum/apys.json', | ||
baseCurveTokens: v1Pools, | ||
}), | ||
this.curveFactoryPoolTokenHelper.getTokens({ | ||
factoryAddress: '0xb17b674d9c5cb2e441f8e196a2f048a81355d031', | ||
network, | ||
appId, | ||
groupId, | ||
baseCurveTokens: v1Pools, | ||
skipVolume: true, // Arbitrum public RPC can't handle this | ||
}), | ||
]); | ||
|
||
return [v1Pools, v2Pools, v2FactoryPools].flat(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { Inject } from '@nestjs/common'; | ||
|
||
import { SingleStakingContractPositionBalanceHelper, TokenBalanceHelper } from '~app-toolkit'; | ||
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 { CurveContractFactory, CurveGaugeV2 } from '../contracts'; | ||
import { CURVE_DEFINITION } from '../curve.definition'; | ||
|
||
@Register.BalanceFetcher(CURVE_DEFINITION.id, Network.AVALANCHE_MAINNET) | ||
export class AvalancheCurveBalanceFetcher implements BalanceFetcher { | ||
constructor( | ||
@Inject(TokenBalanceHelper) private readonly tokenBalanceHelper: TokenBalanceHelper, | ||
@Inject(CurveContractFactory) private readonly curveContractFactory: CurveContractFactory, | ||
@Inject(SingleStakingContractPositionBalanceHelper) | ||
private readonly singleStakingContractPositionBalanceHelper: SingleStakingContractPositionBalanceHelper, | ||
) {} | ||
|
||
private async getPoolTokenBalances(address: string) { | ||
return this.tokenBalanceHelper.getTokenBalances({ | ||
network: Network.AVALANCHE_MAINNET, | ||
appId: CURVE_DEFINITION.id, | ||
groupId: CURVE_DEFINITION.groups.pool.id, | ||
address, | ||
}); | ||
} | ||
|
||
private async getStakedBalances(address: string) { | ||
return this.singleStakingContractPositionBalanceHelper.getBalances<CurveGaugeV2>({ | ||
address, | ||
appId: CURVE_DEFINITION.id, | ||
groupId: CURVE_DEFINITION.groups.farm.id, | ||
network: Network.AVALANCHE_MAINNET, | ||
resolveContract: ({ address, network }) => this.curveContractFactory.curveGaugeV2({ 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))); | ||
}, | ||
}); | ||
} | ||
|
||
async getBalances(address: string) { | ||
const [poolTokenBalances, stakedBalances] = await Promise.all([ | ||
this.getPoolTokenBalances(address), | ||
this.getStakedBalances(address), | ||
]); | ||
|
||
return presentBalanceFetcherResponse([ | ||
{ | ||
label: 'Pools', | ||
assets: poolTokenBalances, | ||
}, | ||
{ | ||
label: 'Staked', | ||
assets: stakedBalances, | ||
}, | ||
]); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
src/apps/curve/avalanche/curve.farm.contract-position-fetcher.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { Inject } from '@nestjs/common'; | ||
|
||
import { SingleStakingFarmContractPositionHelper } from '~app-toolkit'; | ||
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 { CurveContractFactory, CurveGaugeV2 } from '../contracts'; | ||
import { CURVE_DEFINITION } from '../curve.definition'; | ||
import { CurveGaugeV2RewardTokenStrategy } from '../helpers/curve.gauge-v2.reward-token-strategy'; | ||
import { CurveGaugeV2RoiStrategy } from '../helpers/curve.gauge-v2.roi-strategy'; | ||
|
||
import { CURVE_V1_POOL_DEFINITIONS, CURVE_V2_POOL_DEFINITIONS } from './curve.pool.definitions'; | ||
|
||
const appId = CURVE_DEFINITION.id; | ||
const groupId = CURVE_DEFINITION.groups.farm.id; | ||
const network = Network.AVALANCHE_MAINNET; | ||
|
||
@Register.ContractPositionFetcher({ appId, groupId, network }) | ||
export class AvalancheCurveFarmContractPositionFetcher implements PositionFetcher<ContractPosition> { | ||
constructor( | ||
@Inject(SingleStakingFarmContractPositionHelper) | ||
private readonly singleStakingFarmContractPositionHelper: SingleStakingFarmContractPositionHelper, | ||
@Inject(CurveContractFactory) | ||
private readonly curveContractFactory: CurveContractFactory, | ||
@Inject(CurveGaugeV2RoiStrategy) | ||
private readonly curveGaugeV2RoiStrategy: CurveGaugeV2RoiStrategy, | ||
@Inject(CurveGaugeV2RewardTokenStrategy) | ||
private readonly curveGaugeV2RewardTokenStrategy: CurveGaugeV2RewardTokenStrategy, | ||
) {} | ||
|
||
async getPositions() { | ||
const definitions = [CURVE_V1_POOL_DEFINITIONS, CURVE_V2_POOL_DEFINITIONS].flat().filter(v => !!v.gaugeAddress); | ||
return this.singleStakingFarmContractPositionHelper.getContractPositions<CurveGaugeV2>({ | ||
network, | ||
appId, | ||
groupId, | ||
dependencies: [{ appId: CURVE_DEFINITION.id, groupIds: [CURVE_DEFINITION.groups.pool.id], network }], | ||
resolveFarmAddresses: () => definitions.map(v => v.gaugeAddress ?? null), | ||
resolveFarmContract: ({ address, network }) => this.curveContractFactory.curveGaugeV2({ address, network }), | ||
resolveStakedTokenAddress: ({ contract, multicall }) => multicall.wrap(contract).lp_token(), | ||
resolveRewardTokenAddresses: this.curveGaugeV2RewardTokenStrategy.build(), | ||
resolveIsActive: () => true, | ||
resolveRois: this.curveGaugeV2RoiStrategy.build({ | ||
tokenDefinitions: definitions, | ||
}), | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { CurvePoolDefinition } from '../curve.types'; | ||
|
||
export const CURVE_V1_POOL_DEFINITIONS: CurvePoolDefinition[] = [ | ||
{ | ||
queryKey: 'aave', | ||
label: 'Aave 3Pool Curve', | ||
swapAddress: '0x7f90122bf0700f9e7e1f688fe926940e8839f353', | ||
tokenAddress: '0x1337bedc9d22ecbe766df105c9623922a27963ec', | ||
gaugeAddress: '0x5b5cfe992adac0c9d48e05854b2d91c73a003858', | ||
streamAddress: '0xb504b6eb06760019801a91b451d3f7bd9f027fc9', | ||
}, | ||
{ | ||
queryKey: 'renBTC', | ||
label: 'renBTC Curve', | ||
swapAddress: '0x16a7da911a4dd1d83f3ff066fe28f3c792c50d90', | ||
tokenAddress: '0xc2b1df84112619d190193e48148000e3990bf627', | ||
gaugeAddress: '0x0f9cb53ebe405d49a0bbdbd291a65ff571bc83e1', | ||
streamAddress: '0x75d05190f35567e79012c2f0a02330d3ed8a1f74', | ||
}, | ||
]; | ||
|
||
export const CURVE_V2_POOL_DEFINITIONS: CurvePoolDefinition[] = [ | ||
{ | ||
queryKey: 'atricrypto', | ||
label: 'Aave TriCrypto Curve', | ||
swapAddress: '0xb755b949c126c04e0348dd881a5cf55d424742b2', | ||
tokenAddress: '0x1dab6560494b04473a0be3e7d83cf3fdf3a51828', | ||
gaugeAddress: '0x445fe580ef8d70ff569ab36e80c647af338db351', | ||
streamAddress: '0xa05e565ca0a103fcd999c7a7b8de7bd15d5f6505', | ||
}, | ||
]; |
Oops, something went wrong.