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

fix: lyra-avalon - address post merge comments #529

Merged
merged 2 commits into from
May 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/apps/lyra-avalon/optimism/helpers/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export const OPTION_TYPES = {
3: 'Short Call Quote',
4: 'Short Put Quote',
};

export const REGISTRY_ADDRESS = '0x7c7AbDdbCb6c731237f7546d3e4c5165531fb0c1'.toLowerCase();
48 changes: 16 additions & 32 deletions src/apps/lyra-avalon/optimism/lyra-avalon.balance-fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Inject } from '@nestjs/common';
import _ from 'lodash';

import { drillBalance } from '~app-toolkit';
import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
Expand All @@ -10,11 +9,10 @@ import { ContractPosition } from '~position/position.interface';
import { isSupplied } from '~position/position.utils';
import { Network } from '~types/network.interface';

import { LyraAvalonContractFactory } from '../contracts';
import { LyraAvalonContractFactory, OptionToken } from '../contracts';
import { LYRA_AVALON_DEFINITION } from '../lyra-avalon.definition';

import { OPTION_TYPES } from './helpers/consts';
import { getOptions } from './helpers/graph';
import { LyraAvalonOptionContractPositionDataProps } from './lyra-avalon.options.contract-position-fetcher';

const appId = LYRA_AVALON_DEFINITION.id;
Expand All @@ -37,23 +35,8 @@ export class OptimismLyraAvalonBalanceFetcher implements BalanceFetcher {
}

async getOptionsBalances(address: string) {
const markets: Record<string, OptionToken.OptionPositionStructOutput[]> = {};
const multicall = this.appToolkit.getMulticall(network);
const response = await getOptions(this.appToolkit.helpers.theGraphHelper);
const markets = await Promise.all(
response.markets.map(async market => {
const tokenContract = this.contractFactory.optionToken({
address: market.optionToken.id.toLowerCase(),
network,
});
const userPositions = await multicall.wrap(tokenContract).getOwnerPositions(address);
return {
userPositions,
marketAddress: market.optionToken.id.toLowerCase(),
quoteAddress: market.quoteAddress,
strikes: _.flatten(market.boards.map(board => board.strikes)),
};
}),
);

return this.appToolkit.helpers.contractPositionBalanceHelper.getContractPositionBalances({
address,
Expand All @@ -65,35 +48,36 @@ export class OptimismLyraAvalonBalanceFetcher implements BalanceFetcher {
}: {
contractPosition: ContractPosition<LyraAvalonOptionContractPositionDataProps>;
}) => {
// Find matching market for contract position
const market = markets.find(market => market.marketAddress === contractPosition.address);
if (!market?.strikes) return [];

// Extract information from contract position
const { strikeId, optionType } = contractPosition.dataProps;
const { strikeId, optionType, marketAddress, quoteAddress, tokenAddress, callPrice, putPrice } =
contractPosition.dataProps;
const collateralToken = contractPosition.tokens.find(isSupplied)!;
const quoteToken = contractPosition.tokens.find(token => token.address === market.quoteAddress.toLowerCase())!;
const quoteToken = contractPosition.tokens.find(token => token.address === quoteAddress)!;

// Pull user positions for the relevant market
if (!markets[marketAddress]) {
const contract = this.contractFactory.optionToken({ address: tokenAddress, network });
markets[marketAddress] = await multicall.wrap(contract).getOwnerPositions(address);
}

// Find matching user position for contract position
const userPosition = market.userPositions.find(
const userPosition = markets[marketAddress].find(
position => Number(position.strikeId) === strikeId && position.optionType === optionType,
);
if (!userPosition) return [];

// Determine price of the contract position strike
const strike = market.strikes.find(strike => Number(strike.strikeId) === strikeId);
if (!strike) return [];
const price = (OPTION_TYPES[optionType].includes('Call') ? strike.callOption : strike.putOption)
.latestOptionPriceAndGreeks.optionPrice;
// Determine price of the contract position strike.
// Note: may not be totally accurate
const price = OPTION_TYPES[optionType].includes('Call') ? callPrice : putPrice;
const balance = ((Number(price) * Number(userPosition.amount)) / 10 ** quoteToken.decimals).toString();

// Return balance. Note: may not be totally accurate
if (Number(optionType) >= 2) {
// Short Option
const debt = drillBalance(quoteToken, balance, { isDebt: true });
const collateral = drillBalance(collateralToken, userPosition.collateral.toString());
return [debt, collateral];
}
// Long Option
return [drillBalance(quoteToken, balance)];
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ const network = Network.OPTIMISM_MAINNET;
export interface LyraAvalonOptionContractPositionDataProps extends DefaultDataProps {
optionType: number;
strikeId: number;
marketAddress: string;
quoteAddress: string;
tokenAddress: string;
callPrice: number;
putPrice: number;
}

@Register.ContractPositionFetcher({ appId, groupId, network })
Expand Down Expand Up @@ -56,6 +61,11 @@ export class OptimismLyraAvalonOptionsContractPositionFetcher implements Positio
dataProps: {
strikeId: Number(strike.strikeId),
optionType: Number(key),
marketAddress: market.id,
quoteAddress: market.quoteAddress,
tokenAddress: market.optionToken.id,
callPrice: Number(strike.callOption.latestOptionPriceAndGreeks.optionPrice),
putPrice: Number(strike.putOption.latestOptionPriceAndGreeks.optionPrice),
},
displayProps: {
...position.displayProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ import { Network } from '~types/network.interface';
import { LyraAvalonContractFactory, LiquidityToken } from '../contracts';
import { LYRA_AVALON_DEFINITION } from '../lyra-avalon.definition';

import { REGISTRY_ADDRESS } from './helpers/consts';
import { runQuery } from './helpers/graph';

const appId = LYRA_AVALON_DEFINITION.id;
const groupId = LYRA_AVALON_DEFINITION.groups.pool.id;
const network = Network.OPTIMISM_MAINNET;

const REGISTRY_ADDRESS = '0x7c7AbDdbCb6c731237f7546d3e4c5165531fb0c1'.toLowerCase();

// TODO: find better way to determine available markets
type QueryResponse = {
markets: {
Expand Down