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 383
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(lyra-avalon): Fix Pool positions on Optimism and update stkLyra p…
…osition (#2847)
- Loading branch information
Showing
9 changed files
with
211 additions
and
232 deletions.
There are no files selected for viewing
88 changes: 5 additions & 83 deletions
88
src/apps/lyra-avalon/arbitrum/lyra-avalon.pool.token-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 |
---|---|---|
@@ -1,89 +1,11 @@ | ||
import { Inject } from '@nestjs/common'; | ||
import { gql } from 'graphql-request'; | ||
|
||
import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; | ||
import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; | ||
import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; | ||
import { AppTokenTemplatePositionFetcher } from '~position/template/app-token.template.position-fetcher'; | ||
import { | ||
DefaultAppTokenDefinition, | ||
DefaultAppTokenDataProps, | ||
GetAddressesParams, | ||
GetPricePerShareParams, | ||
} from '~position/template/app-token.template.types'; | ||
|
||
import { LyraAvalonContractFactory, LyraLiquidityToken } from '../contracts'; | ||
|
||
// TODO: find better way to determine available markets | ||
type QueryResponse = { | ||
markets: { | ||
id: string; | ||
baseAddress: string; | ||
quoteAddress: string; | ||
liquidityPool: { | ||
id: string; | ||
}; | ||
}[]; | ||
}; | ||
const QUERY = gql` | ||
{ | ||
markets(where: { isRemoved: false }) { | ||
id | ||
baseAddress | ||
quoteAddress | ||
liquidityPool { | ||
id | ||
} | ||
} | ||
} | ||
`; | ||
import { LyraAvalonPoolTokenFetcher } from '../common/lyra-avalon.pool.token-fetcher'; | ||
|
||
@PositionTemplate() | ||
export class ArbitrumLyraAvalonPoolTokenFetcher extends AppTokenTemplatePositionFetcher<LyraLiquidityToken> { | ||
groupLabel = 'Pools'; | ||
|
||
constructor( | ||
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, | ||
@Inject(LyraAvalonContractFactory) protected readonly contractFactory: LyraAvalonContractFactory, | ||
) { | ||
super(appToolkit); | ||
} | ||
|
||
getContract(address: string): LyraLiquidityToken { | ||
return this.contractFactory.lyraLiquidityToken({ address, network: this.network }); | ||
} | ||
|
||
async getAddresses({ multicall }: GetAddressesParams<DefaultAppTokenDefinition>) { | ||
const registryContract = this.contractFactory.lyraRegistry({ | ||
address: '0x6c87e4364fd44b0d425adfd0328e56b89b201329', | ||
network: this.network, | ||
}); | ||
|
||
const marketsResponse = await gqlFetch<QueryResponse>({ | ||
endpoint: 'https://api.lyra.finance/subgraph/arbitrum/v2/api', | ||
query: QUERY, | ||
}); | ||
|
||
const markets = await Promise.all( | ||
marketsResponse.markets.map(market => multicall.wrap(registryContract).marketAddresses(market.id)), | ||
); | ||
|
||
return markets.map(market => market.liquidityToken); | ||
} | ||
|
||
async getUnderlyingTokenDefinitions() { | ||
return [{ address: '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', network: this.network }]; | ||
} | ||
|
||
async getPricePerShare({ | ||
contract, | ||
multicall, | ||
}: GetPricePerShareParams<LyraLiquidityToken, DefaultAppTokenDataProps, DefaultAppTokenDefinition>) { | ||
const pool = await contract.liquidityPool(); | ||
const poolContract = this.contractFactory.lyraLiquidityPool({ address: pool, network: this.network }); | ||
const ratioRaw = await multicall.wrap(poolContract).getTokenPrice(); | ||
const ratio = Number(ratioRaw) / 10 ** 18; | ||
export class ArbitrumLyraAvalonPoolTokenFetcher extends LyraAvalonPoolTokenFetcher { | ||
subgraphUrl = 'https://api.lyra.finance/subgraph/arbitrum/v2/api'; | ||
|
||
return [ratio]; | ||
} | ||
registryContractAddress = '0x6c87e4364fd44b0d425adfd0328e56b89b201329'; | ||
underlyingContractAddress = '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8'; | ||
} |
91 changes: 91 additions & 0 deletions
91
src/apps/lyra-avalon/common/lyra-avalon.pool.token-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,91 @@ | ||
import { Inject } from '@nestjs/common'; | ||
import { gql } from 'graphql-request'; | ||
|
||
import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; | ||
import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; | ||
import { AppTokenTemplatePositionFetcher } from '~position/template/app-token.template.position-fetcher'; | ||
import { | ||
DefaultAppTokenDefinition, | ||
DefaultAppTokenDataProps, | ||
GetAddressesParams, | ||
GetPricePerShareParams, | ||
} from '~position/template/app-token.template.types'; | ||
|
||
import { LyraAvalonContractFactory, LyraLiquidityToken } from '../contracts'; | ||
|
||
// TODO: find better way to determine available markets | ||
type QueryResponse = { | ||
markets: { | ||
id: string; | ||
baseAddress: string; | ||
quoteAddress: string; | ||
liquidityPool: { | ||
id: string; | ||
}; | ||
}[]; | ||
}; | ||
const QUERY = gql` | ||
{ | ||
markets(where: { isRemoved: false }) { | ||
id | ||
baseAddress | ||
quoteAddress | ||
liquidityPool { | ||
id | ||
} | ||
} | ||
} | ||
`; | ||
|
||
export abstract class LyraAvalonPoolTokenFetcher extends AppTokenTemplatePositionFetcher<LyraLiquidityToken> { | ||
groupLabel = 'Pools'; | ||
|
||
abstract subgraphUrl: string; | ||
abstract registryContractAddress: string; | ||
abstract underlyingContractAddress: string; | ||
|
||
constructor( | ||
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, | ||
@Inject(LyraAvalonContractFactory) protected readonly contractFactory: LyraAvalonContractFactory, | ||
) { | ||
super(appToolkit); | ||
} | ||
|
||
getContract(address: string): LyraLiquidityToken { | ||
return this.contractFactory.lyraLiquidityToken({ address, network: this.network }); | ||
} | ||
|
||
async getAddresses({ multicall }: GetAddressesParams<DefaultAppTokenDefinition>) { | ||
const registryContract = this.contractFactory.lyraRegistry({ | ||
address: this.registryContractAddress, | ||
network: this.network, | ||
}); | ||
|
||
const marketsResponse = await gqlFetch<QueryResponse>({ | ||
endpoint: this.subgraphUrl, | ||
query: QUERY, | ||
}); | ||
|
||
const markets = await Promise.all( | ||
marketsResponse.markets.map(market => multicall.wrap(registryContract).marketAddresses(market.id)), | ||
); | ||
|
||
return markets.map(market => market.liquidityToken); | ||
} | ||
|
||
async getUnderlyingTokenDefinitions() { | ||
return [{ address: this.underlyingContractAddress, network: this.network }]; | ||
} | ||
|
||
async getPricePerShare({ | ||
contract, | ||
multicall, | ||
}: GetPricePerShareParams<LyraLiquidityToken, DefaultAppTokenDataProps, DefaultAppTokenDefinition>) { | ||
const pool = await contract.liquidityPool(); | ||
const poolContract = this.contractFactory.lyraLiquidityPool({ address: pool, network: this.network }); | ||
const ratioRaw = await multicall.wrap(poolContract).getTokenPrice(); | ||
const ratio = Number(ratioRaw) / 10 ** 18; | ||
|
||
return [ratio]; | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
src/apps/lyra-avalon/common/lyra-avalon.stk-lyra-claimable.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,54 @@ | ||
import { Inject } from '@nestjs/common'; | ||
|
||
import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface'; | ||
import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present'; | ||
import { MetaType } from '~position/position.interface'; | ||
import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher'; | ||
import { | ||
DefaultContractPositionDefinition, | ||
GetDisplayPropsParams, | ||
GetTokenBalancesParams, | ||
GetTokenDefinitionsParams, | ||
} from '~position/template/contract-position.template.types'; | ||
|
||
import { LyraAvalonContractFactory, LyraStkLyra } from '../contracts'; | ||
|
||
export abstract class LyraAvalonStkLyraClaimableContractPositionFetcher extends ContractPositionTemplatePositionFetcher<LyraStkLyra> { | ||
groupLabel = 'stkLYRA Rewards'; | ||
|
||
abstract stkLyraContractAddress: string; | ||
|
||
constructor( | ||
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, | ||
@Inject(LyraAvalonContractFactory) protected readonly contractFactory: LyraAvalonContractFactory, | ||
) { | ||
super(appToolkit); | ||
} | ||
|
||
getContract(address: string): LyraStkLyra { | ||
return this.contractFactory.lyraStkLyra({ address, network: this.network }); | ||
} | ||
|
||
async getDefinitions(): Promise<DefaultContractPositionDefinition[]> { | ||
return [{ address: this.stkLyraContractAddress }]; | ||
} | ||
|
||
async getTokenDefinitions({ contract }: GetTokenDefinitionsParams<LyraStkLyra>) { | ||
return [ | ||
{ | ||
metaType: MetaType.CLAIMABLE, | ||
address: await contract.STAKED_TOKEN(), | ||
network: this.network, | ||
}, | ||
]; | ||
} | ||
|
||
async getLabel({ contractPosition }: GetDisplayPropsParams<LyraStkLyra>) { | ||
return `Claimable ${getLabelFromToken(contractPosition.tokens[0])}`; | ||
} | ||
|
||
async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams<LyraStkLyra>) { | ||
const rewardBalance = await contract.getTotalRewardsBalance(address); | ||
return [rewardBalance]; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/apps/lyra-avalon/ethereum/lyra-avalon.stk-lyra-claimable.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,10 @@ | ||
import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; | ||
|
||
import { LyraAvalonStkLyraClaimableContractPositionFetcher } from '../common/lyra-avalon.stk-lyra-claimable.contract-position-fetcher'; | ||
|
||
@PositionTemplate() | ||
export class EthereumLyraAvalonStkLyraClaimableContractPositionFetcher extends LyraAvalonStkLyraClaimableContractPositionFetcher { | ||
groupLabel = 'stkLYRA Rewards'; | ||
|
||
stkLyraContractAddress = '0xcb9f85730f57732fc899fb158164b9ed60c77d49'; | ||
} |
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
103 changes: 5 additions & 98 deletions
103
src/apps/lyra-avalon/optimism/lyra-avalon.pool.token-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 |
---|---|---|
@@ -1,103 +1,10 @@ | ||
import { Inject } from '@nestjs/common'; | ||
import Axios from 'axios'; | ||
import { gql } from 'graphql-request'; | ||
|
||
import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface'; | ||
import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator'; | ||
import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper'; | ||
import { AppTokenTemplatePositionFetcher } from '~position/template/app-token.template.position-fetcher'; | ||
import { | ||
DefaultAppTokenDefinition, | ||
DefaultAppTokenDataProps, | ||
GetAddressesParams, | ||
GetPricePerShareParams, | ||
} from '~position/template/app-token.template.types'; | ||
|
||
import { LyraAvalonContractFactory, LyraLiquidityToken } from '../contracts'; | ||
|
||
type LyraMainnetAddresses = Record< | ||
string, | ||
{ | ||
contractName: string; | ||
source: string; | ||
address: string; | ||
txn: string; | ||
blockNumber: number; | ||
} | ||
>; | ||
|
||
// TODO: find better way to determine available markets | ||
type QueryResponse = { | ||
markets: { | ||
id: string; | ||
baseAddress: string; | ||
quoteAddress: string; | ||
liquidityPool: { | ||
id: string; | ||
}; | ||
}[]; | ||
}; | ||
const QUERY = gql` | ||
{ | ||
markets(where: { isRemoved: false }) { | ||
id | ||
baseAddress | ||
quoteAddress | ||
liquidityPool { | ||
id | ||
} | ||
} | ||
} | ||
`; | ||
import { LyraAvalonPoolTokenFetcher } from '../common/lyra-avalon.pool.token-fetcher'; | ||
|
||
@PositionTemplate() | ||
export class OptimismLyraAvalonPoolTokenFetcher extends AppTokenTemplatePositionFetcher<LyraLiquidityToken> { | ||
groupLabel = 'Pools'; | ||
|
||
constructor( | ||
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit, | ||
@Inject(LyraAvalonContractFactory) protected readonly contractFactory: LyraAvalonContractFactory, | ||
) { | ||
super(appToolkit); | ||
} | ||
|
||
getContract(address: string): LyraLiquidityToken { | ||
return this.contractFactory.lyraLiquidityToken({ address, network: this.network }); | ||
} | ||
|
||
async getAddresses({ multicall }: GetAddressesParams<DefaultAppTokenDefinition>) { | ||
const dataUrl = 'https://raw.githubusercontent.com/lyra-finance/subgraph/master/addresses/mainnet-ovm/lyra.json'; | ||
const { data: addresses } = await Axios.get<LyraMainnetAddresses>(dataUrl); | ||
const registryContract = this.contractFactory.lyraRegistry({ | ||
address: addresses.LyraRegistry.address, | ||
network: this.network, | ||
}); | ||
|
||
const marketsResponse = await gqlFetch<QueryResponse>({ | ||
endpoint: 'https://api.lyra.finance/subgraph/optimism/v1/api', | ||
query: QUERY, | ||
}); | ||
|
||
const markets = await Promise.all( | ||
marketsResponse.markets.map(market => multicall.wrap(registryContract).marketAddresses(market.id)), | ||
); | ||
|
||
return markets.map(market => market.liquidityToken); | ||
} | ||
|
||
async getUnderlyingTokenDefinitions() { | ||
return [{ address: '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9', network: this.network }]; | ||
} | ||
|
||
async getPricePerShare({ | ||
appToken, | ||
contract, | ||
multicall, | ||
}: GetPricePerShareParams<LyraLiquidityToken, DefaultAppTokenDataProps, DefaultAppTokenDefinition>) { | ||
const pool = await contract.liquidityPool(); | ||
const poolContract = this.contractFactory.lyraLiquidityPool({ address: pool, network: this.network }); | ||
const ratioRaw = await multicall.wrap(poolContract).getTokenPrice(); | ||
const ratio = Number(ratioRaw) / 10 ** appToken.tokens[0].decimals; | ||
return [ratio]; | ||
} | ||
export class OptimismLyraAvalonPoolTokenFetcher extends LyraAvalonPoolTokenFetcher { | ||
subgraphUrl = 'https://api.lyra.finance/subgraph/optimism/v2/api'; | ||
registryContractAddress = '0x0fed189bcd4a680e05b153dc7c3dc87004e162fb'; | ||
underlyingContractAddress = '0x7f5c764cbc14f9669b88837ca1490cca17c31607'; | ||
} |
Oops, something went wrong.