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

Commit

Permalink
fix(pool-together): Split PoolTogether app into v3 and v4 (#797)
Browse files Browse the repository at this point in the history
  • Loading branch information
wpoulin authored Jun 30, 2022
1 parent 7b566ae commit abbecd6
Show file tree
Hide file tree
Showing 78 changed files with 2,535 additions and 383 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@ import { presentBalanceFetcherResponse } from '~app-toolkit/helpers/presentation
import { BalanceFetcher } from '~balance/balance-fetcher.interface';
import { Network } from '~types/network.interface';

import { PoolTogetherClaimableTokenBalancesHelper } from '../helpers/pool-together-v3.claimable.balance-helper';
import { POOL_TOGETHER_DEFINITION } from '../pool-together.definition';
import { PoolTogetherV3ClaimableTokenBalancesHelper } from '../helpers/pool-together-v3.claimable.balance-helper';
import { POOL_TOGETHER_V3_DEFINITION } from '../pool-together-v3.definition';

const network = Network.CELO_MAINNET;

@Register.BalanceFetcher(POOL_TOGETHER_DEFINITION.id, network)
export class CeloPoolTogetherBalanceFetcher implements BalanceFetcher {
@Register.BalanceFetcher(POOL_TOGETHER_V3_DEFINITION.id, network)
export class CeloPoolTogetherV3BalanceFetcher implements BalanceFetcher {
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(PoolTogetherClaimableTokenBalancesHelper)
private readonly claimableTokenBalancesHelper: PoolTogetherClaimableTokenBalancesHelper,
@Inject(PoolTogetherV3ClaimableTokenBalancesHelper)
private readonly claimableTokenBalancesHelper: PoolTogetherV3ClaimableTokenBalancesHelper,
) {}

async getV3TokenBalances(address: string) {
async getTicketBalances(address: string) {
return this.appToolkit.helpers.tokenBalanceHelper.getTokenBalances({
network,
appId: POOL_TOGETHER_DEFINITION.id,
groupId: POOL_TOGETHER_DEFINITION.groups.v3.id,
appId: POOL_TOGETHER_V3_DEFINITION.id,
groupId: POOL_TOGETHER_V3_DEFINITION.groups.ticket.id,
address,
});
}
Expand All @@ -36,15 +36,15 @@ export class CeloPoolTogetherBalanceFetcher implements BalanceFetcher {
}

async getBalances(address: string) {
const [v3TokenBalances, claimableBalances] = await Promise.all([
this.getV3TokenBalances(address),
const [ticketBalances, claimableBalances] = await Promise.all([
this.getTicketBalances(address),
this.getClaimableBalances(address),
]);

return presentBalanceFetcherResponse([
{
label: 'Prize Pools',
assets: v3TokenBalances,
assets: ticketBalances,
},
{
label: 'Rewards',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { PoolTogetherV3ApiPrizePoolRegistry } from '../helpers/pool-together-v3.api.prize-pool-registry';
import { PoolTogetherV3PrizePoolTokenHelper } from '../helpers/pool-together-v3.prize-pool.token-helper';
import { PoolTogetherApiPrizePoolRegistry } from '../helpers/pool-together.api.prize-pool-registry';
import { POOL_TOGETHER_DEFINITION } from '../pool-together.definition';
import POOL_TOGETHER_V3_DEFINITION from '../pool-together-v3.definition';

const appId = POOL_TOGETHER_DEFINITION.id;
const groupId = POOL_TOGETHER_DEFINITION.groups.v3.id;
const appId = POOL_TOGETHER_V3_DEFINITION.id;
const groupId = POOL_TOGETHER_V3_DEFINITION.groups.ticket.id;
const network = Network.CELO_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network, options: { includeInTvl: true } })
export class CeloPoolTogetherV3TicketTokenFetcher implements PositionFetcher<AppTokenPosition> {
constructor(
@Inject(PoolTogetherV3PrizePoolTokenHelper)
private readonly poolTogetherV3PrizePoolTokenHelper: PoolTogetherV3PrizePoolTokenHelper,
@Inject(PoolTogetherApiPrizePoolRegistry) private readonly prizePoolRegistry: PoolTogetherApiPrizePoolRegistry,
@Inject(PoolTogetherV3ApiPrizePoolRegistry) private readonly prizePoolRegistry: PoolTogetherV3ApiPrizePoolRegistry,
) {}

async getPositions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ export { PoolTogetherV3PodRegistry__factory } from './PoolTogetherV3PodRegistry_
export { PoolTogetherV3PrizePool__factory } from './PoolTogetherV3PrizePool__factory';
export { PoolTogetherV3Ticket__factory } from './PoolTogetherV3Ticket__factory';
export { PoolTogetherV3TokenFaucet__factory } from './PoolTogetherV3TokenFaucet__factory';
export { PoolTogetherV4PrizePool__factory } from './PoolTogetherV4PrizePool__factory';
export { PoolTogetherV4Ticket__factory } from './PoolTogetherV4Ticket__factory';
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ export type { PoolTogetherV3PodRegistry } from './PoolTogetherV3PodRegistry';
export type { PoolTogetherV3PrizePool } from './PoolTogetherV3PrizePool';
export type { PoolTogetherV3Ticket } from './PoolTogetherV3Ticket';
export type { PoolTogetherV3TokenFaucet } from './PoolTogetherV3TokenFaucet';
export type { PoolTogetherV4PrizePool } from './PoolTogetherV4PrizePool';
export type { PoolTogetherV4Ticket } from './PoolTogetherV4Ticket';
export * as factories from './factories';
export { PoolTogetherMerkleDistributor__factory } from './factories/PoolTogetherMerkleDistributor__factory';
export { PoolTogetherV3MultiTokenListener__factory } from './factories/PoolTogetherV3MultiTokenListener__factory';
Expand All @@ -20,5 +18,3 @@ export { PoolTogetherV3Pod__factory } from './factories/PoolTogetherV3Pod__facto
export { PoolTogetherV3PrizePool__factory } from './factories/PoolTogetherV3PrizePool__factory';
export { PoolTogetherV3Ticket__factory } from './factories/PoolTogetherV3Ticket__factory';
export { PoolTogetherV3TokenFaucet__factory } from './factories/PoolTogetherV3TokenFaucet__factory';
export { PoolTogetherV4PrizePool__factory } from './factories/PoolTogetherV4PrizePool__factory';
export { PoolTogetherV4Ticket__factory } from './factories/PoolTogetherV4Ticket__factory';
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ import { PoolTogetherV3PodRegistry__factory } from './ethers';
import { PoolTogetherV3PrizePool__factory } from './ethers';
import { PoolTogetherV3Ticket__factory } from './ethers';
import { PoolTogetherV3TokenFaucet__factory } from './ethers';
import { PoolTogetherV4PrizePool__factory } from './ethers';
import { PoolTogetherV4Ticket__factory } from './ethers';

// eslint-disable-next-line
type ContractOpts = { address: string; network: Network };

@Injectable()
export class PoolTogetherContractFactory extends ContractFactory {
export class PoolTogetherV3ContractFactory extends ContractFactory {
constructor(@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit) {
super((network: Network) => appToolkit.getNetworkProvider(network));
}
Expand Down Expand Up @@ -51,12 +49,6 @@ export class PoolTogetherContractFactory extends ContractFactory {
poolTogetherV3TokenFaucet({ address, network }: ContractOpts) {
return PoolTogetherV3TokenFaucet__factory.connect(address, this.appToolkit.getNetworkProvider(network));
}
poolTogetherV4PrizePool({ address, network }: ContractOpts) {
return PoolTogetherV4PrizePool__factory.connect(address, this.appToolkit.getNetworkProvider(network));
}
poolTogetherV4Ticket({ address, network }: ContractOpts) {
return PoolTogetherV4Ticket__factory.connect(address, this.appToolkit.getNetworkProvider(network));
}
}

export type { PoolTogetherMerkleDistributor } from './ethers';
Expand All @@ -67,5 +59,3 @@ export type { PoolTogetherV3PodRegistry } from './ethers';
export type { PoolTogetherV3PrizePool } from './ethers';
export type { PoolTogetherV3Ticket } from './ethers';
export type { PoolTogetherV3TokenFaucet } from './ethers';
export type { PoolTogetherV4PrizePool } from './ethers';
export type { PoolTogetherV4Ticket } from './ethers';
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Inject } from '@nestjs/common';

import { IAppToolkit, APP_TOOLKIT } 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 { Network } from '~types/network.interface';

import { PoolTogetherV3AirdropTokenBalancesHelper } from '../helpers/pool-together-v3.airdrop.balance-helper';
import { PoolTogetherV3ClaimableTokenBalancesHelper } from '../helpers/pool-together-v3.claimable.balance-helper';
import { POOL_TOGETHER_V3_DEFINITION } from '../pool-together-v3.definition';

const network = Network.ETHEREUM_MAINNET;

@Register.BalanceFetcher(POOL_TOGETHER_V3_DEFINITION.id, network)
export class EthereumPoolTogetherV3BalanceFetcher implements BalanceFetcher {
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(PoolTogetherV3ClaimableTokenBalancesHelper)
private readonly claimableTokenBalancesHelper: PoolTogetherV3ClaimableTokenBalancesHelper,
@Inject(PoolTogetherV3AirdropTokenBalancesHelper)
private readonly airdropTokenBalancesHelper: PoolTogetherV3AirdropTokenBalancesHelper,
) {}

async getTicketBalances(address: string) {
return this.appToolkit.helpers.tokenBalanceHelper.getTokenBalances({
network,
appId: POOL_TOGETHER_V3_DEFINITION.id,
groupId: POOL_TOGETHER_V3_DEFINITION.groups.ticket.id,
address,
});
}

async getPodTokenBalances(address: string) {
return this.appToolkit.helpers.tokenBalanceHelper.getTokenBalances({
network,
appId: POOL_TOGETHER_V3_DEFINITION.id,
groupId: POOL_TOGETHER_V3_DEFINITION.groups.pod.id,
address,
});
}

async getClaimableBalances(address: string) {
return this.claimableTokenBalancesHelper.getBalances({
address,
network,
});
}

async getAirdropBalances(address: string) {
return this.airdropTokenBalancesHelper.getBalances({
address,
network,
});
}

async getBalances(address: string) {
const [ticketBalances, podTokenBalances, claimableBalances, airdropBalances] = await Promise.all([
this.getTicketBalances(address),
this.getPodTokenBalances(address),
this.getClaimableBalances(address),
this.getAirdropBalances(address),
]);

return presentBalanceFetcherResponse([
{
label: 'Prize Pools',
assets: ticketBalances,
},
{
label: 'Prize Pods',
assets: podTokenBalances,
},
{
label: 'Rewards',
assets: claimableBalances,
},
{
label: 'Airdrops',
assets: airdropBalances,
},
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { PoolTogetherV3PodTokenHelper } from '../helpers/pool-together-v3.pod.token-helper';
import { POOL_TOGETHER_DEFINITION } from '../pool-together.definition';
import { POOL_TOGETHER_V3_DEFINITION } from '../pool-together-v3.definition';

const appId = POOL_TOGETHER_DEFINITION.id;
const groupId = POOL_TOGETHER_DEFINITION.groups.v3Pod.id;
const appId = POOL_TOGETHER_V3_DEFINITION.id;
const groupId = POOL_TOGETHER_V3_DEFINITION.groups.pod.id;
const network = Network.ETHEREUM_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network, options: { includeInTvl: true } })
export class EthereumPoolTogetherPodTokenFetcher implements PositionFetcher<AppTokenPosition> {
export class EthereumPoolTogetherV3PodTokenFetcher implements PositionFetcher<AppTokenPosition> {
constructor(
@Inject(PoolTogetherV3PodTokenHelper)
private readonly poolTogetherV3PodTokenHelper: PoolTogetherV3PodTokenHelper,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { PoolTogetherV3ApiPrizePoolRegistry } from '../helpers/pool-together-v3.api.prize-pool-registry';
import { PoolTogetherV3PrizePoolTokenHelper } from '../helpers/pool-together-v3.prize-pool.token-helper';
import { PoolTogetherApiPrizePoolRegistry } from '../helpers/pool-together.api.prize-pool-registry';
import { POOL_TOGETHER_DEFINITION } from '../pool-together.definition';
import { POOL_TOGETHER_V3_DEFINITION } from '../pool-together-v3.definition';

const appId = POOL_TOGETHER_DEFINITION.id;
const groupId = POOL_TOGETHER_DEFINITION.groups.v3.id;
const appId = POOL_TOGETHER_V3_DEFINITION.id;
const groupId = POOL_TOGETHER_V3_DEFINITION.groups.ticket.id;
const network = Network.ETHEREUM_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network, options: { includeInTvl: true } })
export class EthereumPoolTogetherV3TicketTokenFetcher implements PositionFetcher<AppTokenPosition> {
constructor(
@Inject(PoolTogetherV3PrizePoolTokenHelper)
private readonly poolTogetherV3PrizePoolTokenHelper: PoolTogetherV3PrizePoolTokenHelper,
@Inject(PoolTogetherApiPrizePoolRegistry) private readonly prizePoolRegistry: PoolTogetherApiPrizePoolRegistry,
@Inject(PoolTogetherV3ApiPrizePoolRegistry) private readonly prizePoolRegistry: PoolTogetherV3ApiPrizePoolRegistry,
) {}

async getPositions() {
Expand All @@ -35,8 +35,8 @@ export class EthereumPoolTogetherV3TicketTokenFetcher implements PositionFetcher
network,
},
{
appId: POOL_TOGETHER_DEFINITION.id,
groupIds: [POOL_TOGETHER_DEFINITION.groups.v3.id], // For pPOOL drip
appId: POOL_TOGETHER_V3_DEFINITION.id,
groupIds: [POOL_TOGETHER_V3_DEFINITION.groups.ticket.id], // For pPOOL drip
network,
},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Inject } from '@nestjs/common';
import axios from 'axios';
import { ethers } from 'ethers';

import { drillBalance } from '~app-toolkit';
import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { buildDollarDisplayItem } from '~app-toolkit/helpers/presentation/display-item.present';
import { getTokenImg } from '~app-toolkit/helpers/presentation/image.present';
import { ContractType } from '~position/contract.interface';
import { ContractPositionBalance } from '~position/position-balance.interface';
import { Network } from '~types/network.interface';

import { PoolTogetherV3ContractFactory } from '../contracts';
import { POOL_TOGETHER_V3_DEFINITION } from '../pool-together-v3.definition';

type GetAirdropTokenBalanceParams = {
address: string;
network: Network;
airDropAddressDataUrl?: string;
airDropToken?: string;
};

export class PoolTogetherV3AirdropTokenBalancesHelper {
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(PoolTogetherV3ContractFactory) private readonly contractFactory: PoolTogetherV3ContractFactory,
) {}

async getBalances({ address, network, airDropAddressDataUrl }: GetAirdropTokenBalanceParams) {
const baseTokens = await this.appToolkit.getBaseTokenPrices(network);

const checksumAddress = ethers.utils.getAddress(address); // Checksum
const url = `${airDropAddressDataUrl}?address=${checksumAddress}`;
const merkleResponseData = await axios
.get<{ index: number; amount: string; proof: string[] }>(url)
.then(({ data }) => data)
.catch(() => null);
if (!merkleResponseData) return [];

const merkleAddress = '0xbe1a33519f586a4c8aa37525163df8d67997016f';
const distributorContract = this.contractFactory.poolTogetherMerkleDistributor({ address: merkleAddress, network });
const isClaimed = await distributorContract.isClaimed(merkleResponseData.index);
if (isClaimed) return [];

const claimableToken = baseTokens.find(p => p.symbol === 'POOL');
if (!claimableToken) return [];

const claimableBalanceRaw = String(parseInt(merkleResponseData.amount, 16));
const claimableTokenBalance = drillBalance(claimableToken, claimableBalanceRaw);
const tokens = [claimableTokenBalance];
const balanceUSD = claimableTokenBalance.balanceUSD;

// Display Props
const label = `Claimable ${claimableToken.symbol}`;
const secondaryLabel = buildDollarDisplayItem(claimableToken.price);
const images = [getTokenImg(claimableToken.address, network)];

const positionBalance: ContractPositionBalance = {
type: ContractType.POSITION,
address: merkleAddress,
appId: POOL_TOGETHER_V3_DEFINITION.id,
groupId: POOL_TOGETHER_V3_DEFINITION.groups.claimable.id,
network,
tokens,
balanceUSD,

dataProps: {},

displayProps: {
label,
secondaryLabel,
images,
},
};

return [positionBalance];
}
}
Loading

0 comments on commit abbecd6

Please sign in to comment.