Skip to content

Commit

Permalink
Update SOR buffers to use unwrapRate from erc4626 tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoguerios committed Dec 20, 2024
1 parent c80691d commit 5ba5c15
Show file tree
Hide file tree
Showing 33 changed files with 1,218 additions and 1,216 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-adults-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'backend': minor
---

Update SOR buffers to use unwrapRate from erc4626 tokens
4 changes: 4 additions & 0 deletions apps/api/gql/schema/token.gql
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ type GqlToken {
"""
isBufferAllowed: Boolean!
"""
If it is an ERC4626 token, it represents the rate between wrapped/underlying.
"""
unwrapRate: BigDecimal!
"""
The ERC4626 review data for the token
"""
erc4626ReviewData: Erc4626ReviewData
Expand Down
5 changes: 5 additions & 0 deletions graphql_schema_generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3221,6 +3221,11 @@ export const schema = gql`
"""
underlyingTokenAddress: String
"""
If it is an ERC4626 token, it represents the rate between wrapped/underlying.
"""
unwrapRate: BigDecimal!
"""
The website URL of the token
"""
Expand Down
16 changes: 15 additions & 1 deletion modules/actions/pool/v3/upsert-pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { prisma } from '../../../../prisma/prisma-client';
import { tokensTransformer } from '../../../sources/transformers/tokens-transformer';
import { V3JoinedSubgraphPool } from '../../../sources/subgraphs';
import { enrichPoolUpsertsUsd } from '../../../sources/enrichers/pool-upserts-usd';
import type { VaultClient } from '../../../sources/contracts';
import { type VaultClient } from '../../../sources/contracts';
import { poolUpsertTransformerV3 } from '../../../sources/transformers/pool-upsert-transformer-v3';
import { applyOnchainDataUpdateV3 } from '../../../sources/enrichers/apply-onchain-data';
import { fetchErc4626AndUnderlyingTokenData } from '../../../sources/contracts/fetch-erc4626-token-data';
Expand Down Expand Up @@ -68,6 +68,20 @@ export const upsertPools = async (
type: 'ERC4626',
},
});
await prisma.prismaToken.upsert({
where: {
address_chain: {
address: token.address,
chain,
},
},
create: {
...token,
},
update: {
...token,
},
});
}
}

Expand Down
4 changes: 2 additions & 2 deletions modules/actions/token/sync-erc4626-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export const syncErc4626Tokens = async (viemClient: ViemClient, chain: Chain) =>
},
});

const erc4626AndUnderlying = await fetchErc4626AndUnderlyingTokenData(allTokens, viemClient);
const enrichedTokensWithErc4626Data = await fetchErc4626AndUnderlyingTokenData(allTokens, viemClient);

for (const token of erc4626AndUnderlying) {
for (const token of enrichedTokensWithErc4626Data) {
await prisma.prismaToken.upsert({
where: {
address_chain: {
Expand Down
11 changes: 5 additions & 6 deletions modules/sor/sor-debug.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,23 @@ describe('sor debugging', () => {
expect(parseFloat(swaps.returnAmount)).toBeGreaterThan(0);
}, 5000000);

it('sor v3 mainnet wusdl -> csusdl', async () => {
it.only('sor v3 mainnet wstETH -> waGnowstETH', async () => {
const chain = Chain.MAINNET;

const chainId = Object.keys(chainIdToChain).find((key) => chainIdToChain[key] === chain) as string;
initRequestScopedContext();
setRequestScopedContextValue('chainId', chainId);
//only do once before starting to debug
await PoolController().reloadPoolsV3(chain);
await PoolController().updateLiquidityValuesForActivePools(chain);

const swaps = await sorService.getSorSwapPaths({
chain,
tokenIn: '0x7751e2f4b8ae93ef6b79d86419d42fe3295a4559', // wusdl
tokenOut: '0xbeefc01767ed5086f35decb6c00e6c12bc7476c1', // csusdl
tokenIn: '0xbeef01735c132ada46aa9aa4c54623caa92a64cb', // steakUSDC 18 decimals
tokenOut: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC 6 decimals
swapType: 'EXACT_IN',
swapAmount: '10',
swapAmount: '1',
useProtocolVersion: 3,
// poolIds: ['0xbeefc01767ed5086f35decb6c00e6c12bc7476c1'], // buffer
poolIds: ['0x5dd88b3aa3143173eb26552923922bdf33f50949'], // boosted
});

console.log(swaps.returnAmount);
Expand Down
11 changes: 10 additions & 1 deletion modules/sor/sorV2/lib/poolsV2/erc4626PoolToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@ import { BasePoolToken } from './basePoolToken';

export class Erc4626PoolToken extends BasePoolToken {
public readonly rate: bigint;
public readonly unwrapRate: bigint;
public readonly underlyingTokenAddress: string;

public constructor(token: Token, amount: BigintIsh, index: number, rate: bigint, underlyingTokenAddress: string) {
public constructor(
token: Token,
amount: BigintIsh,
index: number,
rate: bigint,
unwrapRate: bigint,
underlyingTokenAddress: string,
) {
super(token, amount, index);
this.rate = rate;
this.unwrapRate = unwrapRate;
this.underlyingTokenAddress = underlyingTokenAddress;
}

Expand Down
2 changes: 1 addition & 1 deletion modules/sor/sorV2/lib/poolsV3/buffer/bufferPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class BufferPool implements BasePoolV3 {
erc4626Token.token.address,
erc4626Token.token.address,
erc4626Token.token.chainId,
erc4626Token.rate,
erc4626Token.unwrapRate,
mainToken,
underlyingToken,
);
Expand Down
1 change: 1 addition & 0 deletions modules/sor/sorV2/lib/poolsV3/stable/stablePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class StablePool implements BasePoolV3 {
tokenAmount.amount,
poolToken.index,
parseEther(poolToken.priceRate),
parseEther(poolToken.token.unwrapRate),
poolToken.token.underlyingTokenAddress,
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ export class WeightedErc4626PoolToken extends Erc4626PoolToken {
amount: BigintIsh,
index: number,
rate: bigint,
unwrapRate: bigint,
underlyingTokenAddress: string,
weight: BigintIsh,
) {
super(token, amount, index, rate, underlyingTokenAddress);
super(token, amount, index, rate, unwrapRate, underlyingTokenAddress);
this.weight = BigInt(weight);
}
}
1 change: 1 addition & 0 deletions modules/sor/sorV2/lib/poolsV3/weighted/weightedPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class WeightedPoolV3 implements BasePoolV3 {
tokenAmount.amount,
poolToken.index,
parseEther(poolToken.priceRate),
parseEther(poolToken.token.unwrapRate),
poolToken.token.underlyingTokenAddress,
parseEther(poolToken.weight),
),
Expand Down
41 changes: 27 additions & 14 deletions modules/sources/contracts/fetch-erc4626-token-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import MinimalErc4626Abi from './abis/MinimalERC4626';
import { fetchErc20Headers } from '.';
import { multicallViem, ViemMulticallCall } from '../../web3/multicaller-viem';
import { Chain } from '@prisma/client';
import { formatUnits, parseEther, parseUnits } from 'viem';

interface Erc4626Data {
asset?: string;
Expand All @@ -25,6 +26,7 @@ export async function fetchErc4626AndUnderlyingTokenData(
symbol: string;
chain: Chain;
underlyingTokenAddress?: string;
unwrapRate?: string;
}[]
> {
const tokenData: {
Expand All @@ -35,6 +37,7 @@ export async function fetchErc4626AndUnderlyingTokenData(
symbol: string;
chain: Chain;
underlyingTokenAddress?: string;
unwrapRate?: string;
};
} = {};

Expand All @@ -53,7 +56,7 @@ export async function fetchErc4626AndUnderlyingTokenData(
address: token.address as `0x${string}`,
abi: MinimalErc4626Abi,
functionName: 'convertToAssets',
args: [1n],
args: [parseUnits('1', token.decimals)],
},
{
path: `${token.address}.convertToShares`,
Expand Down Expand Up @@ -118,22 +121,32 @@ export async function fetchErc4626AndUnderlyingTokenData(
name: token.name,
symbol: token.symbol,
chain: token.chain,
underlyingTokenAddress: underlyingTokenAddress,
underlyingTokenAddress,
};

if (underlyingTokenAddress && !tokenData[underlyingTokenAddress]) {
const underlyingTokenDetail = await fetchErc20Headers(
[underlyingTokenAddress as `0x${string}`],
viemClient,
);
if (underlyingTokenAddress) {
if (!tokenData[underlyingTokenAddress]) {
const underlyingTokenDetail = await fetchErc20Headers(
[underlyingTokenAddress as `0x${string}`],
viemClient,
);

tokenData[underlyingTokenAddress] = {
address: underlyingTokenAddress,
decimals: underlyingTokenDetail[underlyingTokenAddress].decimals,
name: underlyingTokenDetail[underlyingTokenAddress].name,
symbol: underlyingTokenDetail[underlyingTokenAddress].symbol,
chain: token.chain,
underlyingTokenAddress: undefined,
};
}

tokenData[underlyingTokenAddress] = {
address: underlyingTokenAddress,
decimals: underlyingTokenDetail[underlyingTokenAddress].decimals,
name: underlyingTokenDetail[underlyingTokenAddress].name,
symbol: underlyingTokenDetail[underlyingTokenAddress].symbol,
chain: token.chain,
underlyingTokenAddress: undefined,
const unwrapRate = result.convertToAssets
? formatUnits(BigInt(result.convertToAssets), tokenData[underlyingTokenAddress].decimals)
: '1';
tokenData[token.address] = {
...tokenData[token.address],
unwrapRate,
};
}
}
Expand Down
7 changes: 3 additions & 4 deletions modules/sources/contracts/v3/fetch-pool-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ type PoolTokenRates = [
AbiParameterToPrimitiveType<ExtractAbiFunction<typeof VaultV3Abi, 'getPoolTokenRates'>['outputs'][0]>, // decimalScalingFactors
AbiParameterToPrimitiveType<ExtractAbiFunction<typeof VaultV3Abi, 'getPoolTokenRates'>['outputs'][1]>, // tokenRates
];
export interface OnchainDataV3 {

export interface PoolDataV3 {
totalSupply: bigint;
swapFee: bigint;
aggregateSwapFee?: bigint;
Expand All @@ -28,7 +29,6 @@ export interface OnchainDataV3 {
balance: bigint;
rateProvider: string;
rate: bigint;
isErc4626: boolean;
scalingFactor: bigint;
}[];
}
Expand All @@ -38,7 +38,7 @@ export async function fetchPoolData(
pools: string[],
client: ViemClient,
blockNumber?: bigint,
): Promise<{ [address: string]: OnchainDataV3 }> {
): Promise<{ [address: string]: PoolDataV3 }> {
const contracts = pools
.map((pool) => [
{
Expand Down Expand Up @@ -102,7 +102,6 @@ export async function fetchPoolData(
paysYieldFees: poolTokenInfo[1][i].paysYieldFees,
rateProvider: poolTokenInfo[1][i].rateProvider,
rate: poolTokenRates ? poolTokenRates[1][i] : 1000000000000000000n,
isErc4626: false, // will be added later in the process
scalingFactor: poolTokenRates ? poolTokenRates[0][i] : 1000000000000000000n,
})),
},
Expand Down
4 changes: 2 additions & 2 deletions modules/sources/contracts/v3/vault-client.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ViemClient } from '../../viem-client';
import { OnchainDataV3, fetchPoolData } from './fetch-pool-data';
import { PoolDataV3, fetchPoolData } from './fetch-pool-data';
import { ProtocolFees, fetchProtocolFees } from './fetch-protocol-fees';

export interface VaultClient {
fetchPoolData: (pools: string[], blockNumber?: bigint) => Promise<{ [address: string]: OnchainDataV3 }>;
fetchPoolData: (pools: string[], blockNumber?: bigint) => Promise<{ [address: string]: PoolDataV3 }>;
fetchProtocolFees: (blockNumber?: bigint) => Promise<ProtocolFees>;
}

Expand Down
7 changes: 4 additions & 3 deletions modules/sources/enrichers/apply-onchain-data.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { formatEther, formatUnits } from 'viem';
import { OnchainDataCowAmm, OnchainDataV3 } from '../contracts';
import { formatEther, formatUnits, parseEther } from 'viem';
import { OnchainDataCowAmm, PoolDataV3 } from '../contracts';
import { Chain } from '@prisma/client';
import { PoolDynamicUpsertData, PoolUpsertData } from '../../../prisma/prisma-types';

export const applyOnchainDataUpdateV3 = (
data: Partial<PoolUpsertData> = {},
onchainPoolData: OnchainDataV3,
onchainPoolData: PoolDataV3,
allTokens: { address: string; decimals: number }[],
chain: Chain,
poolId: string,
blockNumber: bigint,
): PoolDynamicUpsertData => {
const decimals = Object.fromEntries(allTokens.map((token) => [token.address, token.decimals]));

return {
poolDynamicData: {
...data.poolDynamicData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ export type VaultSchemaHistoricApRsArgs = {
};

export type AllPoolsQueryVariables = Exact<{
chainIds?: Maybe<Array<Scalars['Int']> | Scalars['Int']>;
chainIds?: InputMaybe<Array<Scalars['Int']> | Scalars['Int']>;
}>;

export type AllPoolsQuery = {
Expand All @@ -427,7 +427,7 @@ export type PoolSchemaFragment = {
};

export type AccountsQueryVariables = Exact<{
ids?: Maybe<Array<Scalars['String']> | Scalars['String']>;
ids?: InputMaybe<Array<Scalars['String']> | Scalars['String']>;
}>;

export type AccountsQuery = {
Expand Down Expand Up @@ -515,9 +515,10 @@ export const AccountsDocument = gql`
export type SdkFunctionWrapper = <T>(
action: (requestHeaders?: Record<string, string>) => Promise<T>,
operationName: string,
operationType?: string,
) => Promise<T>;

const defaultWrapper: SdkFunctionWrapper = (action, _operationName) => action();
const defaultWrapper: SdkFunctionWrapper = (action, _operationName, _operationType) => action();

export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = defaultWrapper) {
return {
Expand All @@ -532,6 +533,7 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
...wrappedRequestHeaders,
}),
'allPools',
'query',
);
},
accounts(
Expand All @@ -545,6 +547,7 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
...wrappedRequestHeaders,
}),
'accounts',
'query',
);
},
};
Expand Down
Loading

0 comments on commit 5ba5c15

Please sign in to comment.