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

Commit

Permalink
feat(pooltogether): PoolTogether V5 Optimism Support (#2992)
Browse files Browse the repository at this point in the history
* PT V5 Optimism Support

* feat(pooltogether): PoolTogether V5 Optimism Support

* fix(pooltogether): added vaultfactory queries

---------

Co-authored-by: William Poulin <will@zapper.fi>
  • Loading branch information
Ncookiez and wpoulin committed Oct 24, 2023
1 parent 4eec004 commit ebb5882
Show file tree
Hide file tree
Showing 12 changed files with 616 additions and 0 deletions.
Binary file added src/apps/pool-together-v5/assets/logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,84 @@
import { Inject } from '@nestjs/common';

import { Erc4626 } from '~contract/contracts';
import { AppTokenTemplatePositionFetcher } from '~position/template/app-token.template.position-fetcher';
import { DefaultAppTokenDefinition, GetAddressesParams, GetDataPropsParams, GetDefinitionsParams, GetDisplayPropsParams, GetPricePerShareParams, GetUnderlyingTokensParams } from '~position/template/app-token.template.types';
import { PRIZE_VAULT_FACTORY_ADDRESSES } from './pool-together.v5.constants';
import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { PoolTogetherV5ContractFactory } from '../contracts';

export abstract class PoolTogetherV5PrizeVaultTokenFetcher extends AppTokenTemplatePositionFetcher<Erc4626> {
groupLabel: string;

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

getContract(address: string): Erc4626 {
return this.appToolkit.globalContracts.erc4626({ address, network: this.network });
}

async getAddresses({ definitions }: GetAddressesParams): Promise<string[]> {
return definitions.map(def => def.address);
}

async getDefinitions(params: GetDefinitionsParams): Promise<DefaultAppTokenDefinition[]> {
const { multicall } = params;

const vaultFactoryAddress = PRIZE_VAULT_FACTORY_ADDRESSES[this.network];

if(!!vaultFactoryAddress) {
const vaultFactory = multicall.wrap(
this.contractFactory.poolTogetherV5VaultFactory(
{ network: this.network, address: vaultFactoryAddress }
)
);

const totalVaults = Number(await vaultFactory.totalVaults());
const vaultIndexes = [...Array(totalVaults).keys()];

const vaultAddresses = await Promise.all(vaultIndexes.map(index => vaultFactory.allVaults(index)));

return vaultAddresses.map(address => ({ address }));
} else {
return []
}
}

async getUnderlyingTokenDefinitions({ contract }: GetUnderlyingTokensParams<Erc4626>) {
const underlyingToken = await contract.asset();
return [{ address: underlyingToken, network: this.network }];
}

async getPricePerShare({ contract, appToken }: GetPricePerShareParams<Erc4626>) {
const oneShare = BigInt(10 ** appToken.tokens[0].decimals);
const exchangeRate = (await contract.convertToAssets(oneShare)).toBigInt();
const pricePerShare = Number(exchangeRate / oneShare);
return [pricePerShare];
}

async getLiquidity({ contract, appToken }: GetDataPropsParams<Erc4626>) {
const reserveRaw = await contract.totalAssets();
const reserve = Number(reserveRaw) / 10 ** appToken.tokens[0].decimals;
const liquidity = reserve * appToken.tokens[0].price;
return liquidity;
}

async getReserves({ contract, appToken }: GetDataPropsParams<Erc4626>) {
const reserveRaw = await contract.totalAssets();
const reserve = Number(reserveRaw) / 10 ** appToken.tokens[0].decimals;
return [reserve];
}

async getLabel({ contract }: GetDisplayPropsParams<Erc4626>) {
return contract.name();
}

async getLabelDetailed({ appToken }: GetDisplayPropsParams<Erc4626>) {
return appToken.symbol;
}

}
@@ -0,0 +1,5 @@
import { Network } from "~types"

export const PRIZE_VAULT_FACTORY_ADDRESSES: Partial<Record<Network, `0x${string}`>> = {
[Network.OPTIMISM_MAINNET]: '0xF65FA202907D6046D1eF33C521889B54BdE08081'
}
@@ -0,0 +1,56 @@
[
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "contract Vault", "name": "vault", "type": "address" },
{ "indexed": true, "internalType": "contract VaultFactory", "name": "vaultFactory", "type": "address" }
],
"name": "NewFactoryVault",
"type": "event"
},
{
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"name": "allVaults",
"outputs": [{ "internalType": "contract Vault", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "contract IERC20", "name": "_asset", "type": "address" },
{ "internalType": "string", "name": "_name", "type": "string" },
{ "internalType": "string", "name": "_symbol", "type": "string" },
{ "internalType": "contract IERC4626", "name": "_yieldVault", "type": "address" },
{ "internalType": "contract PrizePool", "name": "_prizePool", "type": "address" },
{ "internalType": "address", "name": "_claimer", "type": "address" },
{ "internalType": "address", "name": "_yieldFeeRecipient", "type": "address" },
{ "internalType": "uint32", "name": "_yieldFeePercentage", "type": "uint32" },
{ "internalType": "address", "name": "_owner", "type": "address" }
],
"name": "deployVault",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "contract Vault", "name": "", "type": "address" }],
"name": "deployedVaults",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
"name": "deployerNonces",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalVaults",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
@@ -0,0 +1,218 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type {
BaseContract,
BigNumber,
BigNumberish,
BytesLike,
CallOverrides,
ContractTransaction,
Overrides,
PopulatedTransaction,
Signer,
utils,
} from 'ethers';
import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi';
import type { Listener, Provider } from '@ethersproject/providers';
import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent, PromiseOrValue } from './common';

export interface PoolTogetherV5VaultFactoryInterface extends utils.Interface {
functions: {
'allVaults(uint256)': FunctionFragment;
'deployVault(address,string,string,address,address,address,address,uint32,address)': FunctionFragment;
'deployedVaults(address)': FunctionFragment;
'deployerNonces(address)': FunctionFragment;
'totalVaults()': FunctionFragment;
};

getFunction(
nameOrSignatureOrTopic: 'allVaults' | 'deployVault' | 'deployedVaults' | 'deployerNonces' | 'totalVaults',
): FunctionFragment;

encodeFunctionData(functionFragment: 'allVaults', values: [PromiseOrValue<BigNumberish>]): string;
encodeFunctionData(
functionFragment: 'deployVault',
values: [
PromiseOrValue<string>,
PromiseOrValue<string>,
PromiseOrValue<string>,
PromiseOrValue<string>,
PromiseOrValue<string>,
PromiseOrValue<string>,
PromiseOrValue<string>,
PromiseOrValue<BigNumberish>,
PromiseOrValue<string>,
],
): string;
encodeFunctionData(functionFragment: 'deployedVaults', values: [PromiseOrValue<string>]): string;
encodeFunctionData(functionFragment: 'deployerNonces', values: [PromiseOrValue<string>]): string;
encodeFunctionData(functionFragment: 'totalVaults', values?: undefined): string;

decodeFunctionResult(functionFragment: 'allVaults', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'deployVault', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'deployedVaults', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'deployerNonces', data: BytesLike): Result;
decodeFunctionResult(functionFragment: 'totalVaults', data: BytesLike): Result;

events: {
'NewFactoryVault(address,address)': EventFragment;
};

getEvent(nameOrSignatureOrTopic: 'NewFactoryVault'): EventFragment;
}

export interface NewFactoryVaultEventObject {
vault: string;
vaultFactory: string;
}
export type NewFactoryVaultEvent = TypedEvent<[string, string], NewFactoryVaultEventObject>;

export type NewFactoryVaultEventFilter = TypedEventFilter<NewFactoryVaultEvent>;

export interface PoolTogetherV5VaultFactory extends BaseContract {
connect(signerOrProvider: Signer | Provider | string): this;
attach(addressOrName: string): this;
deployed(): Promise<this>;

interface: PoolTogetherV5VaultFactoryInterface;

queryFilter<TEvent extends TypedEvent>(
event: TypedEventFilter<TEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined,
): Promise<Array<TEvent>>;

listeners<TEvent extends TypedEvent>(eventFilter?: TypedEventFilter<TEvent>): Array<TypedListener<TEvent>>;
listeners(eventName?: string): Array<Listener>;
removeAllListeners<TEvent extends TypedEvent>(eventFilter: TypedEventFilter<TEvent>): this;
removeAllListeners(eventName?: string): this;
off: OnEvent<this>;
on: OnEvent<this>;
once: OnEvent<this>;
removeListener: OnEvent<this>;

functions: {
allVaults(arg0: PromiseOrValue<BigNumberish>, overrides?: CallOverrides): Promise<[string]>;

deployVault(
_asset: PromiseOrValue<string>,
_name: PromiseOrValue<string>,
_symbol: PromiseOrValue<string>,
_yieldVault: PromiseOrValue<string>,
_prizePool: PromiseOrValue<string>,
_claimer: PromiseOrValue<string>,
_yieldFeeRecipient: PromiseOrValue<string>,
_yieldFeePercentage: PromiseOrValue<BigNumberish>,
_owner: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> },
): Promise<ContractTransaction>;

deployedVaults(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<[boolean]>;

deployerNonces(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<[BigNumber]>;

totalVaults(overrides?: CallOverrides): Promise<[BigNumber]>;
};

allVaults(arg0: PromiseOrValue<BigNumberish>, overrides?: CallOverrides): Promise<string>;

deployVault(
_asset: PromiseOrValue<string>,
_name: PromiseOrValue<string>,
_symbol: PromiseOrValue<string>,
_yieldVault: PromiseOrValue<string>,
_prizePool: PromiseOrValue<string>,
_claimer: PromiseOrValue<string>,
_yieldFeeRecipient: PromiseOrValue<string>,
_yieldFeePercentage: PromiseOrValue<BigNumberish>,
_owner: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> },
): Promise<ContractTransaction>;

deployedVaults(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<boolean>;

deployerNonces(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<BigNumber>;

totalVaults(overrides?: CallOverrides): Promise<BigNumber>;

callStatic: {
allVaults(arg0: PromiseOrValue<BigNumberish>, overrides?: CallOverrides): Promise<string>;

deployVault(
_asset: PromiseOrValue<string>,
_name: PromiseOrValue<string>,
_symbol: PromiseOrValue<string>,
_yieldVault: PromiseOrValue<string>,
_prizePool: PromiseOrValue<string>,
_claimer: PromiseOrValue<string>,
_yieldFeeRecipient: PromiseOrValue<string>,
_yieldFeePercentage: PromiseOrValue<BigNumberish>,
_owner: PromiseOrValue<string>,
overrides?: CallOverrides,
): Promise<string>;

deployedVaults(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<boolean>;

deployerNonces(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<BigNumber>;

totalVaults(overrides?: CallOverrides): Promise<BigNumber>;
};

filters: {
'NewFactoryVault(address,address)'(
vault?: PromiseOrValue<string> | null,
vaultFactory?: PromiseOrValue<string> | null,
): NewFactoryVaultEventFilter;
NewFactoryVault(
vault?: PromiseOrValue<string> | null,
vaultFactory?: PromiseOrValue<string> | null,
): NewFactoryVaultEventFilter;
};

estimateGas: {
allVaults(arg0: PromiseOrValue<BigNumberish>, overrides?: CallOverrides): Promise<BigNumber>;

deployVault(
_asset: PromiseOrValue<string>,
_name: PromiseOrValue<string>,
_symbol: PromiseOrValue<string>,
_yieldVault: PromiseOrValue<string>,
_prizePool: PromiseOrValue<string>,
_claimer: PromiseOrValue<string>,
_yieldFeeRecipient: PromiseOrValue<string>,
_yieldFeePercentage: PromiseOrValue<BigNumberish>,
_owner: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> },
): Promise<BigNumber>;

deployedVaults(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<BigNumber>;

deployerNonces(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<BigNumber>;

totalVaults(overrides?: CallOverrides): Promise<BigNumber>;
};

populateTransaction: {
allVaults(arg0: PromiseOrValue<BigNumberish>, overrides?: CallOverrides): Promise<PopulatedTransaction>;

deployVault(
_asset: PromiseOrValue<string>,
_name: PromiseOrValue<string>,
_symbol: PromiseOrValue<string>,
_yieldVault: PromiseOrValue<string>,
_prizePool: PromiseOrValue<string>,
_claimer: PromiseOrValue<string>,
_yieldFeeRecipient: PromiseOrValue<string>,
_yieldFeePercentage: PromiseOrValue<BigNumberish>,
_owner: PromiseOrValue<string>,
overrides?: Overrides & { from?: PromiseOrValue<string> },
): Promise<PopulatedTransaction>;

deployedVaults(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<PopulatedTransaction>;

deployerNonces(arg0: PromiseOrValue<string>, overrides?: CallOverrides): Promise<PopulatedTransaction>;

totalVaults(overrides?: CallOverrides): Promise<PopulatedTransaction>;
};
}

0 comments on commit ebb5882

Please sign in to comment.