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

Commit

Permalink
Merge branch 'main' into add-looksrare-staking-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
wpoulin authored Dec 13, 2023
2 parents 8b1a8d7 + 58fbb3f commit 3f3fc81
Show file tree
Hide file tree
Showing 105 changed files with 58 additions and 13,105 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@

[1]: https://www.npmjs.com/package/@zapper-fi/studio?activeTab=versions

## [0.566.0](https://github.com/Zapper-fi/studio/compare/v0.565.0...v0.566.0) (2023-12-12)


### Features

* **polygon-staking:** Remove subgraph dependency, change contract position addresses to help with interactions indexing ([#3139](https://github.com/Zapper-fi/studio/issues/3139)) ([0f2753e](https://github.com/Zapper-fi/studio/commit/0f2753e49931495eb69cc6647c97317aaf0d16ea))

## [0.565.0](https://github.com/Zapper-fi/studio/compare/v0.564.2...v0.565.0) (2023-12-12)


### Features

* **studio:** Move Synthetix to a private module ([#3137](https://github.com/Zapper-fi/studio/issues/3137)) ([d5fe616](https://github.com/Zapper-fi/studio/commit/d5fe6165ba87d796bb2e770f7033a4724ed4e6f5))

## [0.564.2](https://github.com/Zapper-fi/studio/compare/v0.564.1...v0.564.2) (2023-12-12)


### Bug Fixes

* **dhedge-v2:** Early return if position has been unstaked ([#3134](https://github.com/Zapper-fi/studio/issues/3134)) ([629814b](https://github.com/Zapper-fi/studio/commit/629814bd2d0d0e94a5a9b59e7cb892f0347340b8))

## [0.564.1](https://github.com/Zapper-fi/studio/compare/v0.564.0...v0.564.1) (2023-12-12)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zapper-fi/studio",
"version": "0.564.1",
"version": "0.566.0",
"description": "Community build apps for Zapper.fi",
"license": "MIT",
"main": "./index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export abstract class DhedgeV2StakingContractPositionFetcher extends CustomContr
const matchingPosition = contractPositions.find(x =>
x.tokens.find(x => x.address == lpTokenAddress.toLowerCase()),
);
if (!matchingPosition) return null;
if (!matchingPosition || suppliedBalances[6] == true) return null;

const suppliedDht = suppliedBalances[0];
const suppliedLp = suppliedBalances[3];
Expand Down
4 changes: 4 additions & 0 deletions src/apps/inverse/contracts/viem.contract-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
InverseDcaVaultToken__factory,
InverseLendingPool__factory,
InverseLens__factory,
InverseStaking__factory,
} from './viem';

type ContractOpts = { address: string; network: Network };
Expand All @@ -28,4 +29,7 @@ export class InverseViemContractFactory {
inverseLens({ address, network }: ContractOpts) {
return InverseLens__factory.connect(address, this.appToolkit.getViemNetworkProvider(network));
}
inverseStaking({ address, network }: ContractOpts) {
return InverseStaking__factory.connect(address, this.appToolkit.getViemNetworkProvider(network));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/* eslint-disable */
import { getContract, GetContractReturnType, PublicClient } from 'viem';

export const synthetixRewardsAbi = [
export const inverseStakingAbi = [
{
constant: true,
inputs: [
Expand Down Expand Up @@ -427,11 +427,11 @@ export const synthetixRewardsAbi = [
},
] as const;

export type SynthetixRewards = typeof synthetixRewardsAbi;
export type SynthetixRewardsContract = GetContractReturnType<SynthetixRewards, PublicClient>;
export type InverseStaking = typeof inverseStakingAbi;
export type InverseStakingContract = GetContractReturnType<InverseStaking, PublicClient>;

export class SynthetixRewards__factory {
export class InverseStaking__factory {
static connect(address: string, client: PublicClient) {
return getContract({ address, abi: synthetixRewardsAbi, publicClient: client });
return getContract({ address, abi: inverseStakingAbi, publicClient: client });
}
}
2 changes: 2 additions & 0 deletions src/apps/inverse/contracts/viem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ export type { InverseController } from './InverseController';
export type { InverseDcaVaultToken } from './InverseDcaVaultToken';
export type { InverseLendingPool } from './InverseLendingPool';
export type { InverseLens } from './InverseLens';
export type { InverseStaking } from './InverseStaking';

export { InverseController__factory } from './InverseController';
export { InverseDcaVaultToken__factory } from './InverseDcaVaultToken';
export { InverseLendingPool__factory } from './InverseLendingPool';
export { InverseLens__factory } from './InverseLens';
export { InverseStaking__factory } from './InverseStaking';
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { Inject } from '@nestjs/common';

import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator';
import { SynthetixViemContractFactory } from '~apps/synthetix/contracts';
import { SynthetixRewards } from '~apps/synthetix/contracts/viem';
import { GetDataPropsParams, GetTokenBalancesParams } from '~position/template/contract-position.template.types';
import {
SingleStakingFarmDefinition,
SingleStakingFarmTemplateContractPositionFetcher,
} from '~position/template/single-staking.template.contract-position-fetcher';

import { InverseViemContractFactory } from '../contracts';
import { InverseStaking } from '../contracts/viem';

const FARMS = [
// DOLA 3CRV Curve
{
Expand All @@ -20,37 +21,37 @@ const FARMS = [
];

@PositionTemplate()
export class EthereumInverseFarmContractPositionFetcher extends SingleStakingFarmTemplateContractPositionFetcher<SynthetixRewards> {
export class EthereumInverseFarmContractPositionFetcher extends SingleStakingFarmTemplateContractPositionFetcher<InverseStaking> {
groupLabel = 'Farms';

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

getContract(address: string) {
return this.contractFactory.synthetixRewards({ address, network: this.network });
return this.contractFactory.inverseStaking({ address, network: this.network });
}

async getFarmDefinitions(): Promise<SingleStakingFarmDefinition[]> {
return FARMS;
}

async getRewardRates({ contract }: GetDataPropsParams<SynthetixRewards>) {
async getRewardRates({ contract }: GetDataPropsParams<InverseStaking>) {
return contract.read.rewardRate();
}

async getIsActive({ contract }: GetDataPropsParams<SynthetixRewards>): Promise<boolean> {
async getIsActive({ contract }: GetDataPropsParams<InverseStaking>): Promise<boolean> {
return (await contract.read.rewardRate()) > 0;
}

async getStakedTokenBalance({ address, contract }: GetTokenBalancesParams<SynthetixRewards>) {
async getStakedTokenBalance({ address, contract }: GetTokenBalancesParams<InverseStaking>) {
return contract.read.balanceOf([address]);
}

async getRewardTokenBalances({ address, contract }: GetTokenBalancesParams<SynthetixRewards>) {
async getRewardTokenBalances({ address, contract }: GetTokenBalancesParams<InverseStaking>) {
return contract.read.earned([address]);
}
}
2 changes: 0 additions & 2 deletions src/apps/inverse/inverse.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Module } from '@nestjs/common';

import { AbstractApp } from '~app/app.dynamic-module';
import { SynthetixViemContractFactory } from '~apps/synthetix/contracts';

import { InverseViemContractFactory } from './contracts';
import { EthereumInverseBorrowContractPositionFetcher } from './ethereum/inverse.borrow.contract-position-fetcher';
Expand All @@ -14,7 +13,6 @@ import { EthereumInverseSupplyTokenFetcher } from './ethereum/inverse.supply.tok
@Module({
providers: [
InverseViemContractFactory,
SynthetixViemContractFactory,
EthereumInverseBorrowContractPositionFetcher,
EthereumInverseClaimableContractPositionFetcher,
EthereumInverseDcaVaultTokenFetcher,
Expand Down
3 changes: 0 additions & 3 deletions src/apps/kwenta/kwenta.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { Module } from '@nestjs/common';

import { AbstractApp } from '~app/app.dynamic-module';

import { SynthetixViemContractFactory } from '../synthetix/contracts';

import { KwentaViemContractFactory } from './contracts';
import { OptimismKwentaEscrowV2ContractPositionFetcher } from './optimism/kwenta.escrow-v2.contract-position-fetcher';
import { OptimismKwentaEscrowContractPositionFetcher } from './optimism/kwenta.escrow.contract-position-fetcher';
Expand All @@ -15,7 +13,6 @@ import { OptimismKwentaStakingContractPositionFetcher } from './optimism/kwenta.
@Module({
providers: [
KwentaViemContractFactory,
SynthetixViemContractFactory,
OptimismKwentaPerpV1CrossMarginContractPositionFetcher,
OptimismKwentaPerpV2SmartMarginContractPositionFetcher,
OptimismKwentaStakingContractPositionFetcher,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { PositionTemplate } from '~app-toolkit/decorators/position-template.deco
import { drillBalance } from '~app-toolkit/helpers/drill-balance.helper';
import { getAppAssetImage } from '~app-toolkit/helpers/presentation/image.present';
import { gqlFetch } from '~app-toolkit/helpers/the-graph.helper';
import { SynthetixPerp } from '~apps/synthetix/contracts/viem';
import { ContractType } from '~position/contract.interface';
import { ContractPositionBalance } from '~position/position-balance.interface';
import { MetaType } from '~position/position.interface';
Expand Down Expand Up @@ -64,7 +63,7 @@ export class OptimismKwentaPerpV1CrossMarginContractPositionFetcher extends Cust
throw new Error('Method not implemented.');
}

async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams<SynthetixPerp>) {
async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams<KwentaPerp>) {
const remainingMargin = await contract.read.remainingMargin([address]);
return [remainingMargin[0]];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import { Inject } from '@nestjs/common';
import axios from 'axios';
import { gql } from 'graphql-request';
import { compact, sumBy } from 'lodash';

import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { PositionTemplate } from '~app-toolkit/decorators/position-template.decorator';
import { drillBalance } from '~app-toolkit/helpers/drill-balance.helper';
import { getImagesFromToken, getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { gqlFetchAll } from '~app-toolkit/helpers/the-graph.helper';
import { CacheOnInterval } from '~cache/cache-on-interval.decorator';
import { ContractPositionBalance } from '~position/position-balance.interface';
import { MetaType } from '~position/position.interface';
import { isClaimable, isSupplied } from '~position/position.utils';
import { ContractPositionTemplatePositionFetcher } from '~position/template/contract-position.template.position-fetcher';
import {
GetTokenDefinitionsParams,
GetDisplayPropsParams,
GetTokenBalancesParams,
GetDataPropsParams,
} from '~position/template/contract-position.template.types';
import { CustomContractPositionTemplatePositionFetcher } from '~position/template/custom-contract-position.template.position-fetcher';

import { PolygonStakingViemContractFactory } from '../contracts';
import { PolygonStakeManager } from '../contracts/viem/PolygonStakeManager';
import { PolygonValidatorShare } from '../contracts/viem';

type ValidatorsResponse = {
result: {
Expand Down Expand Up @@ -50,41 +44,20 @@ type ValidatorsResponse = {
}[];
};

type DelegatedMaticResponse = {
delegators: {
validatorId: string;
delegatedAmount: string;
}[];
};

const GQL_ENDPOINT = `https://api.thegraph.com/subgraphs/name/maticnetwork/mainnet-root-subgraphs?source=zapper`;

const DELEGATED_MATIC_QUERY = gql`
query getDelegatedMatic($address: String!, $first: Int, $lastId: String) {
delegators(where: { address: $address, id_gt: $lastId }, first: $first) {
validatorId
delegatedAmount
}
}
`;

type PolygonStakingDepositDefinition = {
address: string;
address: string; // share address
validatorId: number;
validatorName: string;
validatorShareAddress: string;
};

type PolygonStakingDepositDataProps = {
validatorId: number;
validatorName: string;
validatorShareAddress: string;
positionKey: string;
};

@PositionTemplate()
export class EthereumPolygonStakingContractPositionFetcher extends CustomContractPositionTemplatePositionFetcher<
PolygonStakeManager,
export class EthereumPolygonStakingContractPositionFetcher extends ContractPositionTemplatePositionFetcher<
PolygonValidatorShare,
PolygonStakingDepositDataProps,
PolygonStakingDepositDefinition
> {
Expand All @@ -109,21 +82,20 @@ export class EthereumPolygonStakingContractPositionFetcher extends CustomContrac
}

getContract(address: string) {
return this.contractFactory.polygonStakeManager({ address, network: this.network });
return this.contractFactory.polygonValidatorShare({ address, network: this.network });
}

async getDefinitions() {
const validators = await this.getValidators();

return validators.result.map(validator => ({
address: '0x5e3ef299fddf15eaa0432e6e66473ace8c13d908',
address: validator.contractAddress,
validatorId: validator.id,
validatorName: validator.name,
validatorShareAddress: validator.contractAddress,
}));
}

async getTokenDefinitions(_params: GetTokenDefinitionsParams<PolygonStakeManager>) {
async getTokenDefinitions(_params: GetTokenDefinitionsParams<PolygonValidatorShare>) {
return [
{
metaType: MetaType.SUPPLIED,
Expand All @@ -141,82 +113,23 @@ export class EthereumPolygonStakingContractPositionFetcher extends CustomContrac

async getDataProps({
definition,
}: GetDataPropsParams<PolygonStakeManager, PolygonStakingDepositDataProps, PolygonStakingDepositDefinition>) {
}: GetDataPropsParams<PolygonValidatorShare, PolygonStakingDepositDataProps, PolygonStakingDepositDefinition>) {
return {
validatorId: definition.validatorId,
validatorName: definition.validatorName,
validatorShareAddress: definition.validatorShareAddress,
positionKey: `${definition.validatorId}`,
};
}

async getLabel({ contractPosition }: GetDisplayPropsParams<PolygonStakeManager, PolygonStakingDepositDataProps>) {
async getLabel({ contractPosition }: GetDisplayPropsParams<PolygonValidatorShare, PolygonStakingDepositDataProps>) {
const validatorLabel = `${contractPosition.dataProps.validatorName} (ID: ${contractPosition.dataProps.validatorId})`;
return `Delegated ${getLabelFromToken(contractPosition.tokens[0])}: ${validatorLabel}`;
}

async getImages({ contractPosition }: GetDisplayPropsParams<PolygonStakeManager>) {
async getImages({ contractPosition }: GetDisplayPropsParams<PolygonValidatorShare>) {
return getImagesFromToken(contractPosition.tokens[0]);
}

// @ts-ignore
async getTokenBalancesPerPosition(_params: GetTokenBalancesParams<PolygonStakeManager>) {
throw new Error('Method not implemented.');
}

async getBalances(address: string): Promise<ContractPositionBalance<PolygonStakingDepositDataProps>[]> {
const multicall = this.appToolkit.getViemMulticall(this.network);

const data = await gqlFetchAll<DelegatedMaticResponse>({
endpoint: GQL_ENDPOINT,
query: DELEGATED_MATIC_QUERY,
dataToSearch: 'delegators',
variables: {
address: address.toLowerCase(),
},
});

const positions = await this.appToolkit.getAppContractPositions<PolygonStakingDepositDataProps>({
network: this.network,
appId: this.appId,
groupIds: [this.groupId],
});

const balances = await Promise.all(
data.delegators.map(async delegator => {
const position = positions.find(v => v.dataProps.validatorId === Number(delegator.validatorId));
if (!position) return null;

const contract = this.contractFactory.polygonValidatorShare({
address: position.dataProps.validatorShareAddress,
network: this.network,
});

const [balanceRaw, claimableBalanceRaw] = await Promise.all([
multicall.wrap(contract).read.balanceOf([address]),
multicall.wrap(contract).read.getLiquidRewards([address]),
]);

const suppliedToken = position.tokens.find(isSupplied)!;
const claimableToken = position.tokens.find(isClaimable)!;
if (!suppliedToken || !claimableToken) return null;

const tokens = [
drillBalance(suppliedToken, balanceRaw.toString()),
drillBalance(claimableToken, claimableBalanceRaw.toString()),
];

const balanceUSD = sumBy(tokens, v => v.balanceUSD);
const balance: ContractPositionBalance<PolygonStakingDepositDataProps> = {
...position,
tokens,
balanceUSD,
};

return balance;
}),
);

return compact(balances);
async getTokenBalancesPerPosition({ address, contract }: GetTokenBalancesParams<PolygonValidatorShare>) {
return Promise.all([contract.read.balanceOf([address]), contract.read.getLiquidRewards([address])]);
}
}
Loading

0 comments on commit 3f3fc81

Please sign in to comment.