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

Commit

Permalink
feat(across-v2): Integrate Across V2 pools (#1613)
Browse files Browse the repository at this point in the history
* feat(across-v2): Add Across V2 pool support

* feat(across): Done V2

* feat(across): Fix dummy

* Done

* Done
  • Loading branch information
immasandwich authored Oct 21, 2022
1 parent 110db0e commit 4bf37ba
Show file tree
Hide file tree
Showing 13 changed files with 5,542 additions and 4 deletions.
10 changes: 7 additions & 3 deletions src/apps/across/across.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ export const ACROSS_DEFINITION = appDefinition({
type: GroupType.TOKEN,
label: 'V1 Pools',
},
v2Pool: {
id: 'v2-pool',
type: GroupType.TOKEN,
label: 'V2 Pools',
},
},
tags: [AppTag.BRIDGE, AppTag.CROSS_CHAIN],
links: {
learn: 'https://docs.across.to/bridge/',
github: 'https://github.com/across-protocol',
twitter: '',
telegram: '',
twitter: 'https://twitter.com/AcrossProtocol',
discord: 'https://discord.gg/across',
medium: '',
medium: 'https://medium.com/across-protocol',
},
supportedNetworks: {
[Network.ETHEREUM_MAINNET]: [AppAction.VIEW],
Expand Down
8 changes: 7 additions & 1 deletion src/apps/across/across.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import { AbstractApp } from '~app/app.dynamic-module';
import { AcrossAppDefinition, ACROSS_DEFINITION } from './across.definition';
import { AcrossContractFactory } from './contracts';
import { EthereumAcrossV1PoolTokenFetcher } from './ethereum/across.v1-pool.token-fetcher';
import { EthereumAcrossV2PoolTokenFetcher } from './ethereum/across.v2-pool.token-fetcher';

@Register.AppModule({
appId: ACROSS_DEFINITION.id,
providers: [AcrossAppDefinition, AcrossContractFactory, EthereumAcrossV1PoolTokenFetcher],
providers: [
AcrossAppDefinition,
AcrossContractFactory,
EthereumAcrossV1PoolTokenFetcher,
EthereumAcrossV2PoolTokenFetcher,
],
})
export class AcrossAppModule extends AbstractApp() {}
92 changes: 92 additions & 0 deletions src/apps/across/common/across.v2-pool.token-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Inject } from '@nestjs/common';
import { uniq } from 'lodash';
import 'moment-duration-format';

import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { AppTokenTemplatePositionFetcher } from '~position/template/app-token.template.position-fetcher';
import {
DefaultAppTokenDataProps,
GetAddressesParams,
GetDataPropsParams,
GetDefinitionsParams,
GetDisplayPropsParams,
GetPricePerShareParams,
GetUnderlyingTokensParams,
} from '~position/template/app-token.template.types';

import { AcrossContractFactory, AcrossV2PoolToken } from '../contracts';

export type AcrossV2PoolTokenDefinition = {
address: string;
underlyingTokenAddress: string;
};

export abstract class AcrossV2PoolTokenFetcher extends AppTokenTemplatePositionFetcher<
AcrossV2PoolToken,
DefaultAppTokenDataProps,
AcrossV2PoolTokenDefinition
> {
abstract hubAddress: string;

constructor(
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit,
@Inject(AcrossContractFactory) protected readonly contractFactory: AcrossContractFactory,
) {
super(appToolkit);
}

getContract(address: string): AcrossV2PoolToken {
return this.contractFactory.acrossV2PoolToken({ network: this.network, address });
}

async getDefinitions({ multicall }: GetDefinitionsParams): Promise<AcrossV2PoolTokenDefinition[]> {
const hub = this.contractFactory.acrossV2HubPool({ address: this.hubAddress, network: this.network });
const logs = await hub.queryFilter(hub.filters.LiquidityAdded(), 14819537);
const collateral = uniq(logs.map(v => v.args.l1Token.toLowerCase()));

const lpTokens = await Promise.all(collateral.map(c => multicall.wrap(hub).pooledTokens(c)));
const definitions = collateral.map((c, i) => ({
address: lpTokens[i].lpToken.toLowerCase(),
underlyingTokenAddress: c,
}));

return definitions;
}

async getAddresses({ definitions }: GetAddressesParams) {
return definitions.map(v => v.address);
}

async getUnderlyingTokenAddresses({
definition,
}: GetUnderlyingTokensParams<AcrossV2PoolToken, AcrossV2PoolTokenDefinition>) {
return [definition.underlyingTokenAddress];
}

async getPricePerShare({ appToken, multicall }: GetPricePerShareParams<AcrossV2PoolToken>) {
const hub = this.contractFactory.acrossV2HubPool({ address: this.hubAddress, network: this.network });
const poolInfo = await multicall.wrap(hub).pooledTokens(appToken.tokens[0].address);
const reserveRaw = poolInfo.liquidReserves.add(poolInfo.utilizedReserves).sub(poolInfo.undistributedLpFees);
const reserve = Number(reserveRaw) / 10 ** appToken.tokens[0].decimals;
return [reserve / appToken.supply];
}

async getLiquidity({ appToken }: GetDataPropsParams<AcrossV2PoolToken>) {
return appToken.supply * appToken.price;
}

async getReserves({ appToken }: GetDataPropsParams<AcrossV2PoolToken>) {
return [appToken.pricePerShare[0] * appToken.supply];
}

async getApy(_params: GetDataPropsParams<AcrossV2PoolToken>) {
return 0;
}

async getLabel({
appToken,
}: GetDisplayPropsParams<AcrossV2PoolToken, DefaultAppTokenDataProps, AcrossV2PoolTokenDefinition>): Promise<string> {
return `${getLabelFromToken(appToken.tokens[0])} Pool`;
}
}
Loading

0 comments on commit 4bf37ba

Please sign in to comment.