From bda707a4f82acab08e7e852027d11a10c610605d Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Tue, 16 Jul 2024 20:26:23 +0500 Subject: [PATCH 01/36] [for-new-stake] add contract for genesis --- src/contracts/abis/GenesisVaultDiffAbi.json | 31 +++++++++++++++++++++ src/contracts/abis/index.js | 8 ++++-- src/contracts/createContracts.ts | 14 ++++++---- src/contracts/index.ts | 2 +- 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/contracts/abis/GenesisVaultDiffAbi.json diff --git a/src/contracts/abis/GenesisVaultDiffAbi.json b/src/contracts/abis/GenesisVaultDiffAbi.json new file mode 100644 index 00000000..f1c990be --- /dev/null +++ b/src/contracts/abis/GenesisVaultDiffAbi.json @@ -0,0 +1,31 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "osTokenShares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "referrer", + "type": "address" + } + ], + "name": "depositAndMintOsToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + } +] diff --git a/src/contracts/abis/index.js b/src/contracts/abis/index.js index 44bccac4..3c541703 100644 --- a/src/contracts/abis/index.js +++ b/src/contracts/abis/index.js @@ -3,13 +3,14 @@ import RewardSplitterFactoryAbi from './RewardSplitterFactoryAbi.json' import VestingEscrowFactoryAbi from './VestingEscrowFactoryAbi.json' import MintTokenControllerAbi from './MintTokenControllerAbi.json' import DepositDataRegistryAbi from './DepositDataRegistryAbi.json' +import InitialOtherTokenVaultAbi from './OtherTokenVaultAbi.json' import BlocklistVaultDiffAbi from './BlocklistVaultDiffAbi.json' import RestakingVaultDiffAbi from './RestakingVaultDiffAbi.json' import MerkleDistributorAbi from './MerkleDistributorAbi.json' import MintTokenConfigV1Abi from './MintTokenConfigV1Abi.json' import MintTokenConfigV2Abi from './MintTokenConfigV2Abi.json' import PrivateVaultDiffAbi from './PrivateVaultDiffAbi.json' -import OtherTokenVaultAbi from './OtherTokenVaultAbi.json' +import GenesisVaultDiffAbi from './GenesisVaultDiffAbi.json' import GnosisVaultDiffAbi from './GnosisVaultDiffAbi.json' import VaultsRegistryAbi from './VaultsRegistryAbi.json' import RewardSplitterAbi from './RewardSplitterAbi.json' @@ -20,16 +21,18 @@ import VaultFactoryAbi from './VaultFactoryAbi.json' import PriceOracleAbi from './PriceOracleAbi.json' import UniswapPoolAbi from './UniswapPoolAbi.json' import MulticallAbi from './MulticallAbi.json' +import InitialVaultAbi from './VaultAbi.json' import UsdRateAbi from './UsdRateAbi.json' import OraclesAbi from './OraclesAbi.json' import KeeperAbi from './KeeperAbi.json' import Erc20Abi from './Erc20Abi.json' -import InitialVaultAbi from './VaultAbi.json' // ATTN temp solution to handle swapXdaiToGno, need to fix within https://app.clickup.com/t/8694zcfv8 const VaultAbi = InitialVaultAbi.concat(GnosisVaultDiffAbi) +const OtherTokenVaultAbi = InitialOtherTokenVaultAbi.concat(GnosisVaultDiffAbi) +const GenesisVaultAbi = VaultAbi.concat(GenesisVaultDiffAbi) const PrivateVaultAbi = VaultAbi.concat(PrivateVaultDiffAbi) const BlocklistVaultAbi = VaultAbi.concat(BlocklistVaultDiffAbi) const RestakingVaultAbi = VaultAbi.concat(RestakingVaultDiffAbi) @@ -52,6 +55,7 @@ export { EigenPodOwnerAbi, VestingEscrowAbi, PrivateVaultAbi, + GenesisVaultAbi, VaultFactoryAbi, PriceOracleAbi, UniswapPoolAbi, diff --git a/src/contracts/createContracts.ts b/src/contracts/createContracts.ts index 5e5e5b46..eb7ebf26 100644 --- a/src/contracts/createContracts.ts +++ b/src/contracts/createContracts.ts @@ -10,6 +10,7 @@ import { MulticallAbi, UniswapPoolAbi, PriceOracleAbi, + GenesisVaultAbi, PrivateVaultAbi, VaultFactoryAbi, VestingEscrowAbi, @@ -144,18 +145,21 @@ export const createContracts = (input: CreateContractsInput) => { helpers: { multicallContract, createMulticall: commonMulticall(multicallContract as StakeWise.ABI.Multicall), - createVault: (address: string) => createContract(address, VaultAbi, provider), createErc20: (address: string) => createContract(address, Erc20Abi, provider), createUniswapPool: (address: string) => createContract(address, UniswapPoolAbi, provider), - createPrivateVault: (address: string) => createContract(address, PrivateVaultAbi, provider), createEigenPodOwner: (address: string) => createContract(address, EigenPodOwnerAbi, provider), - createRestakingVault: (address: string) => createContract(address, RestakingVaultAbi, provider), - createBlocklistedVault: (address: string) => createContract(address, BlocklistVaultAbi, provider), createRewardSplitter: (address: string) => createContract(address, RewardSplitterAbi, provider), - createOtherTokenVault: (address: string) => createContract(address, OtherTokenVaultAbi, provider), createVestingEscrowDirect: (address: string) => createContract(address, VestingEscrowAbi, provider), createUsdRate: (address: string, _provider?: Provider) => createContract(address, UsdRateAbi, _provider || provider), createVestingEscrowFactory: (address: string) => createContract(address, VestingEscrowFactoryAbi, provider), + + // Vaults + createVault: (address: string) => createContract(address, VaultAbi, provider), + createPrivateVault: (address: string) => createContract(address, PrivateVaultAbi, provider), + createRestakingVault: (address: string) => createContract(address, RestakingVaultAbi, provider), + createBlocklistedVault: (address: string) => createContract(address, BlocklistVaultAbi, provider), + createOtherTokenVault: (address: string) => createContract(address, OtherTokenVaultAbi, provider), + createGenesisVault: (address: string) => createContract(address, GenesisVaultAbi, provider), }, base: { keeper: getKeeper(provider, config), diff --git a/src/contracts/index.ts b/src/contracts/index.ts index 5b29cd3a..d631b918 100644 --- a/src/contracts/index.ts +++ b/src/contracts/index.ts @@ -1,5 +1,5 @@ -export { default as createContracts } from './createContracts' export { default as createContract } from './createContract' +export { default as createContracts } from './createContracts' export { default as multicall } from './multicall/commonMulticall' export { default as vaultMulticall } from './multicall/vaultMulticall' export { default as eigenPodOwnerMulticall } from './multicall/eigenPodOwnerMulticall' From 1e072b7503ef91d66f424ab452da904854e64c97 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Wed, 17 Jul 2024 13:57:24 +0500 Subject: [PATCH 02/36] [for-new-stake] improve vaultMulticall --- src/StakeWiseSDK.ts | 18 +++++++++++++----- src/types/global.ts | 2 ++ src/utils/getVaultContract.ts | 23 +++++++++++++++++++++++ src/utils/index.ts | 1 + 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 src/utils/getVaultContract.ts diff --git a/src/StakeWiseSDK.ts b/src/StakeWiseSDK.ts index 335c3127..328d682d 100644 --- a/src/StakeWiseSDK.ts +++ b/src/StakeWiseSDK.ts @@ -1,5 +1,5 @@ import methods from './methods' -import { configs, getGas, createProvider } from './utils' +import { configs, getGas, createProvider, getVaultContract } from './utils' import { createContracts, vaultMulticall, rewardSplitterMulticall } from './contracts' @@ -38,19 +38,27 @@ class StakeWiseSDK { this.rewardSplitter = methods.createRewardSplitterMethods(argsForMethods) } - vaultMulticall({ userAddress, vaultAddress, request }: VaultMulticallInput) { + vaultMulticall(values: VaultMulticallInput) { + const { userAddress, vaultAddress, request } = values + + const vaultContract = getVaultContract({ + contracts: this.contracts, + network: this.network, + vaultAddress, + }) + return vaultMulticall({ - vaultContract: this.contracts.helpers.createVault(vaultAddress), keeperContract: this.contracts.base.keeper, options: this.options, + vaultContract, vaultAddress, userAddress, request, }) } - rewardSplitterMulticall(props: RewardSplitterMulticallInput) { - const { userAddress, vaultAddress, rewardSplitterAddress, request } = props + rewardSplitterMulticall(values: RewardSplitterMulticallInput) { + const { userAddress, vaultAddress, rewardSplitterAddress, request } = values return rewardSplitterMulticall({ rewardSplitterContract: this.contracts.helpers.createRewardSplitter(rewardSplitterAddress), diff --git a/src/types/global.ts b/src/types/global.ts index b95685f7..9cb249b3 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -21,6 +21,7 @@ import type { RewardSplitterAbi, GnosisVaultDiffAbi, OtherTokenVaultAbi, + GenesisVaultDiffAbi, PrivateVaultDiffAbi, MerkleDistributorAbi, MintTokenConfigV1Abi, @@ -92,6 +93,7 @@ declare global { type EigenPodOwner = EigenPodOwnerAbi type V2RewardToken = V2RewardTokenAbi type VestingEscrow = VestingEscrowAbi + type GenesisVault = GenesisVaultDiffAbi type RewardSplitter = RewardSplitterAbi type VaultsRegistry = VaultsRegistryAbi type OtherTokenVault = OtherTokenVaultAbi diff --git a/src/utils/getVaultContract.ts b/src/utils/getVaultContract.ts new file mode 100644 index 00000000..fd36aca1 --- /dev/null +++ b/src/utils/getVaultContract.ts @@ -0,0 +1,23 @@ +import { Network } from './enums' + + +type Input = { + network: Network + vaultAddress: string + contracts: StakeWise.Contracts +} + +const getVaultContract = (values: Input) => { + const { vaultAddress, network, contracts } = values + + const isNativeToken = [ Network.Holesky, Network.Mainnet ].includes(network) + + if (isNativeToken) { + return contracts.helpers.createVault(vaultAddress) + } + + return contracts.helpers.createOtherTokenVault(vaultAddress) +} + + +export default getVaultContract diff --git a/src/utils/index.ts b/src/utils/index.ts index 41a9f10d..1645fefc 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -8,4 +8,5 @@ export { default as BigDecimal } from './BigDecimal' export { default as validateArgs } from './validateArgs' export { default as createProvider } from './createProvider' export { default as getNetworkTypes } from './getNetworkTypes' +export { default as getVaultContract } from './getVaultContract' export { default as getValidLtvPercent } from './getValidLtvPercent' From ad73ec0df0b4cc03b47147e80988c527c01601f6 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Wed, 17 Jul 2024 13:57:54 +0500 Subject: [PATCH 03/36] [for-new-stake] improve getOsTokenPosition --- .../requests/getOsTokenPosition/index.ts | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/src/methods/osToken/requests/getOsTokenPosition/index.ts b/src/methods/osToken/requests/getOsTokenPosition/index.ts index 253d3605..9272e80e 100644 --- a/src/methods/osToken/requests/getOsTokenPosition/index.ts +++ b/src/methods/osToken/requests/getOsTokenPosition/index.ts @@ -1,6 +1,7 @@ -import { validateArgs } from '../../../../utils' import getHealthFactor from '../../helpers/getHealthFactor' import getOsTokenPositionShares from './getOsTokenPositionShares' +import { wrapAbortPromise } from '../../../../modules/gql-module' +import { validateArgs, OsTokenPositionHealth } from '../../../../utils' type GetOsTokenPositionInput = { @@ -12,35 +13,50 @@ type GetOsTokenPositionInput = { contracts: StakeWise.Contracts } -const getOsTokenPosition = (values: GetOsTokenPositionInput) => { +type Output = { + minted: { + assets: bigint + shares: bigint + fee: bigint + } + healthFactor: { + value: number + health: OsTokenPositionHealth + } + protocolFeePercent: bigint +} + +const getOsTokenPosition = async (values: GetOsTokenPositionInput) => { const { options, contracts, vaultAddress, userAddress, stakedAssets, thresholdPercent } = values validateArgs.address({ vaultAddress, userAddress }) validateArgs.bigint({ stakedAssets, thresholdPercent }) - return getOsTokenPositionShares({ options, vaultAddress, userAddress }) - .then(async (gqlMintedShares) => { - const vaultContract = contracts.helpers.createVault(vaultAddress) - const mintedShares = await vaultContract.osTokenPositions(userAddress) - - const [ mintedAssets, feePercent ] = await Promise.all([ - contracts.base.mintTokenController.convertToAssets(mintedShares), - contracts.base.mintTokenController.feePercent(), - ]) - - const protocolFeePercent = feePercent / 100n - const healthFactor = getHealthFactor({ mintedAssets, stakedAssets, thresholdPercent }) - - return { - minted: { - assets: mintedAssets, - shares: mintedShares, - fee: mintedShares - gqlMintedShares, - }, - healthFactor, - protocolFeePercent, - } - }) + const gqlMintedShares = await getOsTokenPositionShares({ options, vaultAddress, userAddress }) + + const vaultContract = contracts.helpers.createVault(vaultAddress) + const mintedShares = await vaultContract.osTokenPositions(userAddress) + + const [ mintedAssets, feePercent ] = await Promise.all([ + contracts.base.mintTokenController.convertToAssets(mintedShares), + contracts.base.mintTokenController.feePercent(), + ]) + + const protocolFeePercent = feePercent / 100n + const healthFactor = getHealthFactor({ mintedAssets, stakedAssets, thresholdPercent }) + + const result: Output = { + minted: { + assets: mintedAssets, + shares: mintedShares, + fee: mintedShares - gqlMintedShares, + }, + healthFactor, + protocolFeePercent, + } + + return result } -export default getOsTokenPosition + +export default wrapAbortPromise(getOsTokenPosition) From 3c0dcd00fd063966d17f3453621d13ac08b323e8 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Wed, 17 Jul 2024 19:18:59 +0500 Subject: [PATCH 04/36] [for-new-stake] add panding to getExitQueuePositions --- README.md | 16 ++++- changelog/next-release.md | 19 ++++++ .../requests/getExitQueuePositions/index.ts | 1 + .../parseExitRequests.spec.ts | 66 +++++++++++++++++-- .../parseExitRequests.ts | 28 +++++--- 5 files changed, 112 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 08993543..a8198a83 100644 --- a/README.md +++ b/README.md @@ -470,6 +470,14 @@ Returns the withdrawal queue for a specific user. #### Returns: ```ts +type ExitRequest = { + withdrawalTimestamp: string | null + positionTicket: string + totalShares: string + totalAssets: string + timestamp: string +} + type Position = { exitQueueIndex: bigint positionTicket: string @@ -481,15 +489,17 @@ type Output = { duration: number | null withdrawable: bigint positions: Position[] + pending: ExitRequest[] } ``` | Name | Description | |------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `positions` | Queue positions | -| `total` | Total queued assets (e.g. ETH) | +| `pending` | Positions not yet available for claim | +| `positions` | Positions in a special format that are required for claiming | +| `total` | Total queued assets (e.g. ETH) | | `duration` | Queue duration time (in seconds).
- It represents the approximate time after which the assets can be collected (in seconds).
- If the value is null, the time is still being calculated.
- If the value is 0, the assets are available and can be collected. | -| | |- +| | |- | `withdrawable` | Assets available for withdrawal (e.g. ETH) | #### Example: diff --git a/changelog/next-release.md b/changelog/next-release.md index 927d9f86..23ac47d8 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -89,6 +89,25 @@ Use **sdk.vault.operate** instead Use **osToken.getConfig** and **osToken.getRate** --- +### sdk.vault.getExitQueuePositions +Added positions that are not yet available for claim + +#### Returns: +```ts +type ExitRequest = { + withdrawalTimestamp: string | null + positionTicket: string + totalShares: string + totalAssets: string + timestamp: string +} + +type Output = { + ...oldOutput, + pending: ExitRequest[] +} +``` + # New ## Vault diff --git a/src/methods/vault/requests/getExitQueuePositions/index.ts b/src/methods/vault/requests/getExitQueuePositions/index.ts index 788c90da..218f82d6 100644 --- a/src/methods/vault/requests/getExitQueuePositions/index.ts +++ b/src/methods/vault/requests/getExitQueuePositions/index.ts @@ -13,6 +13,7 @@ type GetExitQueuePositionsInput = FetchExitQueuePositionsInput & { const mock: ParseExitRequestsOutput = { total: 0n, + pending: [], duration: 0, positions: [], withdrawable: 0n, diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts index 13741b4f..bd4e853f 100644 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts +++ b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts @@ -111,6 +111,7 @@ describe('parseExitRequests function', () => { positionTicket: 'positionTicket-2', }, ], + pending: [], total: 431n, duration: 1718536919, withdrawable: 281n, @@ -139,6 +140,22 @@ describe('parseExitRequests function', () => { duration: 0, positions: [], withdrawable: 0n, + pending: [ + { + positionTicket: 'positionTicket-1', + withdrawalTimestamp: '1718536919', + timestamp: '123456', + totalAssets: '0', + totalShares: '100', + }, + { + positionTicket: 'positionTicket-2', + withdrawalTimestamp: '1718536919', + timestamp: '123457', + totalAssets: '0', + totalShares: '200', + }, + ], }) }) @@ -153,10 +170,26 @@ describe('parseExitRequests function', () => { const result = await parseExitRequests(input) expect(result).toEqual({ - positions: [], total: 50n, duration: 0, + positions: [], withdrawable: 0n, + pending: [ + { + positionTicket: 'positionTicket-1', + withdrawalTimestamp: '1718536919', + timestamp: '123456', + totalAssets: '0', + totalShares: '100', + }, + { + positionTicket: 'positionTicket-2', + withdrawalTimestamp: '1718536919', + timestamp: '123457', + totalAssets: '0', + totalShares: '200', + }, + ], }) }) @@ -179,12 +212,30 @@ describe('parseExitRequests function', () => { const result = await parseExitRequests(input) expect(result).toEqual({ - positions: [ { - exitQueueIndex: 1n, - timestamp: '123457', - isV1Position: true, - positionTicket: 'positionTicket-2', - } ], + positions: [ + { + exitQueueIndex: 1n, + timestamp: '123457', + isV1Position: true, + positionTicket: 'positionTicket-2', + }, + ], + pending: [ + { + positionTicket: 'positionTicket-1', + withdrawalTimestamp: '1718536919', + timestamp: '123456', + totalAssets: '0', + totalShares: '100', + }, + { + positionTicket: 'positionTicket-2', + withdrawalTimestamp: '1718536919', + timestamp: '123458', + totalAssets: '300', + totalShares: '0', + }, + ], total: 380n, duration: 1718536919, withdrawable: 30n, @@ -228,6 +279,7 @@ describe('parseExitRequests function', () => { positionTicket: 'positionTicket-2', }, ], + pending: [], total: 603n, duration: 1718536919, withdrawable: 603n, diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts index 86bffa9e..3722afc1 100644 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts +++ b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts @@ -1,19 +1,21 @@ import vaultMulticall from '../../../../contracts/multicall/vaultMulticall' +type ExitRequest = { + withdrawalTimestamp: string | null + positionTicket: string + totalShares: string + totalAssets: string + timestamp: string +} + export type ParseExitRequestsInput = { contracts: StakeWise.Contracts provider: StakeWise.Provider + exitRequests: ExitRequest[] options: StakeWise.Options userAddress: string vaultAddress: string - exitRequests: Array<{ - withdrawalTimestamp: string | null - positionTicket: string - totalShares: string - totalAssets: string - timestamp: string - }> } type Position = { @@ -26,8 +28,9 @@ type Position = { export type ParseExitRequestsOutput = { total: bigint withdrawable: bigint - duration: number | null positions: Position[] + pending: ExitRequest[] + duration: number | null } type ExitedAssetsResponse = Array<{ @@ -73,6 +76,7 @@ const parseExitRequests = async (values: ParseExitRequestsInput): Promise Date: Mon, 22 Jul 2024 19:11:51 +0500 Subject: [PATCH 05/36] [for-new-stake] add stake calculator --- src/contracts/abis/GenesisVaultDiffAbi.json | 56 +++++++++++++++++++++ src/contracts/abis/StakeCalculatorAbi.json | 1 + src/contracts/abis/index.js | 2 + src/contracts/createContracts.ts | 9 ++++ src/types/global.ts | 2 + src/utils/configs/chiado.ts | 3 ++ src/utils/configs/gnosis.ts | 3 ++ src/utils/configs/holesky.ts | 3 ++ src/utils/configs/mainnet.ts | 3 ++ 9 files changed, 82 insertions(+) create mode 100644 src/contracts/abis/StakeCalculatorAbi.json diff --git a/src/contracts/abis/GenesisVaultDiffAbi.json b/src/contracts/abis/GenesisVaultDiffAbi.json index f1c990be..505b73e9 100644 --- a/src/contracts/abis/GenesisVaultDiffAbi.json +++ b/src/contracts/abis/GenesisVaultDiffAbi.json @@ -27,5 +27,61 @@ ], "stateMutability": "payable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "osTokenShares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "referrer", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "rewardsRoot", + "type": "bytes32" + }, + { + "internalType": "int160", + "name": "reward", + "type": "int160" + }, + { + "internalType": "uint160", + "name": "unlockedMevReward", + "type": "uint160" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + } + ], + "internalType": "struct IKeeperRewards.HarvestParams", + "name": "harvestParams", + "type": "tuple" + } + ], + "name": "updateStateAndDepositAndMintOsToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" } ] diff --git a/src/contracts/abis/StakeCalculatorAbi.json b/src/contracts/abis/StakeCalculatorAbi.json new file mode 100644 index 00000000..0cee4a15 --- /dev/null +++ b/src/contracts/abis/StakeCalculatorAbi.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"keeper","type":"address"},{"internalType":"address","name":"osTokenConfigV1","type":"address"},{"internalType":"address","name":"osTokenConfigV2","type":"address"},{"internalType":"address","name":"osTokenController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidLtvProvided","type":"error"},{"inputs":[],"name":"MathOverflowedMulDiv","type":"error"},{"inputs":[{"components":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"stakeAssets","type":"uint256"},{"internalType":"uint256","name":"osTokenLtv","type":"uint256"},{"components":[{"internalType":"bytes32","name":"rewardsRoot","type":"bytes32"},{"internalType":"int160","name":"reward","type":"int160"},{"internalType":"uint160","name":"unlockedMevReward","type":"uint160"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"internalType":"struct IKeeperRewards.HarvestParams","name":"harvestParams","type":"tuple"}],"internalType":"struct Helpers.StakeInput","name":"inputData","type":"tuple"}],"name":"calculateStake","outputs":[{"components":[{"internalType":"uint256","name":"receivedOsTokenShares","type":"uint256"},{"internalType":"uint256","name":"exchangeRate","type":"uint256"}],"internalType":"struct Helpers.StakeOutput","name":"outputData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/src/contracts/abis/index.js b/src/contracts/abis/index.js index 3c541703..dabf6666 100644 --- a/src/contracts/abis/index.js +++ b/src/contracts/abis/index.js @@ -12,6 +12,7 @@ import MintTokenConfigV2Abi from './MintTokenConfigV2Abi.json' import PrivateVaultDiffAbi from './PrivateVaultDiffAbi.json' import GenesisVaultDiffAbi from './GenesisVaultDiffAbi.json' import GnosisVaultDiffAbi from './GnosisVaultDiffAbi.json' +import StakeCalculatorAbi from './StakeCalculatorAbi.json' import VaultsRegistryAbi from './VaultsRegistryAbi.json' import RewardSplitterAbi from './RewardSplitterAbi.json' import V2RewardTokenAbi from './V2RewardTokenAbi.json' @@ -46,6 +47,7 @@ export { MerkleDistributorAbi, MintTokenConfigV1Abi, MintTokenConfigV2Abi, + StakeCalculatorAbi, OtherTokenVaultAbi, VaultsRegistryAbi, RestakingVaultAbi, diff --git a/src/contracts/createContracts.ts b/src/contracts/createContracts.ts index eb7ebf26..dfd7d13c 100644 --- a/src/contracts/createContracts.ts +++ b/src/contracts/createContracts.ts @@ -20,6 +20,7 @@ import { VaultsRegistryAbi, RewardSplitterAbi, RestakingVaultAbi, + StakeCalculatorAbi, OtherTokenVaultAbi, MintTokenConfigV1Abi, MintTokenConfigV2Abi, @@ -131,6 +132,12 @@ const getOracles = (provider: Provider, config: StakeWise.Config) => createContr provider ) +const getStakeCalculator = (provider: Provider, config: StakeWise.Config) => createContract( + config.addresses.helpers.stakeCalculator, + StakeCalculatorAbi, + provider +) + type CreateContractsInput = { provider: Provider config: StakeWise.Config @@ -144,6 +151,8 @@ export const createContracts = (input: CreateContractsInput) => { return { helpers: { multicallContract, + stakeCalculator: getStakeCalculator(provider, config), + createMulticall: commonMulticall(multicallContract as StakeWise.ABI.Multicall), createErc20: (address: string) => createContract(address, Erc20Abi, provider), createUniswapPool: (address: string) => createContract(address, UniswapPoolAbi, provider), diff --git a/src/types/global.ts b/src/types/global.ts index 9cb249b3..bb6c3e0e 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -21,6 +21,7 @@ import type { RewardSplitterAbi, GnosisVaultDiffAbi, OtherTokenVaultAbi, + StakeCalculatorAbi, GenesisVaultDiffAbi, PrivateVaultDiffAbi, MerkleDistributorAbi, @@ -96,6 +97,7 @@ declare global { type GenesisVault = GenesisVaultDiffAbi type RewardSplitter = RewardSplitterAbi type VaultsRegistry = VaultsRegistryAbi + type StakeCalculator = StakeCalculatorAbi type OtherTokenVault = OtherTokenVaultAbi type MerkleDistributor = MerkleDistributorAbi type MintTokenConfigV1 = MintTokenConfigV1Abi diff --git a/src/utils/configs/chiado.ts b/src/utils/configs/chiado.ts index 0ae80fc1..866f6673 100644 --- a/src/utils/configs/chiado.ts +++ b/src/utils/configs/chiado.ts @@ -50,6 +50,9 @@ export default { uniswap: { positionManager: ZeroAddress, }, + helpers: { + stakeCalculator: ZeroAddress, + }, }, tokens: { mintToken: constants.tokens.osGNO, diff --git a/src/utils/configs/gnosis.ts b/src/utils/configs/gnosis.ts index 3bfd98e4..817268c6 100644 --- a/src/utils/configs/gnosis.ts +++ b/src/utils/configs/gnosis.ts @@ -50,6 +50,9 @@ export default { uniswap: { positionManager: ZeroAddress, }, + helpers: { + stakeCalculator: ZeroAddress, + }, }, tokens: { mintToken: constants.tokens.osGNO, diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 0da4d8c9..f0a931ae 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -50,6 +50,9 @@ export default { uniswap: { positionManager: ZeroAddress, }, + helpers: { + stakeCalculator: '0xAc640d35448F43e03229455EF1D799a8F77321A7', + }, }, tokens: { mintToken: constants.tokens.osETH, diff --git a/src/utils/configs/mainnet.ts b/src/utils/configs/mainnet.ts index 3a1353bd..c739d701 100644 --- a/src/utils/configs/mainnet.ts +++ b/src/utils/configs/mainnet.ts @@ -53,6 +53,9 @@ export default { uniswap: { positionManager: '0xC36442b4a4522E871399CD717aBDD847Ab11FE88', }, + helpers: { + stakeCalculator: ZeroAddress, + }, }, tokens: { mintToken: constants.tokens.osETH, From bf6078ebeab57bba46d9c041e350cdb39084d846 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Thu, 25 Jul 2024 17:48:59 +0500 Subject: [PATCH 06/36] [for-new-stake] improve stake calculator --- src/contracts/abis/StakeCalculatorAbi.json | 357 +++++++++++++++++- src/contracts/createContracts.ts | 7 +- .../osToken/transactions/burn/common.ts | 9 +- .../osToken/transactions/burn/types.d.ts | 1 - src/utils/configs/chiado.ts | 2 +- src/utils/configs/gnosis.ts | 2 +- src/utils/configs/holesky.ts | 4 +- src/utils/configs/mainnet.ts | 2 +- 8 files changed, 367 insertions(+), 17 deletions(-) diff --git a/src/contracts/abis/StakeCalculatorAbi.json b/src/contracts/abis/StakeCalculatorAbi.json index 0cee4a15..28d500f8 100644 --- a/src/contracts/abis/StakeCalculatorAbi.json +++ b/src/contracts/abis/StakeCalculatorAbi.json @@ -1 +1,356 @@ -[{"inputs":[{"internalType":"address","name":"keeper","type":"address"},{"internalType":"address","name":"osTokenConfigV1","type":"address"},{"internalType":"address","name":"osTokenConfigV2","type":"address"},{"internalType":"address","name":"osTokenController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidLtvProvided","type":"error"},{"inputs":[],"name":"MathOverflowedMulDiv","type":"error"},{"inputs":[{"components":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"stakeAssets","type":"uint256"},{"internalType":"uint256","name":"osTokenLtv","type":"uint256"},{"components":[{"internalType":"bytes32","name":"rewardsRoot","type":"bytes32"},{"internalType":"int160","name":"reward","type":"int160"},{"internalType":"uint160","name":"unlockedMevReward","type":"uint160"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"internalType":"struct IKeeperRewards.HarvestParams","name":"harvestParams","type":"tuple"}],"internalType":"struct Helpers.StakeInput","name":"inputData","type":"tuple"}],"name":"calculateStake","outputs":[{"components":[{"internalType":"uint256","name":"receivedOsTokenShares","type":"uint256"},{"internalType":"uint256","name":"exchangeRate","type":"uint256"}],"internalType":"struct Helpers.StakeOutput","name":"outputData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"}] +[ + { + "inputs": [ + { + "internalType": "address", + "name": "keeper", + "type": "address" + }, + { + "internalType": "address", + "name": "osTokenConfigV1", + "type": "address" + }, + { + "internalType": "address", + "name": "osTokenConfigV2", + "type": "address" + }, + { + "internalType": "address", + "name": "osTokenController", + "type": "address" + }, + { + "internalType": "address", + "name": "osToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakeAssets", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "rewardsRoot", + "type": "bytes32" + }, + { + "internalType": "int160", + "name": "reward", + "type": "int160" + }, + { + "internalType": "uint160", + "name": "unlockedMevReward", + "type": "uint160" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + } + ], + "internalType": "struct IKeeperRewards.HarvestParams", + "name": "harvestParams", + "type": "tuple" + } + ], + "internalType": "struct Helpers.StakeInput", + "name": "inputData", + "type": "tuple" + } + ], + "name": "calculateStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "receivedOsTokenShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "internalType": "struct Helpers.StakeOutput", + "name": "outputData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unstakeAssets", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "rewardsRoot", + "type": "bytes32" + }, + { + "internalType": "int160", + "name": "reward", + "type": "int160" + }, + { + "internalType": "uint160", + "name": "unlockedMevReward", + "type": "uint160" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + } + ], + "internalType": "struct IKeeperRewards.HarvestParams", + "name": "harvestParams", + "type": "tuple" + } + ], + "internalType": "struct Helpers.UnstakeAssetsInput", + "name": "inputData", + "type": "tuple" + } + ], + "name": "calculateUnstakeAssets", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "unstakeAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unstakeShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "burnOsTokenShares", + "type": "uint256" + } + ], + "internalType": "struct Helpers.UnstakeAssetsOutput", + "name": "outputData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "osTokenShares", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "rewardsRoot", + "type": "bytes32" + }, + { + "internalType": "int160", + "name": "reward", + "type": "int160" + }, + { + "internalType": "uint160", + "name": "unlockedMevReward", + "type": "uint160" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + } + ], + "internalType": "struct IKeeperRewards.HarvestParams", + "name": "harvestParams", + "type": "tuple" + } + ], + "internalType": "struct Helpers.UnstakeOsTokenSharesInput", + "name": "inputData", + "type": "tuple" + } + ], + "name": "calculateUnstakeOsTokenShares", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "unstakeOsTokenShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapOsTokenShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivedAssets", + "type": "uint256" + } + ], + "internalType": "struct Helpers.UnstakeOsTokenSharesOutput", + "name": "outputData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "rewardsRoot", + "type": "bytes32" + }, + { + "internalType": "int160", + "name": "reward", + "type": "int160" + }, + { + "internalType": "uint160", + "name": "unlockedMevReward", + "type": "uint160" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + } + ], + "internalType": "struct IKeeperRewards.HarvestParams", + "name": "harvestParams", + "type": "tuple" + } + ], + "internalType": "struct Helpers.UnstakeAmountsInput", + "name": "inputData", + "type": "tuple" + } + ], + "name": "getUnstakeAmounts", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "maxUnstakeAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxUnstakeOsTokenShares", + "type": "uint256" + } + ], + "internalType": "struct Helpers.UnstakeAmountsOutput", + "name": "outputData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxLeftStakeAssetsPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/createContracts.ts b/src/contracts/createContracts.ts index dfd7d13c..b32e8211 100644 --- a/src/contracts/createContracts.ts +++ b/src/contracts/createContracts.ts @@ -133,7 +133,7 @@ const getOracles = (provider: Provider, config: StakeWise.Config) => createContr ) const getStakeCalculator = (provider: Provider, config: StakeWise.Config) => createContract( - config.addresses.helpers.stakeCalculator, + config.addresses.special.stakeCalculator, StakeCalculatorAbi, provider ) @@ -151,8 +151,6 @@ export const createContracts = (input: CreateContractsInput) => { return { helpers: { multicallContract, - stakeCalculator: getStakeCalculator(provider, config), - createMulticall: commonMulticall(multicallContract as StakeWise.ABI.Multicall), createErc20: (address: string) => createContract(address, Erc20Abi, provider), createUniswapPool: (address: string) => createContract(address, UniswapPoolAbi, provider), @@ -202,6 +200,9 @@ export const createContracts = (input: CreateContractsInput) => { uniswap: { positionManager: getUniswapPositionManager(provider, config), }, + special: { + stakeCalculator: getStakeCalculator(provider, config), + }, } } diff --git a/src/methods/osToken/transactions/burn/common.ts b/src/methods/osToken/transactions/burn/common.ts index f01b5bca..c8156a09 100644 --- a/src/methods/osToken/transactions/burn/common.ts +++ b/src/methods/osToken/transactions/burn/common.ts @@ -1,14 +1,9 @@ import type { BurnInput } from './types' -import { validateArgs, Network } from '../../../../utils' +import { validateArgs } from '../../../../utils' export const commonLogic = (values: BurnInput) => { - const { contracts, options, vaultAddress, userAddress, shares } = values - - const isGnosis = ( - options.network === Network.Gnosis - || options.network === Network.Chiado - ) + const { contracts, vaultAddress, userAddress, shares } = values validateArgs.bigint({ shares }) validateArgs.address({ vaultAddress, userAddress }) diff --git a/src/methods/osToken/transactions/burn/types.d.ts b/src/methods/osToken/transactions/burn/types.d.ts index 2eff2f8d..62098f14 100644 --- a/src/methods/osToken/transactions/burn/types.d.ts +++ b/src/methods/osToken/transactions/burn/types.d.ts @@ -6,7 +6,6 @@ export type BurnInput = { shares: bigint userAddress: string vaultAddress: string - options: StakeWise.Options provider: StakeWise.Provider contracts: StakeWise.Contracts } diff --git a/src/utils/configs/chiado.ts b/src/utils/configs/chiado.ts index 866f6673..5f698854 100644 --- a/src/utils/configs/chiado.ts +++ b/src/utils/configs/chiado.ts @@ -50,7 +50,7 @@ export default { uniswap: { positionManager: ZeroAddress, }, - helpers: { + special: { stakeCalculator: ZeroAddress, }, }, diff --git a/src/utils/configs/gnosis.ts b/src/utils/configs/gnosis.ts index 817268c6..3e57fd49 100644 --- a/src/utils/configs/gnosis.ts +++ b/src/utils/configs/gnosis.ts @@ -50,7 +50,7 @@ export default { uniswap: { positionManager: ZeroAddress, }, - helpers: { + special: { stakeCalculator: ZeroAddress, }, }, diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index f0a931ae..5301b6fc 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -50,8 +50,8 @@ export default { uniswap: { positionManager: ZeroAddress, }, - helpers: { - stakeCalculator: '0xAc640d35448F43e03229455EF1D799a8F77321A7', + special: { + stakeCalculator: '0x7151c611d7f76AFF8F53E87B3846Dc38C444dE0A', }, }, tokens: { diff --git a/src/utils/configs/mainnet.ts b/src/utils/configs/mainnet.ts index c739d701..0894f442 100644 --- a/src/utils/configs/mainnet.ts +++ b/src/utils/configs/mainnet.ts @@ -53,7 +53,7 @@ export default { uniswap: { positionManager: '0xC36442b4a4522E871399CD717aBDD847Ab11FE88', }, - helpers: { + special: { stakeCalculator: ZeroAddress, }, }, From 0f247d3aaa79cac7dd56c6ff6a4ffc822c628b9b Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Fri, 26 Jul 2024 18:47:22 +0500 Subject: [PATCH 07/36] [for-new-stake] improve abis --- src/contracts/abis/KeeperAbi.json | 41 ++++- src/contracts/abis/MintTokenAbi.json | 47 ++++- src/contracts/abis/MintTokenConfigV1Abi.json | 29 ++- .../abis/MintTokenControllerAbi.json | 67 ++++++- src/contracts/abis/MulticallAbi.json | 53 +++++- src/contracts/abis/PriceOracleAbi.json | 16 +- src/contracts/abis/StakeCalculatorAbi.json | 161 +---------------- src/contracts/abis/UniswapPoolAbi.json | 59 ++++++- .../abis/UniswapPositionManagerAbi.json | 166 +++++++++++++++++- src/contracts/abis/UsdRateAbi.json | 36 +++- src/contracts/abis/V2RewardTokenAbi.json | 26 ++- src/contracts/abis/VaultFactoryAbi.json | 27 ++- src/contracts/abis/VaultsRegistryAbi.json | 22 ++- src/contracts/abis/VestingEscrowAbi.json | 81 ++++++++- .../abis/VestingEscrowFactoryAbi.json | 83 ++++++++- src/utils/configs/holesky.ts | 2 +- 16 files changed, 743 insertions(+), 173 deletions(-) diff --git a/src/contracts/abis/KeeperAbi.json b/src/contracts/abis/KeeperAbi.json index 1100eabe..930b6b64 100644 --- a/src/contracts/abis/KeeperAbi.json +++ b/src/contracts/abis/KeeperAbi.json @@ -1 +1,40 @@ -[ { "inputs": [ { "internalType": "address", "name": "vault", "type": "address" } ], "name": "isCollateralized", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "vault", "type": "address" } ], "name": "canHarvest", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" } ] +[ + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "isCollateralized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "canHarvest", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/MintTokenAbi.json b/src/contracts/abis/MintTokenAbi.json index 0f6cbaeb..2bc0c453 100644 --- a/src/contracts/abis/MintTokenAbi.json +++ b/src/contracts/abis/MintTokenAbi.json @@ -1 +1,46 @@ -[ { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" } ] +[ + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] diff --git a/src/contracts/abis/MintTokenConfigV1Abi.json b/src/contracts/abis/MintTokenConfigV1Abi.json index 7b2c290b..29ab7952 100644 --- a/src/contracts/abis/MintTokenConfigV1Abi.json +++ b/src/contracts/abis/MintTokenConfigV1Abi.json @@ -1 +1,28 @@ -[ { "inputs": [], "name": "ltvPercent", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "liqThresholdPercent", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" } ] +[ + { + "inputs": [], + "name": "ltvPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liqThresholdPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/MintTokenControllerAbi.json b/src/contracts/abis/MintTokenControllerAbi.json index 652dc853..dea3c5d1 100644 --- a/src/contracts/abis/MintTokenControllerAbi.json +++ b/src/contracts/abis/MintTokenControllerAbi.json @@ -1 +1,66 @@ -[ { "inputs": [ { "internalType": "uint256", "name": "assets", "type": "uint256" } ], "name": "convertToShares", "outputs": [ { "internalType": "uint256", "name": "shares", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "shares", "type": "uint256" } ], "name": "convertToAssets", "outputs": [ { "internalType": "uint256", "name": "assets", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "avgRewardPerSecond", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "feePercent", "outputs": [ { "internalType": "uint64", "name": "", "type": "uint64" } ], "stateMutability": "view", "type": "function" } ] +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "avgRewardPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feePercent", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/MulticallAbi.json b/src/contracts/abis/MulticallAbi.json index 8051c9d4..8f9a7c5a 100644 --- a/src/contracts/abis/MulticallAbi.json +++ b/src/contracts/abis/MulticallAbi.json @@ -1 +1,52 @@ -[{"inputs":[{"components":[{"name":"target","type":"address"},{"name":"callData","type":"bytes"}],"name":"calls","type":"tuple[]"}],"name":"aggregate","outputs":[{"name":"blockNumber","type":"uint256"},{"name":"returnData","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"getEthBalance","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] +[ + { + "inputs": [ + { + "components": [ + { + "name": "target", + "type": "address" + }, + { + "name": "callData", + "type": "bytes" + } + ], + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate", + "outputs": [ + { + "name": "blockNumber", + "type": "uint256" + }, + { + "name": "returnData", + "type": "bytes[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "name": "getEthBalance", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/PriceOracleAbi.json b/src/contracts/abis/PriceOracleAbi.json index 8b4e7155..d899a4e4 100644 --- a/src/contracts/abis/PriceOracleAbi.json +++ b/src/contracts/abis/PriceOracleAbi.json @@ -1 +1,15 @@ -[ { "inputs": [], "name": "latestAnswer", "outputs": [ { "internalType": "int256", "name": "", "type": "int256" } ], "stateMutability": "view", "type": "function" } ] +[ + { + "inputs": [], + "name": "latestAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/StakeCalculatorAbi.json b/src/contracts/abis/StakeCalculatorAbi.json index 28d500f8..6d4186d0 100644 --- a/src/contracts/abis/StakeCalculatorAbi.json +++ b/src/contracts/abis/StakeCalculatorAbi.json @@ -110,86 +110,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "vault", - "type": "address" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "internalType": "uint256", - "name": "unstakeAssets", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "rewardsRoot", - "type": "bytes32" - }, - { - "internalType": "int160", - "name": "reward", - "type": "int160" - }, - { - "internalType": "uint160", - "name": "unlockedMevReward", - "type": "uint160" - }, - { - "internalType": "bytes32[]", - "name": "proof", - "type": "bytes32[]" - } - ], - "internalType": "struct IKeeperRewards.HarvestParams", - "name": "harvestParams", - "type": "tuple" - } - ], - "internalType": "struct Helpers.UnstakeAssetsInput", - "name": "inputData", - "type": "tuple" - } - ], - "name": "calculateUnstakeAssets", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "unstakeAssets", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "unstakeShares", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "burnOsTokenShares", - "type": "uint256" - } - ], - "internalType": "struct Helpers.UnstakeAssetsOutput", - "name": "outputData", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -237,12 +157,12 @@ "type": "tuple" } ], - "internalType": "struct Helpers.UnstakeOsTokenSharesInput", + "internalType": "struct Helpers.UnstakeInput", "name": "inputData", "type": "tuple" } ], - "name": "calculateUnstakeOsTokenShares", + "name": "calculateUnstake", "outputs": [ { "components": [ @@ -251,88 +171,13 @@ "name": "unstakeOsTokenShares", "type": "uint256" }, - { - "internalType": "uint256", - "name": "swapOsTokenShares", - "type": "uint256" - }, { "internalType": "uint256", "name": "receivedAssets", "type": "uint256" } ], - "internalType": "struct Helpers.UnstakeOsTokenSharesOutput", - "name": "outputData", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "vault", - "type": "address" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "rewardsRoot", - "type": "bytes32" - }, - { - "internalType": "int160", - "name": "reward", - "type": "int160" - }, - { - "internalType": "uint160", - "name": "unlockedMevReward", - "type": "uint160" - }, - { - "internalType": "bytes32[]", - "name": "proof", - "type": "bytes32[]" - } - ], - "internalType": "struct IKeeperRewards.HarvestParams", - "name": "harvestParams", - "type": "tuple" - } - ], - "internalType": "struct Helpers.UnstakeAmountsInput", - "name": "inputData", - "type": "tuple" - } - ], - "name": "getUnstakeAmounts", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "maxUnstakeAssets", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxUnstakeOsTokenShares", - "type": "uint256" - } - ], - "internalType": "struct Helpers.UnstakeAmountsOutput", + "internalType": "struct Helpers.UnstakeOutput", "name": "outputData", "type": "tuple" } diff --git a/src/contracts/abis/UniswapPoolAbi.json b/src/contracts/abis/UniswapPoolAbi.json index ae333698..b8c6c718 100644 --- a/src/contracts/abis/UniswapPoolAbi.json +++ b/src/contracts/abis/UniswapPoolAbi.json @@ -1 +1,58 @@ -[{"inputs":[],"name":"liquidity","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"slot0","outputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"int24","name":"tick","type":"int24"},{"internalType":"uint16","name":"observationIndex","type":"uint16"},{"internalType":"uint16","name":"observationCardinality","type":"uint16"},{"internalType":"uint16","name":"observationCardinalityNext","type":"uint16"},{"internalType":"uint8","name":"feeProtocol","type":"uint8"},{"internalType":"bool","name":"unlocked","type":"bool"}],"stateMutability":"view","type":"function"}] +[ + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/UniswapPositionManagerAbi.json b/src/contracts/abis/UniswapPositionManagerAbi.json index 0992c74a..7c2d0430 100644 --- a/src/contracts/abis/UniswapPositionManagerAbi.json +++ b/src/contracts/abis/UniswapPositionManagerAbi.json @@ -1 +1,165 @@ -[{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"positions","outputs":[{"internalType":"uint96","name":"nonce","type":"uint96"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"feeGrowthInside0LastX128","type":"uint256"},{"internalType":"uint256","name":"feeGrowthInside1LastX128","type":"uint256"},{"internalType":"uint128","name":"tokensOwed0","type":"uint128"},{"internalType":"uint128","name":"tokensOwed1","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint128","name":"amount0Max","type":"uint128"},{"internalType":"uint128","name":"amount1Max","type":"uint128"}],"internalType":"struct INonfungiblePositionManager.CollectParams","name":"params","type":"tuple"}],"name":"collect","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"payable","type":"function"}] +[ + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint96", + "name": "nonce", + "type": "uint96" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Max", + "type": "uint128" + } + ], + "internalType": "struct INonfungiblePositionManager.CollectParams", + "name": "params", + "type": "tuple" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + } +] diff --git a/src/contracts/abis/UsdRateAbi.json b/src/contracts/abis/UsdRateAbi.json index e6c7c2e8..6f51d328 100644 --- a/src/contracts/abis/UsdRateAbi.json +++ b/src/contracts/abis/UsdRateAbi.json @@ -1 +1,35 @@ -[ { "inputs": [], "name": "latestRoundData", "outputs": [ { "internalType": "uint80", "name": "roundId", "type": "uint80" }, { "internalType": "int256", "name": "answer", "type": "int256" }, { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } ], "stateMutability": "view", "type": "function" } ] +[ + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/V2RewardTokenAbi.json b/src/contracts/abis/V2RewardTokenAbi.json index 1f4969c3..9758690d 100644 --- a/src/contracts/abis/V2RewardTokenAbi.json +++ b/src/contracts/abis/V2RewardTokenAbi.json @@ -1 +1,25 @@ -[ { "inputs": [ { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "uint256", "name": "principal", "type": "uint256" }, { "internalType": "uint256", "name": "reward", "type": "uint256" } ], "name": "migrate", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ] +[ + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "migrate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/contracts/abis/VaultFactoryAbi.json b/src/contracts/abis/VaultFactoryAbi.json index 93e20691..d836e938 100644 --- a/src/contracts/abis/VaultFactoryAbi.json +++ b/src/contracts/abis/VaultFactoryAbi.json @@ -1 +1,26 @@ -[ { "inputs": [ { "internalType": "bytes", "name": "params", "type": "bytes" }, { "internalType": "bool", "name": "isOwnMevEscrow", "type": "bool" } ], "name": "createVault", "outputs": [ { "internalType": "address", "name": "vault", "type": "address" } ], "stateMutability": "payable", "type": "function" } ] +[ + { + "inputs": [ + { + "internalType": "bytes", + "name": "params", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "isOwnMevEscrow", + "type": "bool" + } + ], + "name": "createVault", + "outputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + } +] diff --git a/src/contracts/abis/VaultsRegistryAbi.json b/src/contracts/abis/VaultsRegistryAbi.json index 27f11492..38135a7b 100644 --- a/src/contracts/abis/VaultsRegistryAbi.json +++ b/src/contracts/abis/VaultsRegistryAbi.json @@ -1 +1,21 @@ -[ { "inputs": [ { "internalType": "address", "name": "vault", "type": "address" } ], "name": "vaults", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" } ] +[ + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "vaults", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/VestingEscrowAbi.json b/src/contracts/abis/VestingEscrowAbi.json index d43b01c9..ad94890e 100644 --- a/src/contracts/abis/VestingEscrowAbi.json +++ b/src/contracts/abis/VestingEscrowAbi.json @@ -1 +1,80 @@ -[{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimedAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "endTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vestedAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/contracts/abis/VestingEscrowFactoryAbi.json b/src/contracts/abis/VestingEscrowFactoryAbi.json index df3894e5..0327bb39 100644 --- a/src/contracts/abis/VestingEscrowFactoryAbi.json +++ b/src/contracts/abis/VestingEscrowFactoryAbi.json @@ -1 +1,82 @@ -[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"address","name":"escrow","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cliffLength","type":"uint256"}],"name":"VestingEscrowCreated","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"}] +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "escrow", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cliffLength", + "type": "uint256" + } + ], + "name": "VestingEscrowCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "total", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 5301b6fc..8f652c63 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -51,7 +51,7 @@ export default { positionManager: ZeroAddress, }, special: { - stakeCalculator: '0x7151c611d7f76AFF8F53E87B3846Dc38C444dE0A', + stakeCalculator: '0x6228CD90A4aB2949eb27763205dA288E23dC09d1', }, }, tokens: { From 7c840c35f141faab7db35a57c2e8de9277d4d8c7 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Mon, 29 Jul 2024 16:05:33 +0500 Subject: [PATCH 08/36] [for-new-stake] new stakecalculator --- src/contracts/abis/StakeCalculatorAbi.json | 25 ++++++---------------- src/utils/configs/holesky.ts | 2 +- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/contracts/abis/StakeCalculatorAbi.json b/src/contracts/abis/StakeCalculatorAbi.json index 6d4186d0..70eeba9e 100644 --- a/src/contracts/abis/StakeCalculatorAbi.json +++ b/src/contracts/abis/StakeCalculatorAbi.json @@ -20,11 +20,6 @@ "internalType": "address", "name": "osTokenController", "type": "address" - }, - { - "internalType": "address", - "name": "osToken", - "type": "address" } ], "stateMutability": "nonpayable", @@ -168,7 +163,12 @@ "components": [ { "internalType": "uint256", - "name": "unstakeOsTokenShares", + "name": "burnOsTokenShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exitQueueShares", "type": "uint256" }, { @@ -184,18 +184,5 @@ ], "stateMutability": "nonpayable", "type": "function" - }, - { - "inputs": [], - "name": "maxLeftStakeAssetsPercent", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" } ] diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 8f652c63..bdffea1d 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -51,7 +51,7 @@ export default { positionManager: ZeroAddress, }, special: { - stakeCalculator: '0x6228CD90A4aB2949eb27763205dA288E23dC09d1', + stakeCalculator: '0x63De511Ff504E70109Bb8312d1329f2C88c14f77', }, }, tokens: { From c1426cea4007cc87784c209250080be4cd4c295b Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Tue, 6 Aug 2024 19:43:40 +0500 Subject: [PATCH 09/36] [for-new-stake] change address --- src/utils/configs/gnosis.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/configs/gnosis.ts b/src/utils/configs/gnosis.ts index 3e57fd49..7bc1b50a 100644 --- a/src/utils/configs/gnosis.ts +++ b/src/utils/configs/gnosis.ts @@ -51,7 +51,7 @@ export default { positionManager: ZeroAddress, }, special: { - stakeCalculator: ZeroAddress, + stakeCalculator: '0x3c5634a5437A394353F49fe04FE5db11961c5c2D', }, }, tokens: { From f897102015ff1b2b61222ebf5439940c1598ab6c Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Thu, 15 Aug 2024 15:33:57 +0500 Subject: [PATCH 10/36] [for-new-stake] improve versions --- src/StakeWiseSDK.ts | 18 ++++++++++++++++- .../osToken/requests/getOsTokenConfig.ts | 5 ++--- .../vault/transactions/operate/common.ts | 6 ++---- .../check/checkDepositDataManagerAccess.ts | 7 ++++--- .../vault/transactions/withdraw/common.ts | 6 ++---- src/utils/getValidLtvPercent.ts | 6 ++---- src/utils/getVaultVersion.ts | 20 +++++++++++++++++++ src/utils/index.ts | 1 + 8 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 src/utils/getVaultVersion.ts diff --git a/src/StakeWiseSDK.ts b/src/StakeWiseSDK.ts index a851cf76..e30a58e3 100644 --- a/src/StakeWiseSDK.ts +++ b/src/StakeWiseSDK.ts @@ -1,7 +1,16 @@ import methods from './methods' import { createContracts, vaultMulticall, rewardSplitterMulticall } from './contracts' -import { configs, getGas, createProvider, getVaultFactory, getVaultContract, VaultType } from './utils' + +import { + getGas, + configs, + VaultType, + createProvider, + getVaultFactory, + getVaultVersion, + getVaultContract, +} from './utils' type GetVaultFactoryInput = { vaultType?: VaultType, isErc20?: boolean } @@ -88,6 +97,13 @@ class StakeWiseSDK { }) } + getVaultVersion(vaultAddress: string) { + return getVaultVersion({ + contracts: this.contracts, + vaultAddress, + }) + } + get network() { return this.options.network } diff --git a/src/methods/osToken/requests/getOsTokenConfig.ts b/src/methods/osToken/requests/getOsTokenConfig.ts index 8f89ac1f..74f27bbc 100644 --- a/src/methods/osToken/requests/getOsTokenConfig.ts +++ b/src/methods/osToken/requests/getOsTokenConfig.ts @@ -1,4 +1,5 @@ import { wrapAbortPromise } from '../../../modules/gql-module' +import { getVaultVersion } from '../../../utils' export type GetOsTokenConfigInput = { @@ -14,9 +15,7 @@ type Output = { const getOsTokenData = async (input: GetOsTokenConfigInput) => { const { vaultAddress, contracts } = input - const vaultContract = contracts.helpers.createVault(vaultAddress) - const version = await vaultContract.version() - const isV1Version = version === 1n + const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) if (isV1Version) { const [ thresholdPercent, ltvPercent ] = await Promise.all([ diff --git a/src/methods/vault/transactions/operate/common.ts b/src/methods/vault/transactions/operate/common.ts index 3c08e247..550ad977 100644 --- a/src/methods/vault/transactions/operate/common.ts +++ b/src/methods/vault/transactions/operate/common.ts @@ -1,5 +1,5 @@ +import { validateArgs, getVaultVersion } from '../../../../utils' import type { MulticallTransactionInput } from './types' -import { validateArgs } from '../../../../utils' import { vaultMulticall } from '../../../../contracts' import { @@ -48,9 +48,7 @@ export const commonLogic = async (values: MulticallTransactionInput) => { vaultContract = contracts.helpers.createRestakingVault(vaultAddress) } - // Temporal logic while different types of vaults exist - const version = Number(await vaultContract.version()) - const isV1Version = version === 1 + const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) if (!isV1Version) { if (validatorsRoot) { diff --git a/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts b/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts index f9af31a8..ef61b48a 100644 --- a/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts +++ b/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts @@ -1,12 +1,13 @@ +import { getVaultVersion } from '../../../../../utils' import type { CheckInput } from './types' const checkDepositDataManagerAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { try { - const vaultContract = await contracts.helpers.createVault(vaultAddress) - const version = await vaultContract.version() + const vaultContract = contracts.helpers.createVault(vaultAddress) + const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) - const depositDataManager = version === 1n + const depositDataManager = isV1Version ? await vaultContract.keysManager() : await contracts.base.depositDataRegistry.getDepositDataManager(vaultAddress) diff --git a/src/methods/vault/transactions/withdraw/common.ts b/src/methods/vault/transactions/withdraw/common.ts index 845707c2..c89e809c 100644 --- a/src/methods/vault/transactions/withdraw/common.ts +++ b/src/methods/vault/transactions/withdraw/common.ts @@ -1,6 +1,6 @@ import type { WithdrawInput } from './types' -import { validateArgs } from '../../../../utils' import { vaultMulticall } from '../../../../contracts' +import { validateArgs, getVaultVersion } from '../../../../utils' export const commonLogic = async (values: WithdrawInput) => { @@ -13,11 +13,9 @@ export const commonLogic = async (values: WithdrawInput) => { const vaultContract = contracts.helpers.createVault(vaultAddress) - const version = Number(await vaultContract.version()) - // In the second version of the vault we do not use the redeem method, // the funds are always withdrawn via a queue - const isV1Version = version === 1 + const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) const baseMulticallArgs: Omit[0], 'request'> = { keeperContract: contracts.base.keeper, diff --git a/src/utils/getValidLtvPercent.ts b/src/utils/getValidLtvPercent.ts index 8ba42588..4cd6cffc 100644 --- a/src/utils/getValidLtvPercent.ts +++ b/src/utils/getValidLtvPercent.ts @@ -1,4 +1,5 @@ import validateArgs from './validateArgs' +import getVaultVersion from './getVaultVersion' type Input = { @@ -13,10 +14,7 @@ const getValidLtvPercent = async (values: Input) => { validateArgs.address({ vaultAddress }) validateArgs.bigint({ ltvPercent }) - const vaultContract = contracts.helpers.createVault(vaultAddress) - - const version = await vaultContract.version() - const isV1Version = version === 1n + const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) // in second+ version 100% ltv percent = 1 ether in wei const percent = isV1Version diff --git a/src/utils/getVaultVersion.ts b/src/utils/getVaultVersion.ts new file mode 100644 index 00000000..cb7ff694 --- /dev/null +++ b/src/utils/getVaultVersion.ts @@ -0,0 +1,20 @@ +type Input = { + vaultAddress: string + contracts: StakeWise.Contracts +} + +const getVaultVersion = async (values: Input) => { + const { contracts, vaultAddress } = values + + const vaultContract = contracts.helpers.createVault(vaultAddress) + + const version = await vaultContract.version() + const isV1Version = version === 1n + + return { + isV1Version, + } +} + + +export default getVaultVersion diff --git a/src/utils/index.ts b/src/utils/index.ts index 71b79fd4..a9dc9a48 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -7,6 +7,7 @@ export { default as constants } from './constants' export { default as BigDecimal } from './BigDecimal' export { default as validateArgs } from './validateArgs' export { default as createProvider } from './createProvider' +export { default as getVaultVersion } from './getVaultVersion' export { default as getNetworkTypes } from './getNetworkTypes' export { default as getVaultFactory } from './getVaultFactory' export { default as getVaultContract } from './getVaultContract' From 9cd977649106683e5d3d1713e4a50ae0af580865 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Tue, 20 Aug 2024 17:36:10 +0500 Subject: [PATCH 11/36] [for-new-stake] open AbortPromise --- src/index.ts | 1 + src/modules/gql-module/index.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index a408c66f..d6741a51 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,5 +6,6 @@ export * from './utils/enums' export { createContract } from './contracts' export { default as StakeWiseSDK } from './StakeWiseSDK' export { BigDecimal, configs, getGas, createProvider } from './utils' +export { wrapAbortPromise, AbortPromise } from './modules/gql-module' export const chains = constants.chains diff --git a/src/modules/gql-module/index.ts b/src/modules/gql-module/index.ts index 090385e6..352e0d23 100644 --- a/src/modules/gql-module/index.ts +++ b/src/modules/gql-module/index.ts @@ -1,3 +1,4 @@ export { default as graphqlFetch } from './graphqlFetch' +export { default as AbortPromise } from './abortPromise' export type { FetchCodegenInput, FetchInput } from './types' export { default as wrapAbortPromise } from './wrapAbortPromise' From 193187bdac66650e25ed07a997f72891fd38f088 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Thu, 12 Sep 2024 15:03:38 +0500 Subject: [PATCH 12/36] [for-new-stake] replace address --- src/utils/configs/gnosis.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/configs/gnosis.ts b/src/utils/configs/gnosis.ts index 2841fc5e..c6f92ef1 100644 --- a/src/utils/configs/gnosis.ts +++ b/src/utils/configs/gnosis.ts @@ -45,7 +45,7 @@ export default { erc20BlocklistVault: '0x99E4300326867FE3f97864a74e500d19654c19e9', }, special: { - stakeCalculator: '0x3c5634a5437A394353F49fe04FE5db11961c5c2D', + stakeCalculator: '0x9747e1fF73f1759217AFD212Dd36d21360D0880A', }, }, tokens: { From d7e09fe2d61614f3132d930c2887641184390cb7 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Thu, 12 Sep 2024 18:31:55 +0500 Subject: [PATCH 13/36] [for-new-stake] change exit queue --- .../subgraph/exitQueue/exitQueueQuery.graphql | 1 + .../getExitQueuePositions/parseExitRequests.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql index 7ab0f527..2a5d6909 100644 --- a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql +++ b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql @@ -5,6 +5,7 @@ query exitQueue($receiver: Bytes, $vault: String!) { }) { withdrawalTimestamp positionTicket + isV2Position totalShares totalAssets timestamp diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts index 9b34bfdc..e746672d 100644 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts +++ b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts @@ -4,6 +4,7 @@ import vaultMulticall from '../../../../contracts/multicall/vaultMulticall' type ExitRequest = { withdrawalTimestamp: string | null positionTicket: string + isV2Position: boolean totalShares: string totalAssets: string timestamp: string @@ -21,7 +22,7 @@ export type ParseExitRequestsInput = { type Position = { exitQueueIndex: bigint positionTicket: string - isV1Position: boolean + isV2Position: boolean timestamp: string } @@ -115,7 +116,7 @@ const parseExitRequests = async (values: ParseExitRequestsInput): Promise 0 - const item = { exitQueueIndex, positionTicket, timestamp, isV1Position } + const item = { exitQueueIndex, positionTicket, timestamp, isV2Position } claims.push(item) } @@ -180,14 +180,14 @@ const parseExitRequests = async (values: ParseExitRequestsInput): Promise { - const { isV1Position } = claims[i] + const { isV2Position } = claims[i] - if (isV1Position) { - // in V1 exit queue exit tickets are shares - queuedShares -= BigInt(exitedTickets || 0) + if (isV2Position) { + // in V2 vaults exit queue exit tickets are assets, for v1 and v3+ will be shares + queuedAssets -= BigInt(exitedAssets || 0) } else { - queuedAssets -= BigInt(exitedAssets || 0) + queuedShares -= BigInt(exitedTickets || 0) } withdrawableAssets += BigInt(exitedAssets || 0) From 862891ac5ca33167027aaa7933a34dd491fd09bd Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Tue, 17 Sep 2024 16:54:16 +0500 Subject: [PATCH 14/36] [for-new-stake] change logic --- codegen.ts | 2 +- src/methods/osToken/index.ts | 4 ++-- .../getOsTokenPositionShares.ts => getPosition/getShares.ts} | 4 ++-- .../requests/{getOsTokenPosition => getPosition}/index.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename src/methods/osToken/requests/{getOsTokenPosition/getOsTokenPositionShares.ts => getPosition/getShares.ts} (81%) rename src/methods/osToken/requests/{getOsTokenPosition => getPosition}/index.ts (90%) diff --git a/codegen.ts b/codegen.ts index a1f113a4..64aee880 100644 --- a/codegen.ts +++ b/codegen.ts @@ -5,7 +5,7 @@ import configs from './src/utils/configs' // For every network we have same gql shema, so we can use just Mainnet here -const urls = configs[Network.Holesky].api +const urls = configs[Network.Gnosis].api // https://the-guild.dev/graphql/codegen/plugins/typescript/typescript const typesConfig = { diff --git a/src/methods/osToken/index.ts b/src/methods/osToken/index.ts index 734d68a4..9ebede40 100644 --- a/src/methods/osToken/index.ts +++ b/src/methods/osToken/index.ts @@ -1,10 +1,10 @@ // Requests import getAPY from './requests/getOsTokenAPY' -import getRate from './requests/getOsTokenRate' import getMaxMint from './requests/getMaxMint' +import getRate from './requests/getOsTokenRate' +import getPosition from './requests/getPosition' import getConfig from './requests/getOsTokenConfig' import getBurnAmount from './helpers/getBurnAmount' -import getPosition from './requests/getOsTokenPosition' import getHealthFactor from './helpers/getHealthFactor' import getSharesFromAssets from './requests/getSharesFromAssets' import getAssetsFromShares from './requests/getAssetsFromShares' diff --git a/src/methods/osToken/requests/getOsTokenPosition/getOsTokenPositionShares.ts b/src/methods/osToken/requests/getPosition/getShares.ts similarity index 81% rename from src/methods/osToken/requests/getOsTokenPosition/getOsTokenPositionShares.ts rename to src/methods/osToken/requests/getPosition/getShares.ts index 29ba10c4..89a119c6 100644 --- a/src/methods/osToken/requests/getOsTokenPosition/getOsTokenPositionShares.ts +++ b/src/methods/osToken/requests/getPosition/getShares.ts @@ -8,7 +8,7 @@ type GetOsTokenPositionSharesInput = { options: StakeWise.Options } -const getOsTokenPositionShares = (values: GetOsTokenPositionSharesInput) => { +const getShares = (values: GetOsTokenPositionSharesInput) => { const { options, vaultAddress, userAddress } = values return graphql.subgraph.osToken.fetchOsTokenPositionsQuery({ @@ -22,4 +22,4 @@ const getOsTokenPositionShares = (values: GetOsTokenPositionSharesInput) => { } -export default getOsTokenPositionShares +export default getShares diff --git a/src/methods/osToken/requests/getOsTokenPosition/index.ts b/src/methods/osToken/requests/getPosition/index.ts similarity index 90% rename from src/methods/osToken/requests/getOsTokenPosition/index.ts rename to src/methods/osToken/requests/getPosition/index.ts index 9272e80e..56a9110e 100644 --- a/src/methods/osToken/requests/getOsTokenPosition/index.ts +++ b/src/methods/osToken/requests/getPosition/index.ts @@ -1,5 +1,5 @@ +import getShares from './getShares' import getHealthFactor from '../../helpers/getHealthFactor' -import getOsTokenPositionShares from './getOsTokenPositionShares' import { wrapAbortPromise } from '../../../../modules/gql-module' import { validateArgs, OsTokenPositionHealth } from '../../../../utils' @@ -32,7 +32,7 @@ const getOsTokenPosition = async (values: GetOsTokenPositionInput) => { validateArgs.address({ vaultAddress, userAddress }) validateArgs.bigint({ stakedAssets, thresholdPercent }) - const gqlMintedShares = await getOsTokenPositionShares({ options, vaultAddress, userAddress }) + const gqlMintedShares = await getShares({ options, vaultAddress, userAddress }) const vaultContract = contracts.helpers.createVault(vaultAddress) const mintedShares = await vaultContract.osTokenPositions(userAddress) From 11fcf5e5813bf7a68b3efcfffce7a72b868c3cf4 Mon Sep 17 00:00:00 2001 From: CAst Date: Fri, 20 Sep 2024 17:29:26 +0500 Subject: [PATCH 15/36] New createVault method (#169) * [improve-abi-diff] new createVault method * [improve-abi-diff] gitignor * [improve-abi-diff] fix --- .gitignore | 1 + codegen.ts | 1 + package.json | 4 +- src/StakeWiseSDK.ts | 16 +-- src/contracts/abis/index.js | 24 +---- src/contracts/createContracts.ts | 17 +-- src/contracts/multicall/types.d.ts | 4 +- .../multicall/util/getSignedContract.ts | 2 +- src/contracts/multicall/vaultMulticall.ts | 3 +- .../abis/BlocklistVaultDiffAbi.json | 0 .../{ => vault}/abis/GenesisVaultDiffAbi.json | 0 .../{ => vault}/abis/GnosisVaultDiffAbi.json | 0 .../abis/NativeTokenVaultAbi.json} | 0 .../{ => vault}/abis/OtherTokenVaultAbi.json | 0 .../{ => vault}/abis/PrivateVaultDiffAbi.json | 0 .../abis/RestakingVaultDiffAbi.json | 0 src/contracts/vault/abis/index.js | 18 ++++ src/contracts/vault/createVaultContract.ts | 102 ++++++++++++++++++ src/contracts/vault/index.ts | 1 + .../osToken/requests/getPosition/index.ts | 2 +- .../osToken/transactions/burn/common.ts | 2 +- .../osToken/transactions/mint/common.ts | 2 +- .../getClaimAmount/getAssetsFromShares.ts | 2 +- .../claimRewards/getSharesFromAssets.ts | 2 +- .../parseExitRequests.ts | 2 +- src/methods/vault/requests/getStakeBalance.ts | 2 +- .../transactions/claimExitQueue/common.ts | 2 +- .../transactions/createEigenPod/common.ts | 7 +- .../deposit/nativeToken/common.ts | 2 +- .../transactions/deposit/otherToken/common.ts | 7 +- .../vault/transactions/operate/common.ts | 32 ++++-- .../util/check/checkAdminAccess.ts | 2 +- .../util/check/checkBlocklistManagerAccess.ts | 6 +- .../check/checkDepositDataManagerAccess.ts | 2 +- .../checkRestakeOperatorsManagerAccess.ts | 6 +- .../util/check/checkWhitelisterAccess.ts | 6 +- .../vault/transactions/withdraw/common.ts | 2 +- src/types/global.ts | 14 --- src/utils/getVaultContract.ts | 23 ---- src/utils/getVaultVersion.ts | 2 +- src/utils/index.ts | 1 - 41 files changed, 206 insertions(+), 115 deletions(-) rename src/contracts/{ => vault}/abis/BlocklistVaultDiffAbi.json (100%) rename src/contracts/{ => vault}/abis/GenesisVaultDiffAbi.json (100%) rename src/contracts/{ => vault}/abis/GnosisVaultDiffAbi.json (100%) rename src/contracts/{abis/VaultAbi.json => vault/abis/NativeTokenVaultAbi.json} (100%) rename src/contracts/{ => vault}/abis/OtherTokenVaultAbi.json (100%) rename src/contracts/{ => vault}/abis/PrivateVaultDiffAbi.json (100%) rename src/contracts/{ => vault}/abis/RestakingVaultDiffAbi.json (100%) create mode 100644 src/contracts/vault/abis/index.js create mode 100644 src/contracts/vault/createVaultContract.ts create mode 100644 src/contracts/vault/index.ts delete mode 100644 src/utils/getVaultContract.ts diff --git a/.gitignore b/.gitignore index c61e6b02..438ea144 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ node_modules schema.graphql src/types/graphql src/contracts/types +src/contracts/vault/types diff --git a/codegen.ts b/codegen.ts index 64aee880..7bc9b290 100644 --- a/codegen.ts +++ b/codegen.ts @@ -4,6 +4,7 @@ import { Network } from './src/utils/enums' import configs from './src/utils/configs' +// TODO change to Holesky // For every network we have same gql shema, so we can use just Mainnet here const urls = configs[Network.Gnosis].api diff --git a/package.json b/package.json index 3c662932..e646e24e 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "test": "jest --clearCache && jest --onlyChanged", "prepare": "npm run typechain && npm run graphql && npm run beforePublish", "build": "npm run test && npm run prepare && rm -rf ./dist && npm run rollup", - "typechain": "typechain --target ethers-v6 --out-dir src/contracts/types 'src/contracts/abis/*.json'", + "typechain:vault": "typechain --target ethers-v6 --out-dir src/contracts/vault/types 'src/contracts/vault/abis/*.json'", + "typechain:base": "typechain --target ethers-v6 --out-dir src/contracts/types 'src/contracts/abis/*.json'", + "typechain": "npm run typechain:base && npm run typechain:vault", "graphql": "graphql-codegen && ts-node -O '{\"module\": \"commonjs\"}' ./scripts/generateGraphqlExports", "rollup": "rollup --config rollup.config.js --bundleConfigAsCjs", "beforePublish": "node ./scripts/beforePublish", diff --git a/src/StakeWiseSDK.ts b/src/StakeWiseSDK.ts index 993cb07e..6ef7916e 100644 --- a/src/StakeWiseSDK.ts +++ b/src/StakeWiseSDK.ts @@ -9,7 +9,6 @@ import { createProvider, getVaultFactory, getVaultVersion, - getVaultContract, } from './utils' @@ -53,12 +52,18 @@ class StakeWiseSDK { this.rewardSplitter = methods.createRewardSplitterMethods(argsForMethods) } - vaultMulticall(values: VaultMulticallInput) { + async vaultMulticall(values: VaultMulticallInput) { const { userAddress, vaultAddress, request } = values - const vaultContract = getVaultContract({ - contracts: this.contracts, - network: this.network, + const { isBlocklist, isPrivate, isRestake } = await this.vault.getVault({ vaultAddress }) + + const vaultContract = this.contracts.helpers.createVault({ + options: { + chainId: this.config.network.chainId, + isBlocklist, + isPrivate, + isRestake, + }, vaultAddress, }) @@ -79,7 +84,6 @@ class StakeWiseSDK { }) } - rewardSplitterMulticall(values: RewardSplitterMulticallInput) { const { userAddress, vaultAddress, rewardSplitterAddress, request } = values diff --git a/src/contracts/abis/index.js b/src/contracts/abis/index.js index 75e37e68..b9868193 100644 --- a/src/contracts/abis/index.js +++ b/src/contracts/abis/index.js @@ -2,15 +2,10 @@ import RewardSplitterFactoryAbi from './RewardSplitterFactoryAbi.json' import VestingEscrowFactoryAbi from './VestingEscrowFactoryAbi.json' import MintTokenControllerAbi from './MintTokenControllerAbi.json' import DepositDataRegistryAbi from './DepositDataRegistryAbi.json' -import InitialOtherTokenVaultAbi from './OtherTokenVaultAbi.json' -import BlocklistVaultDiffAbi from './BlocklistVaultDiffAbi.json' -import RestakingVaultDiffAbi from './RestakingVaultDiffAbi.json' import MerkleDistributorAbi from './MerkleDistributorAbi.json' import MintTokenConfigV1Abi from './MintTokenConfigV1Abi.json' import MintTokenConfigV2Abi from './MintTokenConfigV2Abi.json' -import PrivateVaultDiffAbi from './PrivateVaultDiffAbi.json' -import GenesisVaultDiffAbi from './GenesisVaultDiffAbi.json' -import GnosisVaultDiffAbi from './GnosisVaultDiffAbi.json' + import StakeCalculatorAbi from './StakeCalculatorAbi.json' import VaultsRegistryAbi from './VaultsRegistryAbi.json' import RewardSplitterAbi from './RewardSplitterAbi.json' @@ -20,22 +15,13 @@ import VestingEscrowAbi from './VestingEscrowAbi.json' import VaultFactoryAbi from './VaultFactoryAbi.json' import PriceOracleAbi from './PriceOracleAbi.json' import MulticallAbi from './MulticallAbi.json' -import InitialVaultAbi from './VaultAbi.json' + import UsdRateAbi from './UsdRateAbi.json' import OraclesAbi from './OraclesAbi.json' import KeeperAbi from './KeeperAbi.json' import Erc20Abi from './Erc20Abi.json' -// ATTN temp solution to handle swapXdaiToGno, need to fix within https://app.clickup.com/t/8694zcfv8 -const VaultAbi = InitialVaultAbi.concat(GnosisVaultDiffAbi) -const OtherTokenVaultAbi = InitialOtherTokenVaultAbi.concat(GnosisVaultDiffAbi) - -const GenesisVaultAbi = VaultAbi.concat(GenesisVaultDiffAbi) -const PrivateVaultAbi = VaultAbi.concat(PrivateVaultDiffAbi) -const BlocklistVaultAbi = VaultAbi.concat(BlocklistVaultDiffAbi) -const RestakingVaultAbi = VaultAbi.concat(RestakingVaultDiffAbi) - export { RewardSplitterFactoryAbi, VestingEscrowFactoryAbi, @@ -45,22 +31,16 @@ export { MintTokenConfigV1Abi, MintTokenConfigV2Abi, StakeCalculatorAbi, - OtherTokenVaultAbi, VaultsRegistryAbi, - RestakingVaultAbi, RewardSplitterAbi, - BlocklistVaultAbi, V2RewardTokenAbi, EigenPodOwnerAbi, VestingEscrowAbi, - PrivateVaultAbi, - GenesisVaultAbi, VaultFactoryAbi, PriceOracleAbi, MulticallAbi, OraclesAbi, UsdRateAbi, KeeperAbi, - VaultAbi, Erc20Abi, } diff --git a/src/contracts/createContracts.ts b/src/contracts/createContracts.ts index e98d4f60..fc53f0b0 100644 --- a/src/contracts/createContracts.ts +++ b/src/contracts/createContracts.ts @@ -3,24 +3,18 @@ import type { Provider } from 'ethers' import { Erc20Abi, - VaultAbi, KeeperAbi, OraclesAbi, UsdRateAbi, MulticallAbi, PriceOracleAbi, - GenesisVaultAbi, - PrivateVaultAbi, VaultFactoryAbi, VestingEscrowAbi, EigenPodOwnerAbi, V2RewardTokenAbi, - BlocklistVaultAbi, VaultsRegistryAbi, RewardSplitterAbi, - RestakingVaultAbi, StakeCalculatorAbi, - OtherTokenVaultAbi, MintTokenConfigV1Abi, MintTokenConfigV2Abi, MerkleDistributorAbi, @@ -32,6 +26,7 @@ import { import commonMulticall from './multicall/commonMulticall' import createContract from './createContract' +import { createVaultContract } from './vault' const getSwiseToken = (provider: Provider, config: StakeWise.Config) => createContract( @@ -138,10 +133,12 @@ type CreateContractsInput = { export const createContracts = (input: CreateContractsInput) => { const { provider, config } = input + const createVault = createVaultContract(provider) const multicallContract = getMulticall(provider, config) return { helpers: { + createVault, multicallContract, createMulticall: commonMulticall(multicallContract as StakeWise.ABI.Multicall), createErc20: (address: string) => createContract(address, Erc20Abi, provider), @@ -150,14 +147,6 @@ export const createContracts = (input: CreateContractsInput) => { createVestingEscrowDirect: (address: string) => createContract(address, VestingEscrowAbi, provider), createUsdRate: (address: string, _provider?: Provider) => createContract(address, UsdRateAbi, _provider || provider), createVestingEscrowFactory: (address: string) => createContract(address, VestingEscrowFactoryAbi, provider), - - // Vaults - createVault: (address: string) => createContract(address, VaultAbi, provider), - createPrivateVault: (address: string) => createContract(address, PrivateVaultAbi, provider), - createRestakingVault: (address: string) => createContract(address, RestakingVaultAbi, provider), - createBlocklistedVault: (address: string) => createContract(address, BlocklistVaultAbi, provider), - createOtherTokenVault: (address: string) => createContract(address, OtherTokenVaultAbi, provider), - createGenesisVault: (address: string) => createContract(address, GenesisVaultAbi, provider), }, base: { keeper: getKeeper(provider, config), diff --git a/src/contracts/multicall/types.d.ts b/src/contracts/multicall/types.d.ts index 18fdd9b8..a6567980 100644 --- a/src/contracts/multicall/types.d.ts +++ b/src/contracts/multicall/types.d.ts @@ -1,4 +1,4 @@ -import { VaultAbi, RewardSplitterAbi, OtherTokenVaultAbi, EigenPodOwnerAbi } from '../types' +import { VaultAbi, RewardSplitterAbi, EigenPodOwnerAbi } from '../types' export type MulticallParameter = { @@ -13,4 +13,4 @@ export type MulticallRequestInput = { transactionData?: boolean } -export type ContractAbi = VaultAbi | OtherTokenVaultAbi | RewardSplitterAbi | EigenPodOwnerAbi +export type ContractAbi = ReturnType | RewardSplitterAbi | EigenPodOwnerAbi diff --git a/src/contracts/multicall/util/getSignedContract.ts b/src/contracts/multicall/util/getSignedContract.ts index 40aec046..6f841319 100644 --- a/src/contracts/multicall/util/getSignedContract.ts +++ b/src/contracts/multicall/util/getSignedContract.ts @@ -4,8 +4,8 @@ import { MulticallRequestInput, ContractAbi } from '../types' type Input = { - contract: ContractAbi userAddress: string + contract: ContractAbi options: StakeWise.Options request: MulticallRequestInput } diff --git a/src/contracts/multicall/vaultMulticall.ts b/src/contracts/multicall/vaultMulticall.ts index 2691ba15..1d4f0d30 100644 --- a/src/contracts/multicall/vaultMulticall.ts +++ b/src/contracts/multicall/vaultMulticall.ts @@ -9,11 +9,10 @@ import { } from './util' import type { MulticallRequestInput } from './types' -import type { OtherTokenVaultAbi, VaultAbi } from '../types' import { Network } from '../../utils' -type VaultContractAbi = VaultAbi | OtherTokenVaultAbi +type VaultContractAbi = ReturnType export type VaultMulticallBaseInput = { userAddress: string diff --git a/src/contracts/abis/BlocklistVaultDiffAbi.json b/src/contracts/vault/abis/BlocklistVaultDiffAbi.json similarity index 100% rename from src/contracts/abis/BlocklistVaultDiffAbi.json rename to src/contracts/vault/abis/BlocklistVaultDiffAbi.json diff --git a/src/contracts/abis/GenesisVaultDiffAbi.json b/src/contracts/vault/abis/GenesisVaultDiffAbi.json similarity index 100% rename from src/contracts/abis/GenesisVaultDiffAbi.json rename to src/contracts/vault/abis/GenesisVaultDiffAbi.json diff --git a/src/contracts/abis/GnosisVaultDiffAbi.json b/src/contracts/vault/abis/GnosisVaultDiffAbi.json similarity index 100% rename from src/contracts/abis/GnosisVaultDiffAbi.json rename to src/contracts/vault/abis/GnosisVaultDiffAbi.json diff --git a/src/contracts/abis/VaultAbi.json b/src/contracts/vault/abis/NativeTokenVaultAbi.json similarity index 100% rename from src/contracts/abis/VaultAbi.json rename to src/contracts/vault/abis/NativeTokenVaultAbi.json diff --git a/src/contracts/abis/OtherTokenVaultAbi.json b/src/contracts/vault/abis/OtherTokenVaultAbi.json similarity index 100% rename from src/contracts/abis/OtherTokenVaultAbi.json rename to src/contracts/vault/abis/OtherTokenVaultAbi.json diff --git a/src/contracts/abis/PrivateVaultDiffAbi.json b/src/contracts/vault/abis/PrivateVaultDiffAbi.json similarity index 100% rename from src/contracts/abis/PrivateVaultDiffAbi.json rename to src/contracts/vault/abis/PrivateVaultDiffAbi.json diff --git a/src/contracts/abis/RestakingVaultDiffAbi.json b/src/contracts/vault/abis/RestakingVaultDiffAbi.json similarity index 100% rename from src/contracts/abis/RestakingVaultDiffAbi.json rename to src/contracts/vault/abis/RestakingVaultDiffAbi.json diff --git a/src/contracts/vault/abis/index.js b/src/contracts/vault/abis/index.js new file mode 100644 index 00000000..eaa48605 --- /dev/null +++ b/src/contracts/vault/abis/index.js @@ -0,0 +1,18 @@ +import BlocklistVaultDiffAbi from './BlocklistVaultDiffAbi.json' +import RestakingVaultDiffAbi from './RestakingVaultDiffAbi.json' +import PrivateVaultDiffAbi from './PrivateVaultDiffAbi.json' +import NativeTokenVaultAbi from './NativeTokenVaultAbi.json' +import GenesisVaultDiffAbi from './GenesisVaultDiffAbi.json' +import OtherTokenVaultAbi from './OtherTokenVaultAbi.json' +import GnosisVaultDiffAbi from './GnosisVaultDiffAbi.json' + + +export { + GnosisVaultDiffAbi, + OtherTokenVaultAbi, + NativeTokenVaultAbi, + PrivateVaultDiffAbi, + GenesisVaultDiffAbi, + BlocklistVaultDiffAbi, + RestakingVaultDiffAbi, +} diff --git a/src/contracts/vault/createVaultContract.ts b/src/contracts/vault/createVaultContract.ts new file mode 100644 index 00000000..cfa85771 --- /dev/null +++ b/src/contracts/vault/createVaultContract.ts @@ -0,0 +1,102 @@ +import type { Provider } from 'ethers' + + +import { + GnosisVaultDiffAbi, + OtherTokenVaultAbi, + NativeTokenVaultAbi, + PrivateVaultDiffAbi, + GenesisVaultDiffAbi, + BlocklistVaultDiffAbi, + RestakingVaultDiffAbi, +} from './abis' + +import { + GnosisVaultDiffAbi as GnosisVaultDiffType, + OtherTokenVaultAbi as OtherTokenVaultType, + GenesisVaultDiffAbi as GenesisVaultDiffType, + NativeTokenVaultAbi as NativeTokenVaultType, + PrivateVaultDiffAbi as PrivateVaultDiffType, + BlocklistVaultDiffAbi as BlocklistVaultDiffType, + RestakingVaultDiffAbi as RestakingVaultDiffType, +} from './types' + +import { Network } from '../../utils' +import createContract from '../createContract' +import { ModifiedVault } from '../../methods/vault/requests/getVault/types' + + +type Options = Partial> & { + chainId?: Network + isGenesis?: boolean +} + +type CreateContractsInput = { + vaultAddress: string + options?: T +} + +type Output = Omit< + (T['chainId'] extends Network.Chiado | Network.Gnosis + ? OtherTokenVaultType & GnosisVaultDiffType + : NativeTokenVaultType + ) & + (T['isBlocklist'] extends true + ? BlocklistVaultDiffType + : object + ) & + (T['isRestake'] extends true + ? RestakingVaultDiffType + : object + ) & + (T['isPrivate'] extends true + ? PrivateVaultDiffType + : object + ) & + (T['isGenesis'] extends true + ? GenesisVaultDiffType + : object + ), + 'connect' +> & { + // overwrite, since each abi returns itself + connect: (signer: any) => Output +} + +const createVaultContract = (provider: Provider) => ( + (input: CreateContractsInput): Output => { + const { vaultAddress, options } = input + + const isGnosis = [ + Network.Chiado, + Network.Gnosis, + ].includes(options?.chainId || Network.Mainnet) + + let baseAbi = isGnosis + ? OtherTokenVaultAbi.concat(GnosisVaultDiffAbi) + : NativeTokenVaultAbi + + if (options?.isBlocklist) { + baseAbi = baseAbi.concat(BlocklistVaultDiffAbi) + } + + if (options?.isPrivate) { + baseAbi = baseAbi.concat(PrivateVaultDiffAbi) + } + + if (options?.isRestake) { + baseAbi = baseAbi.concat(RestakingVaultDiffAbi) + } + + if (options?.isGenesis) { + baseAbi = baseAbi.concat(GenesisVaultDiffAbi) + } + + return createContract(vaultAddress, baseAbi, provider) as Output & { + connect: () => Output + } + } +) + + +export default createVaultContract diff --git a/src/contracts/vault/index.ts b/src/contracts/vault/index.ts new file mode 100644 index 00000000..30890a42 --- /dev/null +++ b/src/contracts/vault/index.ts @@ -0,0 +1 @@ +export { default as createVaultContract } from './createVaultContract' diff --git a/src/methods/osToken/requests/getPosition/index.ts b/src/methods/osToken/requests/getPosition/index.ts index 56a9110e..432e68d2 100644 --- a/src/methods/osToken/requests/getPosition/index.ts +++ b/src/methods/osToken/requests/getPosition/index.ts @@ -34,7 +34,7 @@ const getOsTokenPosition = async (values: GetOsTokenPositionInput) => { const gqlMintedShares = await getShares({ options, vaultAddress, userAddress }) - const vaultContract = contracts.helpers.createVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ vaultAddress }) const mintedShares = await vaultContract.osTokenPositions(userAddress) const [ mintedAssets, feePercent ] = await Promise.all([ diff --git a/src/methods/osToken/transactions/burn/common.ts b/src/methods/osToken/transactions/burn/common.ts index c8156a09..70a81da3 100644 --- a/src/methods/osToken/transactions/burn/common.ts +++ b/src/methods/osToken/transactions/burn/common.ts @@ -8,7 +8,7 @@ export const commonLogic = (values: BurnInput) => { validateArgs.bigint({ shares }) validateArgs.address({ vaultAddress, userAddress }) - const vaultContract = contracts.helpers.createVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ vaultAddress }) return vaultContract } diff --git a/src/methods/osToken/transactions/mint/common.ts b/src/methods/osToken/transactions/mint/common.ts index c39696bd..a895567c 100644 --- a/src/methods/osToken/transactions/mint/common.ts +++ b/src/methods/osToken/transactions/mint/common.ts @@ -12,7 +12,7 @@ export const commonLogic = (values: MintInput) => { validateArgs.address({ vaultAddress, userAddress }) const multicallArgs: Omit[0], 'request'> = { - vaultContract: contracts.helpers.createVault(vaultAddress), + vaultContract: contracts.helpers.createVault({ vaultAddress }), vaultAddress, userAddress, options, diff --git a/src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts b/src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts index 6ea0f7ec..376f259c 100644 --- a/src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts +++ b/src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts @@ -24,7 +24,7 @@ const getAssetsFromShares = async (input: GetAssetsFromSharesInput) => { options, userAddress, vaultAddress, - vaultContract: contracts.helpers.createVault(vaultAddress), + vaultContract: contracts.helpers.createVault({ vaultAddress }), }) return result?.[0]?.assets | 0n diff --git a/src/methods/rewardSplitter/transactions/claimRewards/getSharesFromAssets.ts b/src/methods/rewardSplitter/transactions/claimRewards/getSharesFromAssets.ts index ebec80e7..d7a933a8 100644 --- a/src/methods/rewardSplitter/transactions/claimRewards/getSharesFromAssets.ts +++ b/src/methods/rewardSplitter/transactions/claimRewards/getSharesFromAssets.ts @@ -24,7 +24,7 @@ const getSharesFromAssets = async (input: GetSharesFromAssetsInput) => { options, userAddress, vaultAddress, - vaultContract: contracts.helpers.createVault(vaultAddress), + vaultContract: contracts.helpers.createVault({ vaultAddress }), }) return result?.[0]?.shares | 0n diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts index e746672d..eb84f323 100644 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts +++ b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts @@ -85,7 +85,7 @@ const parseExitRequests = async (values: ParseExitRequestsInput): Promise { validateArgs.address({ vaultAddress, userAddress }) - const vaultContract = contracts.helpers.createVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ vaultAddress }) const balanceShares = await vaultContract.getShares(userAddress) diff --git a/src/methods/vault/transactions/claimExitQueue/common.ts b/src/methods/vault/transactions/claimExitQueue/common.ts index 17424917..c4e11b45 100644 --- a/src/methods/vault/transactions/claimExitQueue/common.ts +++ b/src/methods/vault/transactions/claimExitQueue/common.ts @@ -19,7 +19,7 @@ export const commonLogic = (values: ClaimExitQueueInput) => { validatePositions(positions) const baseMulticallArgs: VaultMulticallBaseInput = { - vaultContract: contracts.helpers.createVault(vaultAddress), + vaultContract: contracts.helpers.createVault({ vaultAddress }), vaultAddress, userAddress, options, diff --git a/src/methods/vault/transactions/createEigenPod/common.ts b/src/methods/vault/transactions/createEigenPod/common.ts index 5fa54ff2..a809902f 100644 --- a/src/methods/vault/transactions/createEigenPod/common.ts +++ b/src/methods/vault/transactions/createEigenPod/common.ts @@ -7,5 +7,10 @@ export const commonLogic = async (values: CreateEigenPodInput) => { validateArgs.address({ vaultAddress, userAddress }) - return contracts.helpers.createRestakingVault(vaultAddress) + const contract = contracts.helpers.createVault({ + options: { isRestake: true }, + vaultAddress, + }) + + return contract } diff --git a/src/methods/vault/transactions/deposit/nativeToken/common.ts b/src/methods/vault/transactions/deposit/nativeToken/common.ts index 6280cf6c..e9201ada 100644 --- a/src/methods/vault/transactions/deposit/nativeToken/common.ts +++ b/src/methods/vault/transactions/deposit/nativeToken/common.ts @@ -10,7 +10,7 @@ export const commonLogic = async (values: DepositInput) => { validateArgs.bigint({ assets }) validateArgs.address({ vaultAddress, userAddress }) - const vaultContract = contracts.helpers.createVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ vaultAddress }) const canHarvest = await contracts.base.keeper.canHarvest(vaultAddress) const overrides = { diff --git a/src/methods/vault/transactions/deposit/otherToken/common.ts b/src/methods/vault/transactions/deposit/otherToken/common.ts index 0b02d0a2..586588da 100644 --- a/src/methods/vault/transactions/deposit/otherToken/common.ts +++ b/src/methods/vault/transactions/deposit/otherToken/common.ts @@ -19,8 +19,13 @@ export const commonLogic = (values: DepositInput) => { }, ] + const vaultContract = contracts.helpers.createVault({ + options: { chainId: options.network }, + vaultAddress, + }) + const baseInput: VaultMulticallBaseInput = { - vaultContract: contracts.helpers.createOtherTokenVault(vaultAddress), + vaultContract, vaultAddress, userAddress, options, diff --git a/src/methods/vault/transactions/operate/common.ts b/src/methods/vault/transactions/operate/common.ts index d95ecbe1..6cb813be 100644 --- a/src/methods/vault/transactions/operate/common.ts +++ b/src/methods/vault/transactions/operate/common.ts @@ -27,26 +27,36 @@ export const commonLogic = async (values: MulticallTransactionInput) => { validateArgs.address({ vaultAddress, userAddress }) - let vaultContract = contracts.helpers.createVault(vaultAddress) + const chainId = options.network + const isPrivate = Boolean(whitelist?.length || whitelistManager) + const isBlocklist = Boolean(blocklist?.length || blocklistManager) + const isRestake = Boolean(restakeOperatorsManager || restakeWithdrawalsManager) - if (whitelist?.length || whitelistManager) { + const vaultContract = contracts.helpers.createVault({ + vaultAddress, + options: { + chainId, + isRestake, + isPrivate, + isBlocklist, + }, + }) + + // @ts-ignore: boolean + boolean + if (isRestake + isPrivate + isBlocklist >= 2) { + throw new Error('You are trying to change the data for different vaults types') + } + + if (isPrivate) { if (whitelist && whitelist.length > 700) { throw new Error('Your transaction is likely to fail, we do not recommend passing more than 700 addresses to the whitelist at a time') } - - vaultContract = contracts.helpers.createPrivateVault(vaultAddress) } - if (blocklist?.length || blocklistManager) { + if (isBlocklist) { if (blocklist && blocklist.length > 700) { throw new Error('Your transaction is likely to fail, we do not recommend passing more than 700 addresses to the block list at a time') } - - vaultContract = contracts.helpers.createBlocklistedVault(vaultAddress) - } - - if (restakeOperatorsManager || restakeWithdrawalsManager) { - vaultContract = contracts.helpers.createRestakingVault(vaultAddress) } const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) diff --git a/src/methods/vault/transactions/util/check/checkAdminAccess.ts b/src/methods/vault/transactions/util/check/checkAdminAccess.ts index 20818a96..770c6769 100644 --- a/src/methods/vault/transactions/util/check/checkAdminAccess.ts +++ b/src/methods/vault/transactions/util/check/checkAdminAccess.ts @@ -3,7 +3,7 @@ import type { CheckInput } from './types' const checkAdminAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { try { - const vaultContract = await contracts.helpers.createVault(vaultAddress) + const vaultContract = await contracts.helpers.createVault({ vaultAddress }) const admin = await vaultContract.admin() const hasAccess = admin.toLowerCase() === userAddress.toLowerCase() diff --git a/src/methods/vault/transactions/util/check/checkBlocklistManagerAccess.ts b/src/methods/vault/transactions/util/check/checkBlocklistManagerAccess.ts index 578b4af9..9329e215 100644 --- a/src/methods/vault/transactions/util/check/checkBlocklistManagerAccess.ts +++ b/src/methods/vault/transactions/util/check/checkBlocklistManagerAccess.ts @@ -3,7 +3,11 @@ import type { CheckInput } from './types' const checkBlocklistManagerAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { try { - const vaultContract = contracts.helpers.createBlocklistedVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ + options: { isBlocklist: true }, + vaultAddress, + }) + const blocklistManager = await vaultContract.blocklistManager() const hasAccess = blocklistManager.toLowerCase() === userAddress.toLowerCase() diff --git a/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts b/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts index ef61b48a..f46abb56 100644 --- a/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts +++ b/src/methods/vault/transactions/util/check/checkDepositDataManagerAccess.ts @@ -4,7 +4,7 @@ import type { CheckInput } from './types' const checkDepositDataManagerAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { try { - const vaultContract = contracts.helpers.createVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ vaultAddress }) const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) const depositDataManager = isV1Version diff --git a/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts b/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts index 8b4eb9b4..cc2a7d8c 100644 --- a/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts +++ b/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts @@ -3,7 +3,11 @@ import type { CheckInput } from './types' const checkRestakeOperatorsManagerAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { try { - const restakingVaultContract = contracts.helpers.createRestakingVault(vaultAddress) + const restakingVaultContract = contracts.helpers.createVault({ + options: { isRestake: true }, + vaultAddress, + }) + const restakeOperatorsManager = await restakingVaultContract.restakeOperatorsManager() const hasAccess = restakeOperatorsManager.toLowerCase() === userAddress.toLowerCase() diff --git a/src/methods/vault/transactions/util/check/checkWhitelisterAccess.ts b/src/methods/vault/transactions/util/check/checkWhitelisterAccess.ts index 77d34801..c45d0da8 100644 --- a/src/methods/vault/transactions/util/check/checkWhitelisterAccess.ts +++ b/src/methods/vault/transactions/util/check/checkWhitelisterAccess.ts @@ -3,7 +3,11 @@ import type { CheckInput } from './types' const checkWhitelisterAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { try { - const vaultContract = contracts.helpers.createPrivateVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ + vaultAddress, + options: { isPrivate: true }, + }) + const whitelistManager = await vaultContract.whitelister() const hasAccess = whitelistManager.toLowerCase() === userAddress.toLowerCase() diff --git a/src/methods/vault/transactions/withdraw/common.ts b/src/methods/vault/transactions/withdraw/common.ts index df38de78..c634d85b 100644 --- a/src/methods/vault/transactions/withdraw/common.ts +++ b/src/methods/vault/transactions/withdraw/common.ts @@ -11,7 +11,7 @@ export const commonLogic = async (values: WithdrawInput) => { const params: Parameters[0]['request']['params'] = [] - const vaultContract = contracts.helpers.createVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ vaultAddress }) // In the second version of the vault we do not use the redeem method, // the funds are always withdrawn via a queue diff --git a/src/types/global.ts b/src/types/global.ts index 787ab52c..41a237ac 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -5,7 +5,6 @@ import { Network, configs } from '../utils' import { createContracts } from '../contracts' import type { - VaultAbi as InitialVaultAbi, Erc20Abi, KeeperAbi, OraclesAbi, @@ -18,23 +17,16 @@ import type { VestingEscrowAbi, VaultsRegistryAbi, RewardSplitterAbi, - GnosisVaultDiffAbi, - OtherTokenVaultAbi, StakeCalculatorAbi, - GenesisVaultDiffAbi, - PrivateVaultDiffAbi, MerkleDistributorAbi, MintTokenConfigV1Abi, MintTokenConfigV2Abi, - RestakingVaultDiffAbi, - BlocklistVaultDiffAbi, DepositDataRegistryAbi, MintTokenControllerAbi, VestingEscrowFactoryAbi, RewardSplitterFactoryAbi, } from '../contracts/types' -type VaultAbi = InitialVaultAbi & GnosisVaultDiffAbi declare global { @@ -79,7 +71,6 @@ declare global { type TransactionHash = string namespace ABI { - type Vault = VaultAbi type Keeper = KeeperAbi type Oracles = OraclesAbi type UsdRate = UsdRateAbi @@ -91,21 +82,16 @@ declare global { type EigenPodOwner = EigenPodOwnerAbi type V2RewardToken = V2RewardTokenAbi type VestingEscrow = VestingEscrowAbi - type GenesisVault = GenesisVaultDiffAbi type RewardSplitter = RewardSplitterAbi type VaultsRegistry = VaultsRegistryAbi type StakeCalculator = StakeCalculatorAbi - type OtherTokenVault = OtherTokenVaultAbi type MerkleDistributor = MerkleDistributorAbi type MintTokenConfigV1 = MintTokenConfigV1Abi type MintTokenConfigV2 = MintTokenConfigV2Abi type DepositDataRegistry = DepositDataRegistryAbi type MintTokenController = MintTokenControllerAbi - type PrivateVault = VaultAbi & PrivateVaultDiffAbi type VestingEscrowFactory = VestingEscrowFactoryAbi type RewardSplitterFactory = RewardSplitterFactoryAbi - type RestakingVault = RestakingVaultDiffAbi & VaultAbi - type BlocklistVault = VaultAbi & BlocklistVaultDiffAbi } } } diff --git a/src/utils/getVaultContract.ts b/src/utils/getVaultContract.ts deleted file mode 100644 index fd36aca1..00000000 --- a/src/utils/getVaultContract.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Network } from './enums' - - -type Input = { - network: Network - vaultAddress: string - contracts: StakeWise.Contracts -} - -const getVaultContract = (values: Input) => { - const { vaultAddress, network, contracts } = values - - const isNativeToken = [ Network.Holesky, Network.Mainnet ].includes(network) - - if (isNativeToken) { - return contracts.helpers.createVault(vaultAddress) - } - - return contracts.helpers.createOtherTokenVault(vaultAddress) -} - - -export default getVaultContract diff --git a/src/utils/getVaultVersion.ts b/src/utils/getVaultVersion.ts index cb7ff694..4fde5302 100644 --- a/src/utils/getVaultVersion.ts +++ b/src/utils/getVaultVersion.ts @@ -6,7 +6,7 @@ type Input = { const getVaultVersion = async (values: Input) => { const { contracts, vaultAddress } = values - const vaultContract = contracts.helpers.createVault(vaultAddress) + const vaultContract = contracts.helpers.createVault({ vaultAddress }) const version = await vaultContract.version() const isV1Version = version === 1n diff --git a/src/utils/index.ts b/src/utils/index.ts index a9dc9a48..5c7ae5d9 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -10,5 +10,4 @@ export { default as createProvider } from './createProvider' export { default as getVaultVersion } from './getVaultVersion' export { default as getNetworkTypes } from './getNetworkTypes' export { default as getVaultFactory } from './getVaultFactory' -export { default as getVaultContract } from './getVaultContract' export { default as getValidLtvPercent } from './getValidLtvPercent' From b0597745b74e0144b1d5ef110715b9fa2b648ee5 Mon Sep 17 00:00:00 2001 From: Mike Diamond Date: Tue, 24 Sep 2024 10:44:58 +0300 Subject: [PATCH 16/36] New subgraph (#171) * [new subgraph] update schema * [codegen ci] add fallback subgraph codegen check (#168) # Conflicts: # codegen.ts * [codegen ci] add fallback subgraph codegen check (#168) # Conflicts: # codegen.ts * [new subgraph] Update codegen * [new subgraph] Update codegen * [new subgraph] Update types * [new subgraph] Update graphql --- .graphqlconfig | 2 +- README.md | 32 +++--------- changelog/next-release.md | 19 +++++++ codegen.ts | 5 +- .../subgraph/exitQueue/exitQueueQuery.graphql | 4 +- src/graphql/subgraph/osToken/index.ts | 6 --- .../osToken/osTokenPositionsQuery.graphql | 5 -- .../osTokenRewardPerSecondQuery.graphql | 5 -- src/graphql/subgraph/vault/vaultQuery.graphql | 4 +- src/methods/osToken/index.ts | 6 --- .../requests/getAvgRewardsPerSecond.ts | 39 -------------- .../osToken/requests/getOsTokenPosition.ts | 51 +++++++++++++++++++ .../{getPosition/index.ts => getPosition.ts} | 14 ++--- .../osToken/requests/getPosition/getShares.ts | 25 --------- .../parseExitRequests.spec.ts | 9 ++-- .../parseExitRequests.ts | 7 +-- src/utils/configs/holesky.ts | 2 +- src/utils/configs/mainnet.ts | 4 +- 18 files changed, 101 insertions(+), 138 deletions(-) delete mode 100644 src/graphql/subgraph/osToken/osTokenPositionsQuery.graphql delete mode 100644 src/graphql/subgraph/osToken/osTokenRewardPerSecondQuery.graphql delete mode 100644 src/methods/osToken/requests/getAvgRewardsPerSecond.ts create mode 100644 src/methods/osToken/requests/getOsTokenPosition.ts rename src/methods/osToken/requests/{getPosition/index.ts => getPosition.ts} (71%) delete mode 100644 src/methods/osToken/requests/getPosition/getShares.ts diff --git a/.graphqlconfig b/.graphqlconfig index 6654cf03..e58ec43a 100644 --- a/.graphqlconfig +++ b/.graphqlconfig @@ -11,7 +11,7 @@ "extensions": { "endpoints": { "Subgraph GraphQL": { - "url": "https://holesky-graph.stakewise.io/subgraphs/name/stakewise/stakewise/graphql", + "url": "https://graphs.stakewise.io/holesky/subgraphs/name/stakewise/prod/graphql", "headers": { "user-agent": "JS GraphQL" }, diff --git a/README.md b/README.md index 1c375b31..d3545082 100644 --- a/README.md +++ b/README.md @@ -879,24 +879,6 @@ type Output = string const apy = await sdk.osToken.getAPY() ``` --- -### `sdk.osToken.getAvgRewardsPerSecond` - -#### Description: - -osETH average rewards per second - -#### Returns: - -```ts -type Output = bigint -``` - -#### Example: - -```ts -const averageRewardsPerSecond = await sdk.osToken.getAvgRewardsPerSecond() -``` ---- ### `sdk.osToken.getPosition` #### Description: @@ -916,7 +898,6 @@ User position data ```ts type Output = { minted: { - fee: bigint assets: bigint shares: bigint } @@ -928,13 +909,12 @@ type Output = { } ``` -| Name | Description | -|------|-------------| -| `minted.fee` | Usage fee amount | -| `minted.shares` | Balance | -| `minted.assets` | Balance in ETH | -| `healthFactor` | [sdk.osToken.getHealthFactor](#sdkostokengethealthfactor) | -| `protocolFeePercent` | Usage fee percent | +| Name | Description | +|----------------------|-----------------------------------------------------------| +| `minted.shares` | Balance | +| `minted.assets` | Balance in ETH | +| `healthFactor` | [sdk.osToken.getHealthFactor](#sdkostokengethealthfactor) | +| `protocolFeePercent` | Usage fee percent | #### Example: diff --git a/changelog/next-release.md b/changelog/next-release.md index 40ed4e34..7412b9d8 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -34,3 +34,22 @@ type AddedOutput = { ### 3. Removed method ### `sdk.vault.getVault` + +--- + +### 3. Removed method +### `sdk.osToken.getAvgRewardsPerSecond` + +--- + +### 4. Removed output field +### `sdk.osToken.getPosition` +#### New output field: + +```ts +type RemovedOutput = { + minted: { + fee: bigint + } +} +``` diff --git a/codegen.ts b/codegen.ts index 7bc9b290..12f1d1c5 100644 --- a/codegen.ts +++ b/codegen.ts @@ -4,9 +4,8 @@ import { Network } from './src/utils/enums' import configs from './src/utils/configs' -// TODO change to Holesky -// For every network we have same gql shema, so we can use just Mainnet here -const urls = configs[Network.Gnosis].api +// For every network we have same gql schema, so we can use just Mainnet here +const urls = configs[Network.Holesky].api // https://the-guild.dev/graphql/codegen/plugins/typescript/typescript const typesConfig = { diff --git a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql index 2a5d6909..38f22216 100644 --- a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql +++ b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql @@ -6,8 +6,10 @@ query exitQueue($receiver: Bytes, $vault: String!) { withdrawalTimestamp positionTicket isV2Position - totalShares totalAssets timestamp + exitQueueIndex + exitedAssets + isClaimable } } diff --git a/src/graphql/subgraph/osToken/index.ts b/src/graphql/subgraph/osToken/index.ts index 07cc951b..65dd2864 100644 --- a/src/graphql/subgraph/osToken/index.ts +++ b/src/graphql/subgraph/osToken/index.ts @@ -1,8 +1,2 @@ export { fetchOsTokenApyQuery } from './osTokenApyQuery.graphql' export type { OsTokenApyQueryPayload, OsTokenApyQueryVariables } from './osTokenApyQuery.graphql' - -export { fetchOsTokenPositionsQuery } from './osTokenPositionsQuery.graphql' -export type { OsTokenPositionsQueryPayload, OsTokenPositionsQueryVariables } from './osTokenPositionsQuery.graphql' - -export { fetchOsTokenRewardPerSecondQuery } from './osTokenRewardPerSecondQuery.graphql' -export type { OsTokenRewardPerSecondQueryPayload, OsTokenRewardPerSecondQueryVariables } from './osTokenRewardPerSecondQuery.graphql' diff --git a/src/graphql/subgraph/osToken/osTokenPositionsQuery.graphql b/src/graphql/subgraph/osToken/osTokenPositionsQuery.graphql deleted file mode 100644 index bc7cdf98..00000000 --- a/src/graphql/subgraph/osToken/osTokenPositionsQuery.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query OsTokenPositions($address: Bytes, $vaultAddress: String) { - osTokenPositions(where: { address: $address, vault: $vaultAddress }) { - shares - } -} diff --git a/src/graphql/subgraph/osToken/osTokenRewardPerSecondQuery.graphql b/src/graphql/subgraph/osToken/osTokenRewardPerSecondQuery.graphql deleted file mode 100644 index f2ff2de6..00000000 --- a/src/graphql/subgraph/osToken/osTokenRewardPerSecondQuery.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query osTokenRewardPerSecond($first: Int, $orderBy: OsTokenSnapshot_orderBy, $orderDirection: OrderDirection) { - osTokenSnapshots(first: $first, orderBy: $orderBy, orderDirection: $orderDirection) { - avgRewardPerSecond - } -} diff --git a/src/graphql/subgraph/vault/vaultQuery.graphql b/src/graphql/subgraph/vault/vaultQuery.graphql index 6e6d2f16..2dd5b2ac 100644 --- a/src/graphql/subgraph/vault/vaultQuery.graphql +++ b/src/graphql/subgraph/vault/vaultQuery.graphql @@ -25,9 +25,9 @@ query Vault($address: ID!) { description whitelister tokenSymbol - keysManager + keysManager: depositDataManager feeRecipient - validatorsRoot + validatorsRoot: depositDataRoot blocklistCount whitelistCount isCollateralized diff --git a/src/methods/osToken/index.ts b/src/methods/osToken/index.ts index 9ebede40..9b22d2e2 100644 --- a/src/methods/osToken/index.ts +++ b/src/methods/osToken/index.ts @@ -8,7 +8,6 @@ import getBurnAmount from './helpers/getBurnAmount' import getHealthFactor from './helpers/getHealthFactor' import getSharesFromAssets from './requests/getSharesFromAssets' import getAssetsFromShares from './requests/getAssetsFromShares' -import getAvgRewardsPerSecond from './requests/getAvgRewardsPerSecond' // Transactions import { default as mint } from './transactions/mint' @@ -62,11 +61,6 @@ export default { * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkostokengetassetsfromshares */ getAssetsFromShares, - /** - * @description osETH average rewards per second - * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkostokengetavgrewardspersecond - */ - getAvgRewardsPerSecond, }, transactions: { /** diff --git a/src/methods/osToken/requests/getAvgRewardsPerSecond.ts b/src/methods/osToken/requests/getAvgRewardsPerSecond.ts deleted file mode 100644 index 0892eac8..00000000 --- a/src/methods/osToken/requests/getAvgRewardsPerSecond.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { apiUrls } from '../../../utils' -import graphql from '../../../graphql' - - -export type FetchOsTokenSnapshotsInput = { - options: StakeWise.Options -} - -const getAvgRewardsPerSecond = (input: FetchOsTokenSnapshotsInput) => { - const { options } = input - - return graphql.subgraph.osToken.fetchOsTokenRewardPerSecondQuery({ - url: apiUrls.getSubgraphqlUrl(options), - variables: { - first: 14, - orderBy: 'createdAt', - orderDirection: 'desc', - }, - modifyResult: (data) => { - let rewardPerSecond = 0n - - const count = BigInt(data.osTokenSnapshots.length || 0) - - if (count) { - const sum = data.osTokenSnapshots.reduce( - (acc, { avgRewardPerSecond }) => acc + BigInt(avgRewardPerSecond), - 0n - ) - - rewardPerSecond = sum / count - } - - return rewardPerSecond - }, - }) -} - - -export default getAvgRewardsPerSecond diff --git a/src/methods/osToken/requests/getOsTokenPosition.ts b/src/methods/osToken/requests/getOsTokenPosition.ts new file mode 100644 index 00000000..64a0ce44 --- /dev/null +++ b/src/methods/osToken/requests/getOsTokenPosition.ts @@ -0,0 +1,51 @@ +import { validateArgs } from '../../../utils' +import getHealthFactor from '../helpers/getHealthFactor' +import { wrapAbortPromise } from '../../../modules/gql-module' + + +type Output = { + minted: { + assets: bigint + shares: bigint + }, + healthFactor: ReturnType + protocolFeePercent: bigint +} + +type GetOsTokenPositionInput = { + userAddress: string + vaultAddress: string + stakedAssets: bigint + thresholdPercent: bigint + contracts: StakeWise.Contracts +} + +const getOsTokenPosition = async (values: GetOsTokenPositionInput) => { + const { contracts, vaultAddress, userAddress, stakedAssets, thresholdPercent } = values + + validateArgs.address({ vaultAddress, userAddress }) + validateArgs.bigint({ stakedAssets, thresholdPercent }) + + const vaultContract = contracts.helpers.createVault({ vaultAddress }) + const mintedShares = await vaultContract.osTokenPositions(userAddress) + + const [ mintedAssets, feePercent ] = await Promise.all([ + contracts.base.mintTokenController.convertToAssets(mintedShares), + contracts.base.mintTokenController.feePercent(), + ]) + + const protocolFeePercent = feePercent / 100n + const healthFactor = getHealthFactor({ mintedAssets, stakedAssets, thresholdPercent }) + + return { + minted: { + assets: mintedAssets, + shares: mintedShares, + }, + healthFactor, + protocolFeePercent, + } +} + + +export default wrapAbortPromise(getOsTokenPosition) diff --git a/src/methods/osToken/requests/getPosition/index.ts b/src/methods/osToken/requests/getPosition.ts similarity index 71% rename from src/methods/osToken/requests/getPosition/index.ts rename to src/methods/osToken/requests/getPosition.ts index 432e68d2..d7fbbbc1 100644 --- a/src/methods/osToken/requests/getPosition/index.ts +++ b/src/methods/osToken/requests/getPosition.ts @@ -1,7 +1,6 @@ -import getShares from './getShares' -import getHealthFactor from '../../helpers/getHealthFactor' -import { wrapAbortPromise } from '../../../../modules/gql-module' -import { validateArgs, OsTokenPositionHealth } from '../../../../utils' +import getHealthFactor from '../helpers/getHealthFactor' +import { wrapAbortPromise } from '../../../modules/gql-module' +import { validateArgs, OsTokenPositionHealth } from '../../../utils' type GetOsTokenPositionInput = { @@ -9,7 +8,6 @@ type GetOsTokenPositionInput = { vaultAddress: string stakedAssets: bigint thresholdPercent: bigint - options: StakeWise.Options contracts: StakeWise.Contracts } @@ -17,7 +15,6 @@ type Output = { minted: { assets: bigint shares: bigint - fee: bigint } healthFactor: { value: number @@ -27,13 +24,11 @@ type Output = { } const getOsTokenPosition = async (values: GetOsTokenPositionInput) => { - const { options, contracts, vaultAddress, userAddress, stakedAssets, thresholdPercent } = values + const { contracts, vaultAddress, userAddress, stakedAssets, thresholdPercent } = values validateArgs.address({ vaultAddress, userAddress }) validateArgs.bigint({ stakedAssets, thresholdPercent }) - const gqlMintedShares = await getShares({ options, vaultAddress, userAddress }) - const vaultContract = contracts.helpers.createVault({ vaultAddress }) const mintedShares = await vaultContract.osTokenPositions(userAddress) @@ -49,7 +44,6 @@ const getOsTokenPosition = async (values: GetOsTokenPositionInput) => { minted: { assets: mintedAssets, shares: mintedShares, - fee: mintedShares - gqlMintedShares, }, healthFactor, protocolFeePercent, diff --git a/src/methods/osToken/requests/getPosition/getShares.ts b/src/methods/osToken/requests/getPosition/getShares.ts deleted file mode 100644 index 89a119c6..00000000 --- a/src/methods/osToken/requests/getPosition/getShares.ts +++ /dev/null @@ -1,25 +0,0 @@ -import graphql from '../../../../graphql' -import { apiUrls } from '../../../../utils' - - -type GetOsTokenPositionSharesInput = { - userAddress: string - vaultAddress: string - options: StakeWise.Options -} - -const getShares = (values: GetOsTokenPositionSharesInput) => { - const { options, vaultAddress, userAddress } = values - - return graphql.subgraph.osToken.fetchOsTokenPositionsQuery({ - url: apiUrls.getSubgraphqlUrl(options), - variables: { - vaultAddress, - address: userAddress, - }, - modifyResult: (data) => BigInt(data?.osTokenPositions?.[0]?.shares || 0), - }) -} - - -export default getShares diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts index 7ada8720..c1ad5eab 100644 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts +++ b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts @@ -35,21 +35,24 @@ describe('parseExitRequests function', () => { withdrawalTimestamp: '1718536919', timestamp: '123456', totalAssets: '0', - totalShares: '100', + // totalShares: '100', + isV2Position: false, }, { positionTicket: 'positionTicket-2', withdrawalTimestamp: '1718536919', timestamp: '123457', totalAssets: '0', - totalShares: '200', + // totalShares: '200', + isV2Position: false, }, { positionTicket: 'positionTicket-2', withdrawalTimestamp: '1718536919', timestamp: '123458', totalAssets: '300', - totalShares: '0', + // totalShares: '0', + isV2Position: false, }, ], } diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts index eb84f323..94c598aa 100644 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts +++ b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts @@ -5,7 +5,7 @@ type ExitRequest = { withdrawalTimestamp: string | null positionTicket: string isV2Position: boolean - totalShares: string + // totalShares: string totalAssets: string timestamp: string } @@ -116,9 +116,10 @@ const parseExitRequests = async (values: ParseExitRequestsInput): Promise= 0. diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 84e34b19..8f6c9f40 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -7,7 +7,7 @@ export default { network: constants.chains.holesky, api: { backend: 'https://holesky-api.stakewise.io/graphql', - subgraph: 'https://holesky-graph.stakewise.io/subgraphs/name/stakewise/stakewise', + subgraph: 'https://graphs.stakewise.io/holesky/subgraphs/name/stakewise/prod', }, pages: { beaconchain: 'https://holesky.beaconcha.in', diff --git a/src/utils/configs/mainnet.ts b/src/utils/configs/mainnet.ts index 77056c0d..3ff35175 100644 --- a/src/utils/configs/mainnet.ts +++ b/src/utils/configs/mainnet.ts @@ -8,8 +8,8 @@ export default { api: { backend: 'https://mainnet-api.stakewise.io/graphql', subgraph: [ - 'https://mainnet-graph.stakewise.io/subgraphs/name/stakewise/stakewise', - 'https://mainnet-graph-b.stakewise.io/subgraphs/name/stakewise/stakewise', + // TODO replace with https://graphs.stakewise.io/mainnet/subgraphs/name/stakewise/prod + 'https://graphs.stakewise.io/mainnet-stage/subgraphs/name/stakewise/prod', ], }, pages: { From 17d349d0436f64b0260d2c2d71bea9863183c268 Mon Sep 17 00:00:00 2001 From: CAst Date: Tue, 24 Sep 2024 17:15:19 +0500 Subject: [PATCH 17/36] Subgraph tvl apy (#172) * [subgraph-tvl-ap] add getStakewiseStats * [subgraph-tvl-ap] change urls * [subgraph-tvl-apy] rename validatorsRoot and keysManager --- .graphqlconfig | 2 +- README.md | 36 +++++++++++++++---- changelog/next-release.md | 3 ++ src/graphql/subgraph/index.ts | 1 + .../subgraph/osToken/osTokenApyQuery.graphql | 2 +- src/graphql/subgraph/stats/index.ts | 2 ++ src/graphql/subgraph/stats/statsQuery.graphql | 7 ++++ src/graphql/subgraph/vault/vaultQuery.graphql | 3 +- src/methods/utils/getStakewiseStats.ts | 23 ++++++++++++ src/methods/utils/index.ts | 1 + src/methods/vault/index.ts | 2 +- .../requests/getVault/modifyVault.spec.ts | 6 ++-- .../vault/requests/getVault/modifyVault.ts | 6 +--- src/methods/vault/requests/getVault/types.ts | 6 ---- .../vault/transactions/operate/checkAccess.ts | 4 +-- .../vault/transactions/operate/common.ts | 12 +++---- .../transactions/setDepositDataRoot/common.ts | 4 +-- .../transactions/setDepositDataRoot/index.ts | 4 +-- .../setDepositDataRootEncode.ts | 2 +- .../setDepositDataRootGas.ts | 4 +-- .../setDepositDataRoot/types.d.ts | 2 +- .../util/params/getDepositDataRootParams.ts | 24 +++++++++++++ .../util/params/getValidatorsRootParams.ts | 24 ------------- .../vault/transactions/util/params/index.ts | 2 +- src/utils/configs/chiado.ts | 2 +- src/utils/configs/gnosis.ts | 2 +- src/utils/configs/mainnet.ts | 4 +-- 27 files changed, 118 insertions(+), 72 deletions(-) create mode 100644 src/graphql/subgraph/stats/index.ts create mode 100644 src/graphql/subgraph/stats/statsQuery.graphql create mode 100644 src/methods/utils/getStakewiseStats.ts create mode 100644 src/methods/vault/transactions/util/params/getDepositDataRootParams.ts delete mode 100644 src/methods/vault/transactions/util/params/getValidatorsRootParams.ts diff --git a/.graphqlconfig b/.graphqlconfig index e58ec43a..c0fa6a6d 100644 --- a/.graphqlconfig +++ b/.graphqlconfig @@ -11,7 +11,7 @@ "extensions": { "endpoints": { "Subgraph GraphQL": { - "url": "https://graphs.stakewise.io/holesky/subgraphs/name/stakewise/prod/graphql", + "url": "https://graphs.stakewise.io/holesky/subgraphs/name/stakewise/prod", "headers": { "user-agent": "JS GraphQL" }, diff --git a/README.md b/README.md index d3545082..b205fd8f 100644 --- a/README.md +++ b/README.md @@ -978,7 +978,7 @@ type Output = bigint #### Example: ```ts -await sdk.utils.getAssetsFromShares({ amount: 0n }) +await sdk.osToken.getAssetsFromShares({ amount: 0n }) ``` --- ### `sdk.osToken.getSharesFromAssets` @@ -1002,7 +1002,7 @@ type Output = bigint #### Example: ```ts -await sdk.utils.getSharesFromAssets({ amount: 0n }) +await sdk.osToken.getSharesFromAssets({ amount: 0n }) ``` --- ### `sdk.osToken.getRate` @@ -1196,6 +1196,28 @@ type Output = string await sdk.utils.getSwiseUsdPrice() ``` --- +### `sdk.utils.getStakewiseStats` + +#### Description: + +TVL statistics, number of users, rewards earned + +#### Returns: + +```ts +type Output = { + usersCount: number + totalAssets: string + totalEarnedAssets: string +} +``` + +#### Example: + +```ts +await sdk.utils.getStakewiseStats() +``` +--- ### `sdk.utils.getTransactions` #### Description: @@ -1431,7 +1453,7 @@ Adding root validators to vaults **version 2** or higher | Name | Type | Required | Description | |----------------|----------|----------|-------------| -| validatorsRoot | `string` | **Yes** | The vault validators merkle tree | +| depositDataRoot | `string` | **Yes** | The vault validators merkle tree | | userAddress | `string` | **Yes** | - | | vaultAddress | `string` | **Yes** | - | @@ -1439,7 +1461,7 @@ Adding root validators to vaults **version 2** or higher ```ts const params = { - validatorsRoot: 'hash', + depositDataRoot: 'hash', vaultAddress: '0x...', userAddress: '0x...', } @@ -1591,7 +1613,7 @@ Updates the vault by authorized personnel such as the vault admin, whitelistMana | restakeOperatorsManager | `string` | **No** | Admin | The restake operators manager can add EigenPods and update EigenLayer operators. | | whitelistManager | `string` | **No** | Admin | Address of the vault whitelistManager | | feeRecipient | `string` | **No** | Admin | Address of the vault fee recipient | -| validatorsRoot | `string` | **No** | Keys manager | The vault validators merkle tree root. Support only **first version** on valults. For second verion use `vault.setDepositDataRoot` | +| depositDataRoot | `string` | **No** | Keys manager | The vault validators merkle tree root. Support only **first version** on valults. For second verion use `vault.setDepositDataRoot` | | blocklistManager | `string` | **No** | Admin | The blocklisted vault blocklist manager | | image | `string` | **No** | Admin | The vault image in base64 string format (will be uploaded to IPFS; maximum size is 1 MB) | | displayName | `string` | **No** | Admin | The vault display name (will be uploaded to IPFS; maximum size is 30 characters) | @@ -1610,7 +1632,7 @@ const params = { displayName: '...', description: '...', feeRecipient: '0x...', - validatorsRoot: '0x...', + depositDataRoot: '0x...', blocklistManager: '0x...', whitelistManager: '0x...', validatorsManager: '0x...', @@ -1621,7 +1643,7 @@ const params = { // Data to update the vault by vault keys manager. const params = { - validatorsRoot: '...', + depositDataRoot: '...', vaultAddress: '0x...', userAddress: '0x...', } diff --git a/changelog/next-release.md b/changelog/next-release.md index 7412b9d8..33a25810 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -53,3 +53,6 @@ type RemovedOutput = { } } ``` + +### 5. Added method getStakewiseStats +### `sdk.utils.getStakewiseStats` diff --git a/src/graphql/subgraph/index.ts b/src/graphql/subgraph/index.ts index 0b087c31..b816e9da 100644 --- a/src/graphql/subgraph/index.ts +++ b/src/graphql/subgraph/index.ts @@ -1,3 +1,4 @@ +export * as stats from './stats' export * as vault from './vault' export * as osToken from './osToken' export * as eigenPods from './eigenPods' diff --git a/src/graphql/subgraph/osToken/osTokenApyQuery.graphql b/src/graphql/subgraph/osToken/osTokenApyQuery.graphql index dbf46586..702d85fb 100644 --- a/src/graphql/subgraph/osToken/osTokenApyQuery.graphql +++ b/src/graphql/subgraph/osToken/osTokenApyQuery.graphql @@ -1,4 +1,4 @@ -query osTokenApy($first: Int, $orderBy: OsTokenSnapshot_orderBy, $orderDirection: OrderDirection) { +query osTokenApy { osTokens { apy } diff --git a/src/graphql/subgraph/stats/index.ts b/src/graphql/subgraph/stats/index.ts new file mode 100644 index 00000000..843767c8 --- /dev/null +++ b/src/graphql/subgraph/stats/index.ts @@ -0,0 +1,2 @@ +export { fetchStatsQuery } from './statsQuery.graphql' +export type { StatsQueryPayload, StatsQueryVariables } from './statsQuery.graphql' diff --git a/src/graphql/subgraph/stats/statsQuery.graphql b/src/graphql/subgraph/stats/statsQuery.graphql new file mode 100644 index 00000000..bfacff3f --- /dev/null +++ b/src/graphql/subgraph/stats/statsQuery.graphql @@ -0,0 +1,7 @@ +query Stats { + networks { + totalAssets + usersCount + totalEarnedAssets + } +} diff --git a/src/graphql/subgraph/vault/vaultQuery.graphql b/src/graphql/subgraph/vault/vaultQuery.graphql index 2dd5b2ac..8a0216ec 100644 --- a/src/graphql/subgraph/vault/vaultQuery.graphql +++ b/src/graphql/subgraph/vault/vaultQuery.graphql @@ -25,11 +25,10 @@ query Vault($address: ID!) { description whitelister tokenSymbol - keysManager: depositDataManager feeRecipient - validatorsRoot: depositDataRoot blocklistCount whitelistCount + depositDataRoot isCollateralized blocklistManager validatorsManager diff --git a/src/methods/utils/getStakewiseStats.ts b/src/methods/utils/getStakewiseStats.ts new file mode 100644 index 00000000..a471c7af --- /dev/null +++ b/src/methods/utils/getStakewiseStats.ts @@ -0,0 +1,23 @@ +import graphql from '../../graphql' +import { apiUrls } from '../../utils' + + +type GetStakewiseStatsInput = { + options: StakeWise.Options +} + +const getStakewiseStats = (values: GetStakewiseStatsInput) => { + const { options } = values + + return graphql.subgraph.stats.fetchStatsQuery({ + url: apiUrls.getSubgraphqlUrl(options), + modifyResult: (data) => ({ + usersCount: data.networks[0].usersCount, + totalAssets: data.networks[0].totalAssets, + totalEarnedAssets: data.networks[0].totalEarnedAssets, + }), + }) +} + + +export default getStakewiseStats diff --git a/src/methods/utils/index.ts b/src/methods/utils/index.ts index 74ada8ae..522af2f2 100644 --- a/src/methods/utils/index.ts +++ b/src/methods/utils/index.ts @@ -1,5 +1,6 @@ export type { BaseInput } from './types' export { default as getTransactions } from './getTransactions' export { default as getSwiseUsdPrice } from './getSwiseUsdPrice' +export { default as getStakewiseStats } from './getStakewiseStats' export { default as getVaultMulticallGas } from './getVaultMulticallGas' export { default as getVaultMulticallEncode } from './getVaultMulticallEncode' diff --git a/src/methods/vault/index.ts b/src/methods/vault/index.ts index bedc4d42..e11444d4 100644 --- a/src/methods/vault/index.ts +++ b/src/methods/vault/index.ts @@ -128,7 +128,7 @@ export default { /** * @description Updates the vault by authorized personnel such as the vault admin, whitelist manager, * blocklist manager, validators manager, or deposit-data manager. - * @throws Fields validatorsRoot and depositDataManager supported only first version of vaults + * @throws Fields depositDataRoot and depositDataManager supported only first version of vaults * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultoperate */ operate, diff --git a/src/methods/vault/requests/getVault/modifyVault.spec.ts b/src/methods/vault/requests/getVault/modifyVault.spec.ts index 784e31b9..dfe157a9 100644 --- a/src/methods/vault/requests/getVault/modifyVault.spec.ts +++ b/src/methods/vault/requests/getVault/modifyVault.spec.ts @@ -27,14 +27,13 @@ describe('modifyVault', () => { whitelistCount: '0', totalAssets: '150000000000', capacity: '1000000000000000', - validatorsRoot: 'mockValidators', + depositDataRoot: 'mockValidators', description: 'This is a mock vault', isCollateralized: true, admin: '0xeefffd4c23d2e8c845870e273861e7d60df49663', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663', mevEscrow: '0xeefffd4c23d2e8c845870e273861e7d60df49663', whitelister: '0xeefffd4c23d2e8c845870e273861e7d60df49663', - keysManager: '0xeefffd4c23d2e8c845870e273861e7d60df49663', feeRecipient: '0xeefffd4c23d2e8c845870e273861e7d60df49663', blocklistManager: '0xeefffd4c23d2e8c845870e273861e7d60df49663', validatorsManager: '0xeefffd4c23d2e8c845870e273861e7d60df49663', @@ -68,11 +67,10 @@ describe('modifyVault', () => { createdAt: 1693395816000, displayName: 'Mock Vault', totalAssets: '0.00000015', - validatorsRoot: 'mockValidators', + depositDataRoot: 'mockValidators', description: 'This is a mock vault', vaultAdmin: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', whitelister: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', - keysManager: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', vaultAddress: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', feeRecipient: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', mevRecipient: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', diff --git a/src/methods/vault/requests/getVault/modifyVault.ts b/src/methods/vault/requests/getVault/modifyVault.ts index febf78fe..60d061b0 100644 --- a/src/methods/vault/requests/getVault/modifyVault.ts +++ b/src/methods/vault/requests/getVault/modifyVault.ts @@ -26,7 +26,6 @@ const modifyVault = (input: ModifyVaultInput): ModifiedVault => { mevEscrow, createdAt, feePercent, - keysManager, performance, totalAssets, feeRecipient, @@ -34,14 +33,12 @@ const modifyVault = (input: ModifyVaultInput): ModifiedVault => { blocklistCount, whitelistCount, validatorsManager, + depositDataManager, restakeOperatorsManager, restakeWithdrawalsManager, - depositDataManager: initialDepositDataManager, ...rest } = vault - const depositDataManager = Number(version) > 1 ? initialDepositDataManager : keysManager - return { ...rest, apy: Number(apy), @@ -56,7 +53,6 @@ const modifyVault = (input: ModifyVaultInput): ModifiedVault => { feeRecipient: getAddress(feeRecipient), blocklistCount: Number(blocklistCount), whitelistCount: Number(whitelistCount), - keysManager: keysManager ? getAddress(keysManager) : '', whitelister: vault.whitelister ? getAddress(vault.whitelister) : '', whitelistManager: vault.whitelister ? getAddress(vault.whitelister) : '', validatorsManager: validatorsManager ? getAddress(validatorsManager) : '', diff --git a/src/methods/vault/requests/getVault/types.ts b/src/methods/vault/requests/getVault/types.ts index af4e194f..6bf71326 100644 --- a/src/methods/vault/requests/getVault/types.ts +++ b/src/methods/vault/requests/getVault/types.ts @@ -9,7 +9,6 @@ export type ModifiedVault = Omit< | 'version' | 'createdAt' | 'mevEscrow' - | 'keysManager' | 'performance' | 'whitelister' | 'osTokenConfig' @@ -32,11 +31,6 @@ export type ModifiedVault = Omit< thresholdPercent: string // The liquidation threshold percent used to calculate health factor for OsToken position } - /** - * @deprecated use depositDataManager - */ - keysManager: string - /** * @deprecated use whitelistManager */ diff --git a/src/methods/vault/transactions/operate/checkAccess.ts b/src/methods/vault/transactions/operate/checkAccess.ts index e0cdcbac..41f29924 100644 --- a/src/methods/vault/transactions/operate/checkAccess.ts +++ b/src/methods/vault/transactions/operate/checkAccess.ts @@ -14,7 +14,7 @@ const checkAccess = (action: Action) => ( async (values: Input) => { const { blocklist, whitelist, depositDataManager, whitelistManager, feeRecipient, - validatorsRoot, blocklistManager, metadataIpfsHash, validatorsManager, restakeOperatorsManager, restakeWithdrawalsManager, + depositDataRoot, blocklistManager, metadataIpfsHash, validatorsManager, restakeOperatorsManager, restakeWithdrawalsManager, } = values try { @@ -34,7 +34,7 @@ const checkAccess = (action: Action) => ( || restakeWithdrawalsManager ) - const isDepositData = Boolean(validatorsRoot) + const isDepositData = Boolean(depositDataRoot) const isWhitelistManager = Boolean(whitelist) const isBlocklistManager = Boolean(blocklist) diff --git a/src/methods/vault/transactions/operate/common.ts b/src/methods/vault/transactions/operate/common.ts index 6cb813be..104981c6 100644 --- a/src/methods/vault/transactions/operate/common.ts +++ b/src/methods/vault/transactions/operate/common.ts @@ -9,7 +9,7 @@ import { getWhitelistParams, getWhitelisterParams, getFeeRecipientParams, - getValidatorsRootParams, + getDepositDataRootParams, getBlocklistManagerParams, getValidatorsManagerParams, getDepositDataManagerParams, @@ -20,7 +20,7 @@ import { export const commonLogic = async (values: MulticallTransactionInput) => { const { - validatorsRoot, blocklistManager, metadataIpfsHash, + depositDataRoot, blocklistManager, metadataIpfsHash, blocklist, whitelist, depositDataManager, whitelistManager, feeRecipient, options, contracts, userAddress, vaultAddress, provider, validatorsManager, restakeOperatorsManager, restakeWithdrawalsManager, } = values @@ -62,8 +62,8 @@ export const commonLogic = async (values: MulticallTransactionInput) => { const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) if (!isV1Version) { - if (validatorsRoot) { - throw new Error('To set validatorsRoot in version 2 of vault, use the vault.setDepositDataRoot() method') + if (depositDataRoot) { + throw new Error('To set depositDataRoot in version 2 of vault, use the vault.setDepositDataRoot() method') } if (depositDataManager) { @@ -118,8 +118,8 @@ export const commonLogic = async (values: MulticallTransactionInput) => { params.push(...feeRecipientParams) } - if (validatorsRoot) { - const validatorsRootParams = getValidatorsRootParams({ ...baseInput, validatorsRoot }) + if (depositDataRoot) { + const validatorsRootParams = getDepositDataRootParams({ ...baseInput, depositDataRoot }) params.push(...validatorsRootParams) } diff --git a/src/methods/vault/transactions/setDepositDataRoot/common.ts b/src/methods/vault/transactions/setDepositDataRoot/common.ts index b7697d64..2bbaa4c2 100644 --- a/src/methods/vault/transactions/setDepositDataRoot/common.ts +++ b/src/methods/vault/transactions/setDepositDataRoot/common.ts @@ -3,9 +3,9 @@ import { validateArgs } from '../../../../utils' export const commonLogic = (values: SetDepositDataRootInput) => { - const { vaultAddress, validatorsRoot, userAddress } = values + const { vaultAddress, depositDataRoot, userAddress } = values - validateArgs.string({ validatorsRoot }) + validateArgs.string({ depositDataRoot }) validateArgs.address({ vaultAddress, userAddress }) return values.contracts.base.depositDataRegistry diff --git a/src/methods/vault/transactions/setDepositDataRoot/index.ts b/src/methods/vault/transactions/setDepositDataRoot/index.ts index 71d237b0..215299d7 100644 --- a/src/methods/vault/transactions/setDepositDataRoot/index.ts +++ b/src/methods/vault/transactions/setDepositDataRoot/index.ts @@ -6,14 +6,14 @@ import setDepositDataRootEncode from './setDepositDataRootEncode' const setDepositDataRoot: SetDepositDataRoot = async (values) => { - const { provider, userAddress, vaultAddress, validatorsRoot } = values + const { provider, userAddress, vaultAddress, depositDataRoot } = values const contract = commonLogic(values) const signer = await provider.getSigner(userAddress) const signedDepositDataRegistryContract = contract.connect(signer) - const result = await signedDepositDataRegistryContract.setDepositDataRoot(vaultAddress, validatorsRoot) + const result = await signedDepositDataRegistryContract.setDepositDataRoot(vaultAddress, depositDataRoot) return result?.hash } diff --git a/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootEncode.ts b/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootEncode.ts index 1afccf18..6de81b88 100644 --- a/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootEncode.ts +++ b/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootEncode.ts @@ -5,7 +5,7 @@ import type { SetDepositDataRootInput } from './types' const setDepositDataRootEncode = async (values: SetDepositDataRootInput) => { const contract = commonLogic(values) - return contract.setDepositDataRoot.populateTransaction(values.vaultAddress, values.validatorsRoot) + return contract.setDepositDataRoot.populateTransaction(values.vaultAddress, values.depositDataRoot) } diff --git a/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootGas.ts b/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootGas.ts index bb51a196..9419d506 100644 --- a/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootGas.ts +++ b/src/methods/vault/transactions/setDepositDataRoot/setDepositDataRootGas.ts @@ -4,14 +4,14 @@ import type { SetDepositDataRootInput } from './types' const setDepositDataRootGas = async (values: SetDepositDataRootInput) => { - const { provider, userAddress, vaultAddress, validatorsRoot } = values + const { provider, userAddress, vaultAddress, depositDataRoot } = values const contract = commonLogic(values) const signer = await provider.getSigner(userAddress) const signedDepositDataRegistryContract = contract.connect(signer) - const estimatedGas = await signedDepositDataRegistryContract.setDepositDataRoot.estimateGas(vaultAddress, validatorsRoot) + const estimatedGas = await signedDepositDataRegistryContract.setDepositDataRoot.estimateGas(vaultAddress, depositDataRoot) return getGas({ estimatedGas, provider: values.provider }) } diff --git a/src/methods/vault/transactions/setDepositDataRoot/types.d.ts b/src/methods/vault/transactions/setDepositDataRoot/types.d.ts index 7cce650d..2ffedb08 100644 --- a/src/methods/vault/transactions/setDepositDataRoot/types.d.ts +++ b/src/methods/vault/transactions/setDepositDataRoot/types.d.ts @@ -1,7 +1,7 @@ export type SetDepositDataRootInput = { userAddress: string vaultAddress: string - validatorsRoot: string + depositDataRoot: string options: StakeWise.Options provider: StakeWise.Provider contracts: StakeWise.Contracts diff --git a/src/methods/vault/transactions/util/params/getDepositDataRootParams.ts b/src/methods/vault/transactions/util/params/getDepositDataRootParams.ts new file mode 100644 index 00000000..3c670749 --- /dev/null +++ b/src/methods/vault/transactions/util/params/getDepositDataRootParams.ts @@ -0,0 +1,24 @@ +import { validateArgs } from '../../../../../utils' +import { vaultMulticall } from '../../../../../contracts' + + +export type SetDepositDataRootParams = { + depositDataRoot: string +} + +const getDepositDataRootParams = (values: SetDepositDataRootParams) => { + const { depositDataRoot } = values + + validateArgs.string({ depositDataRoot }) + + const params: Parameters[0]['request']['params'] = [ + { + method: 'setValidatorsRoot', args: [ depositDataRoot ], + }, + ] + + return params +} + + +export default getDepositDataRootParams diff --git a/src/methods/vault/transactions/util/params/getValidatorsRootParams.ts b/src/methods/vault/transactions/util/params/getValidatorsRootParams.ts deleted file mode 100644 index b5f8c357..00000000 --- a/src/methods/vault/transactions/util/params/getValidatorsRootParams.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { validateArgs } from '../../../../../utils' -import { vaultMulticall } from '../../../../../contracts' - - -export type SetValidatorsRootParams = { - validatorsRoot: string -} - -const getValidatorsRootParams = (values: SetValidatorsRootParams) => { - const { validatorsRoot } = values - - validateArgs.string({ validatorsRoot }) - - const params: Parameters[0]['request']['params'] = [ - { - method: 'setValidatorsRoot', args: [ validatorsRoot ], - }, - ] - - return params -} - - -export default getValidatorsRootParams diff --git a/src/methods/vault/transactions/util/params/index.ts b/src/methods/vault/transactions/util/params/index.ts index ee547c84..8915c7d5 100644 --- a/src/methods/vault/transactions/util/params/index.ts +++ b/src/methods/vault/transactions/util/params/index.ts @@ -3,7 +3,7 @@ export { default as getBlocklistParams } from './getBlocklistParams' export { default as getWhitelistParams } from './getWhitelistParams' export { default as getWhitelisterParams } from './getWhitelisterParams' export { default as getFeeRecipientParams } from './getFeeRecipientParams' -export { default as getValidatorsRootParams } from './getValidatorsRootParams' +export { default as getDepositDataRootParams } from './getDepositDataRootParams' export { default as getBlocklistManagerParams } from './getBlocklistManagerParams' export { default as getValidatorsManagerParams } from './getValidatorsManagerParams' export { default as getDepositDataManagerParams } from './getDepositDataManagerParams' diff --git a/src/utils/configs/chiado.ts b/src/utils/configs/chiado.ts index 69bb4b7a..0df01e95 100644 --- a/src/utils/configs/chiado.ts +++ b/src/utils/configs/chiado.ts @@ -7,7 +7,7 @@ export default { network: constants.chains.chiado, api: { backend: 'https://chiado-api.stakewise.io/graphql', - subgraph: 'https://chiado-graph.stakewise.io/subgraphs/name/stakewise/stakewise', + subgraph: 'https://graphs.stakewise.io/chiado/subgraphs/name/stakewise/prod', }, pages: { beaconchain: 'https://beacon.chiadochain.net', diff --git a/src/utils/configs/gnosis.ts b/src/utils/configs/gnosis.ts index c6f92ef1..d8abc0ce 100644 --- a/src/utils/configs/gnosis.ts +++ b/src/utils/configs/gnosis.ts @@ -7,7 +7,7 @@ export default { network: constants.chains.gnosis, api: { backend: 'https://gnosis-api.stakewise.io/graphql', - subgraph: 'https://gnosis-graph.stakewise.io/subgraphs/name/stakewise/stakewise', + subgraph: 'https://graphs.stakewise.io/gnosis/subgraphs/name/stakewise/prod', }, pages: { beaconchain: 'https://gnosis.beaconcha.in', diff --git a/src/utils/configs/mainnet.ts b/src/utils/configs/mainnet.ts index 3ff35175..aa99772e 100644 --- a/src/utils/configs/mainnet.ts +++ b/src/utils/configs/mainnet.ts @@ -8,8 +8,8 @@ export default { api: { backend: 'https://mainnet-api.stakewise.io/graphql', subgraph: [ - // TODO replace with https://graphs.stakewise.io/mainnet/subgraphs/name/stakewise/prod - 'https://graphs.stakewise.io/mainnet-stage/subgraphs/name/stakewise/prod', + 'https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod', + 'https://graphs.stakewise.io/mainnet-b/subgraphs/name/stakewise/prod', ], }, pages: { From 70088c7e772bb9ba97e72f5d641e5467b134876c Mon Sep 17 00:00:00 2001 From: Mike Diamond Date: Wed, 25 Sep 2024 10:57:09 +0300 Subject: [PATCH 18/36] [exit queue] Update request (#173) * [exit queue] Update request * [exit queue] Update request * [exit queue] Update request --- README.md | 25 ++++++++++--------- changelog/next-release.md | 10 ++++++++ .../subgraph/exitQueue/exitQueueQuery.graphql | 15 +++++------ .../fetchExitQueuePositions.ts | 4 ++- .../requests/getExitQueuePositions/index.ts | 8 ++++-- src/utils/validateArgs.ts | 9 +++++++ 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index b205fd8f..0d2bd1ea 100644 --- a/README.md +++ b/README.md @@ -468,10 +468,11 @@ Returns the withdrawal queue for a specific user. #### Arguments: -| Name | Type | Required | -|------|------|----------| -| userAddress | `string` | **Yes** | -| vaultAddress | `string` | **Yes** | +| Name | Type | Required | +|--------------|-----------|----------| +| userAddress | `string` | **Yes** | +| vaultAddress | `string` | **Yes** | +| isClaimed | `boolean` | **No** | #### Returns: @@ -499,14 +500,14 @@ type Output = { } ``` -| Name | Description | -|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `pending` | Positions not yet available for claim | -| `positions` | Positions in a special format that are required for claiming | -| `total` | Total queued assets (e.g. ETH) | -| `duration` | Queue duration time (in seconds).
- It represents the approximate time after which the assets can be collected (in seconds).
- If the value is null, the time is still being calculated.
- If the value is 0, the assets are available and can be collected. | -| | |- -| `withdrawable` | Assets available for withdrawal (e.g. ETH) | +| Name | Description | +|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `pending` | Positions not yet available for claim | +| `positions` | Positions in a special format that are required for claiming | +| `total` | Total queued assets (e.g. ETH) | +| `duration` | Queue duration time (in seconds).
- It represents the approximate time after which the assets can be collected (in seconds).
- If the value is null, the time is still being calculated.
- If the value is 0, the assets are available and can be collected. | +| | |- +| `withdrawable` | Assets available for withdrawal (e.g. ETH) | #### Example: diff --git a/changelog/next-release.md b/changelog/next-release.md index 33a25810..879d1fe8 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -56,3 +56,13 @@ type RemovedOutput = { ### 5. Added method getStakewiseStats ### `sdk.utils.getStakewiseStats` + +--- + +### 6. Added optional input field +### `sdk.vault.getExitQueuePositions` +#### Added Argument: + +| Name | Type | Required | +|--------------|-----------|----------| +| isClaimed | `boolean` | **No** | \ No newline at end of file diff --git a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql index 38f22216..9ecaf5e8 100644 --- a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql +++ b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql @@ -1,15 +1,16 @@ -query exitQueue($receiver: Bytes, $vault: String!) { +query exitQueue($receiver: Bytes, $vault: String!, $isClaimed: Boolean!) { exitRequests(where: { receiver: $receiver, vault: $vault, + isClaimed: $isClaimed }) { - withdrawalTimestamp - positionTicket - isV2Position - totalAssets timestamp - exitQueueIndex - exitedAssets + totalAssets isClaimable + isV2Position + exitedAssets + positionTicket + exitQueueIndex + withdrawalTimestamp } } diff --git a/src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts b/src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts index 78f90393..4130fdd7 100644 --- a/src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts +++ b/src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts @@ -6,16 +6,18 @@ export type FetchExitQueuePositionsInput = { options: StakeWise.Options vaultAddress: string userAddress: string + isClaimed?: boolean } const fetchExitQueuePositions = (values: FetchExitQueuePositionsInput) => { - const { options, vaultAddress, userAddress } = values + const { options, vaultAddress, userAddress, isClaimed = false } = values return graphql.subgraph.exitQueue.fetchExitQueueQuery({ url: apiUrls.getSubgraphqlUrl(options), variables: { vault: vaultAddress.toLowerCase(), receiver: userAddress.toLowerCase(), + isClaimed, }, modifyResult: (data) => data?.exitRequests || [], }) diff --git a/src/methods/vault/requests/getExitQueuePositions/index.ts b/src/methods/vault/requests/getExitQueuePositions/index.ts index 218f82d6..8a0fb073 100644 --- a/src/methods/vault/requests/getExitQueuePositions/index.ts +++ b/src/methods/vault/requests/getExitQueuePositions/index.ts @@ -20,11 +20,15 @@ const mock: ParseExitRequestsOutput = { } const getExitQueuePositions = async (input: GetExitQueuePositionsInput): Promise => { - const { options, contracts, provider, vaultAddress, userAddress } = input + const { options, contracts, provider, vaultAddress, userAddress, isClaimed } = input validateArgs.address({ vaultAddress, userAddress }) - return fetchExitQueuePositions({ options, vaultAddress, userAddress }) + if (typeof isClaimed !== 'undefined') { + validateArgs.boolean({ isClaimed }) + } + + return fetchExitQueuePositions({ options, vaultAddress, userAddress, isClaimed }) .then((data) => { if (!data) { return mock diff --git a/src/utils/validateArgs.ts b/src/utils/validateArgs.ts index e3d946b7..b68b56ab 100644 --- a/src/utils/validateArgs.ts +++ b/src/utils/validateArgs.ts @@ -44,6 +44,14 @@ const number = (values: Record) => { }) } +const boolean = (values: Record) => { + Object.keys(values).forEach((key) => { + if (typeof values[key] !== 'boolean') { + throw new Error(`The "${key}" argument must be a boolean`) + } + }) +} + const array = (values: Record, withEmptyCheck: boolean = true) => { Object.keys(values).forEach((key) => { if (!Array.isArray(values[key])) { @@ -71,6 +79,7 @@ export default { bigint, string, number, + boolean, address, maxLength, } From 54614dc208b0c1eb2c2e20a2ed777f38ee373be6 Mon Sep 17 00:00:00 2001 From: Mike Diamond Date: Wed, 25 Sep 2024 14:25:47 +0300 Subject: [PATCH 19/36] [parse exit request] Update exit queue fetch (#174) * [parse exit request] Update exit queue fetch * [exit queue] Update parse exit request * [exit queue] Update parse exit request --- .../subgraph/exitQueue/exitQueueQuery.graphql | 9 +- .../fetchExitQueuePositions.ts | 27 -- .../requests/getExitQueuePositions/index.ts | 53 ++-- .../modifyExitRequests.ts | 93 ++++++ .../parseExitRequests.spec.ts | 291 ------------------ .../parseExitRequests.ts | 221 ------------- 6 files changed, 116 insertions(+), 578 deletions(-) delete mode 100644 src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts create mode 100644 src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts delete mode 100644 src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts delete mode 100644 src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts diff --git a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql index 9ecaf5e8..3c32480e 100644 --- a/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql +++ b/src/graphql/subgraph/exitQueue/exitQueueQuery.graphql @@ -1,13 +1,8 @@ -query exitQueue($receiver: Bytes, $vault: String!, $isClaimed: Boolean!) { - exitRequests(where: { - receiver: $receiver, - vault: $vault, - isClaimed: $isClaimed - }) { +query exitQueue($where: ExitRequest_filter) { + exitRequests(where: $where) { timestamp totalAssets isClaimable - isV2Position exitedAssets positionTicket exitQueueIndex diff --git a/src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts b/src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts deleted file mode 100644 index 4130fdd7..00000000 --- a/src/methods/vault/requests/getExitQueuePositions/fetchExitQueuePositions.ts +++ /dev/null @@ -1,27 +0,0 @@ -import graphql from '../../../../graphql' -import { apiUrls } from '../../../../utils' - - -export type FetchExitQueuePositionsInput = { - options: StakeWise.Options - vaultAddress: string - userAddress: string - isClaimed?: boolean -} - -const fetchExitQueuePositions = (values: FetchExitQueuePositionsInput) => { - const { options, vaultAddress, userAddress, isClaimed = false } = values - - return graphql.subgraph.exitQueue.fetchExitQueueQuery({ - url: apiUrls.getSubgraphqlUrl(options), - variables: { - vault: vaultAddress.toLowerCase(), - receiver: userAddress.toLowerCase(), - isClaimed, - }, - modifyResult: (data) => data?.exitRequests || [], - }) -} - - -export default fetchExitQueuePositions diff --git a/src/methods/vault/requests/getExitQueuePositions/index.ts b/src/methods/vault/requests/getExitQueuePositions/index.ts index 8a0fb073..3d2bc442 100644 --- a/src/methods/vault/requests/getExitQueuePositions/index.ts +++ b/src/methods/vault/requests/getExitQueuePositions/index.ts @@ -1,26 +1,19 @@ -import { validateArgs } from '../../../../utils' -import parseExitRequests from './parseExitRequests' -import fetchExitQueuePositions from './fetchExitQueuePositions' -import type { ParseExitRequestsOutput } from './parseExitRequests' -import type { FetchExitQueuePositionsInput } from './fetchExitQueuePositions' +import graphql from '../../../../graphql' +import { apiUrls, validateArgs } from '../../../../utils' +import modifyExitRequests from './modifyExitRequests' +import type { ParseExitRequestsOutput } from './modifyExitRequests' +import { StakeWiseSubgraphGraph } from '../../../../types/graphql/subgraph' -type GetExitQueuePositionsInput = FetchExitQueuePositionsInput & { - contracts: StakeWise.Contracts - provider: StakeWise.Provider +type GetExitQueuePositionsInput = { options: StakeWise.Options -} - -const mock: ParseExitRequestsOutput = { - total: 0n, - pending: [], - duration: 0, - positions: [], - withdrawable: 0n, + vaultAddress: string + userAddress: string + isClaimed?: boolean } const getExitQueuePositions = async (input: GetExitQueuePositionsInput): Promise => { - const { options, contracts, provider, vaultAddress, userAddress, isClaimed } = input + const { options, vaultAddress, userAddress, isClaimed } = input validateArgs.address({ vaultAddress, userAddress }) @@ -28,21 +21,17 @@ const getExitQueuePositions = async (input: GetExitQueuePositionsInput): Promise validateArgs.boolean({ isClaimed }) } - return fetchExitQueuePositions({ options, vaultAddress, userAddress, isClaimed }) - .then((data) => { - if (!data) { - return mock - } - - return parseExitRequests({ - options, - provider, - contracts, - userAddress, - vaultAddress, - exitRequests: data, - }) - }) + return graphql.subgraph.exitQueue.fetchExitQueueQuery({ + url: apiUrls.getSubgraphqlUrl(options), + variables: { + where: { + vault: vaultAddress.toLowerCase(), + receiver: userAddress.toLowerCase(), + isClaimed, + } as StakeWiseSubgraphGraph.ExitRequest_Filter, + }, + modifyResult: modifyExitRequests, + }) } diff --git a/src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts b/src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts new file mode 100644 index 00000000..e4a70972 --- /dev/null +++ b/src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts @@ -0,0 +1,93 @@ +import { ExitQueueQueryPayload } from 'graphql/subgraph/exitQueue' + + +type ExitRequest = Omit & { + withdrawalTimestamp: string | null +} + +export type ParseExitRequestsInput = { + exitRequests: ExitRequest[] +} + +type Position = { + exitQueueIndex: bigint + positionTicket: string + timestamp: string +} + +export type ParseExitRequestsOutput = { + total: bigint + withdrawable: bigint + positions: Position[] + pending: ExitRequest[] + duration: number | null +} + +const modifyExitRequests = async (values: ParseExitRequestsInput): Promise => { + const { exitRequests } = values + + if (!exitRequests.length) { + return { + total: 0n, + duration: 0, + pending: [], + positions: [], + withdrawable: 0n, + } + } + + let total = 0n + let withdrawable = 0n + let duration: null | number = 0 + + const positions: Position[] = [] + const pending: ExitRequest[] = [] + + exitRequests.forEach((exitRequest) => { + const { + timestamp, + totalAssets, + isClaimable, + exitedAssets, + exitQueueIndex, + positionTicket, + } = exitRequest + + total += BigInt(totalAssets || 0) + + if (isClaimable) { + withdrawable += BigInt(exitedAssets || 0) + + positions.push({ + timestamp, + positionTicket, + exitQueueIndex: BigInt(exitQueueIndex), + }) + } + else { + pending.push(exitRequest) + } + + if (exitRequest.withdrawalTimestamp === null) { + duration = null + } + else if (duration !== null) { + const withdrawalTimestamp = Number(exitRequest.withdrawalTimestamp) + + if (withdrawalTimestamp > duration) { + duration = withdrawalTimestamp + } + } + }) + + return { + total, + pending, + duration, + positions, + withdrawable, + } +} + + +export default modifyExitRequests diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts deleted file mode 100644 index c1ad5eab..00000000 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.spec.ts +++ /dev/null @@ -1,291 +0,0 @@ -import { JsonRpcProvider, ZeroAddress } from 'ethers' - -import { Network, configs } from '../../../../utils' -import { createContracts } from '../../../../contracts' -import vaultMulticall from '../../../../contracts/multicall/vaultMulticall' -import parseExitRequests, { ParseExitRequestsInput } from './parseExitRequests' - - -jest.mock('../../../../contracts/multicall/vaultMulticall') - -const getMockProvider = (timestamp: number) => ({ - getBlock() { - return { - timestamp, - } - }, -}) as unknown as StakeWise.Provider - -describe('parseExitRequests function', () => { - const network = Network.Holesky - const config = configs[network] - - const provider = new JsonRpcProvider('') - const contracts = createContracts({ provider, config }) - - const input: ParseExitRequestsInput = { - contracts, - options: { network }, - userAddress: ZeroAddress, - vaultAddress: ZeroAddress, - provider: getMockProvider(9999999999), - exitRequests: [ - { - positionTicket: 'positionTicket-1', - withdrawalTimestamp: '1718536919', - timestamp: '123456', - totalAssets: '0', - // totalShares: '100', - isV2Position: false, - }, - { - positionTicket: 'positionTicket-2', - withdrawalTimestamp: '1718536919', - timestamp: '123457', - totalAssets: '0', - // totalShares: '200', - isV2Position: false, - }, - { - positionTicket: 'positionTicket-2', - withdrawalTimestamp: '1718536919', - timestamp: '123458', - totalAssets: '300', - // totalShares: '0', - isV2Position: false, - }, - ], - } - - beforeEach(() => { - (vaultMulticall as jest.Mock).mockClear() - }) - - it('should parse exit requests correctly', async () => { - (vaultMulticall as jest.Mock) - .mockResolvedValueOnce([ - [ 1n ], - [ 2n ], - [ 3n ], - ]) - .mockResolvedValueOnce([ - { - exitedAssets: 30n, - exitedTickets: 50n, - leftTickets: 10n, - }, - { - exitedAssets: 1n, - exitedTickets: 100n, - leftTickets: 20n, - }, - { - exitedAssets: 250n, - exitedTickets: 200n, - leftTickets: 30n, - }, - ]) - .mockResolvedValueOnce([ - { assets: 100n }, - ]) - - const result = await parseExitRequests(input) - - expect(vaultMulticall).toHaveBeenCalledTimes(3) - - expect(result).toEqual({ - positions: [ - { - exitQueueIndex: 1n, - timestamp: '123456', - isV1Position: true, - positionTicket: 'positionTicket-1', - }, - { - exitQueueIndex: 2n, - timestamp: '123457', - isV1Position: true, - positionTicket: 'positionTicket-2', - }, - { - exitQueueIndex: 3n, - timestamp: '123458', - isV1Position: false, - positionTicket: 'positionTicket-2', - }, - ], - pending: [], - total: 431n, - duration: 1718536919, - withdrawable: 281n, - }) - }) - - it('should hide the position if it hasn\'t been 24 hours', async () => { - (vaultMulticall as jest.Mock) - .mockResolvedValueOnce([ - [ 1n ], - [ 2n ], - ]) - .mockResolvedValueOnce([ - { assets: 100n }, - ]) - - const result = await parseExitRequests({ - ...input, - provider: getMockProvider(1), - }) - - expect(vaultMulticall).toHaveBeenCalledTimes(2) - - expect(result).toEqual({ - total: 100n, - duration: 1718536919, - positions: [], - withdrawable: 0n, - pending: [ - { - positionTicket: 'positionTicket-1', - withdrawalTimestamp: '1718536919', - timestamp: '123456', - totalAssets: '0', - totalShares: '100', - }, - { - positionTicket: 'positionTicket-2', - withdrawalTimestamp: '1718536919', - timestamp: '123457', - totalAssets: '0', - totalShares: '200', - }, - ], - }) - }) - - it('should handle -1 indexes from getExitQueueIndex', async () => { - (vaultMulticall as jest.Mock) - .mockResolvedValueOnce([ - [ -1n ], - [ -1n ], - ]) - .mockResolvedValueOnce([ { assets: 50n } ]) - - const result = await parseExitRequests(input) - - expect(result).toEqual({ - total: 50n, - positions: [], - withdrawable: 0n, - duration: 1718536919, - pending: [ - { - positionTicket: 'positionTicket-1', - withdrawalTimestamp: '1718536919', - timestamp: '123456', - totalAssets: '0', - totalShares: '100', - }, - { - positionTicket: 'positionTicket-2', - withdrawalTimestamp: '1718536919', - timestamp: '123457', - totalAssets: '0', - totalShares: '200', - }, - ], - }) - }) - - it('should handle mixed indexes from getExitQueueIndex', async () => { - (vaultMulticall as jest.Mock) - .mockResolvedValueOnce([ - [ -1n ], - [ 1n ], - [ -1n ], - ]) - .mockResolvedValueOnce([ - { - leftTickets: 10n, - exitedTickets: 50n, - exitedAssets: 30n, - }, - ]) - .mockResolvedValueOnce([ { assets: 50n } ]) - - const result = await parseExitRequests(input) - - expect(result).toEqual({ - positions: [ - { - exitQueueIndex: 1n, - timestamp: '123457', - isV1Position: true, - positionTicket: 'positionTicket-2', - }, - ], - pending: [ - { - positionTicket: 'positionTicket-1', - withdrawalTimestamp: '1718536919', - timestamp: '123456', - totalAssets: '0', - totalShares: '100', - }, - { - positionTicket: 'positionTicket-2', - withdrawalTimestamp: '1718536919', - timestamp: '123458', - totalAssets: '300', - totalShares: '0', - }, - ], - total: 380n, - duration: 1718536919, - withdrawable: 30n, - }) - }) - - it('should handle all newPositionTicket being 0', async () => { - (vaultMulticall as jest.Mock) - .mockResolvedValueOnce([ - [ 0n ], - [ 1n ], - [ 1n ], - ]) - .mockResolvedValueOnce([ - { leftTickets: 0n, exitedTickets: 100n, exitedAssets: 101n }, - { leftTickets: 0n, exitedTickets: 200n, exitedAssets: 202n }, - { leftTickets: 0n, exitedTickets: 300n, exitedAssets: 300n }, - ]) - .mockResolvedValueOnce([ { assets: 0n } ]) - - const result = await parseExitRequests(input) - - expect(result).toEqual({ - positions: [ - { - exitQueueIndex: 0n, - timestamp: '123456', - isV1Position: true, - positionTicket: 'positionTicket-1', - }, - { - exitQueueIndex: 1n, - timestamp: '123457', - isV1Position: true, - positionTicket: 'positionTicket-2', - }, - { - exitQueueIndex: 1n, - timestamp: '123458', - isV1Position: false, - positionTicket: 'positionTicket-2', - }, - ], - pending: [], - total: 603n, - duration: 1718536919, - withdrawable: 603n, - }) - }) -}) diff --git a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts b/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts deleted file mode 100644 index 94c598aa..00000000 --- a/src/methods/vault/requests/getExitQueuePositions/parseExitRequests.ts +++ /dev/null @@ -1,221 +0,0 @@ -import vaultMulticall from '../../../../contracts/multicall/vaultMulticall' - - -type ExitRequest = { - withdrawalTimestamp: string | null - positionTicket: string - isV2Position: boolean - // totalShares: string - totalAssets: string - timestamp: string -} - -export type ParseExitRequestsInput = { - contracts: StakeWise.Contracts - provider: StakeWise.Provider - exitRequests: ExitRequest[] - options: StakeWise.Options - userAddress: string - vaultAddress: string -} - -type Position = { - exitQueueIndex: bigint - positionTicket: string - isV2Position: boolean - timestamp: string -} - -export type ParseExitRequestsOutput = { - total: bigint - withdrawable: bigint - positions: Position[] - pending: ExitRequest[] - duration: number | null -} - -type ExitedAssetsResponse = Array<{ - leftTickets: bigint - exitedTickets: bigint - exitedAssets: bigint -}> - -const _getDuration = (data: ParseExitRequestsInput['exitRequests']): ParseExitRequestsOutput['duration'] => { - if (!data || !data.length) { - return 0 - } - - // which means the exit queue withdrawal time is still being calculated - const hasNullWithdrawal = data.some((item) => item.withdrawalTimestamp === null) - - if (hasNullWithdrawal) { - return null - } - - const durations = data.map((item) => Number(item.withdrawalTimestamp)) - const biggestValue = Math.max(...durations) - - return biggestValue -} - -const _checkTimestamp = async (timestamp: string, provider: StakeWise.Provider) => { - const lastBlock = await provider.getBlock('latest') - - const current = lastBlock - ? lastBlock.timestamp - : Number((new Date().getTime() / 1000).toFixed(0)) - - const diff = Number(current) - Number(timestamp) - - return diff > 86_400 // 24 hours -} - -const parseExitRequests = async (values: ParseExitRequestsInput): Promise => { - const { options, contracts, provider, userAddress, vaultAddress, exitRequests } = values - - if (!exitRequests.length) { - return { - total: 0n, - duration: 0, - pending: [], - positions: [], - withdrawable: 0n, - } - } - - const duration = _getDuration(exitRequests) - const keeperContract = contracts.base.keeper - const vaultContract = contracts.helpers.createVault({ vaultAddress }) - - const commonMulticallParams = { - options, - userAddress, - vaultAddress, - vaultContract, - keeperContract, - } - - // We must fetch the exit queue index for every position. - // Based on the response we can determine if we can claim exited assets. - const indexesResponse = await vaultMulticall>({ - ...commonMulticallParams, - request: { - params: exitRequests.map(({ positionTicket }) => ({ - method: 'getExitQueueIndex', - args: [ positionTicket ], - })), - callStatic: true, - }, - }) - - const pending = [] - const claims: Position[] = [] - const indexes = (indexesResponse || []) - - let queuedShares = 0n, - queuedAssets = 0n - - for (let i = 0; i < indexes.length; i++) { - const { positionTicket, timestamp, totalAssets, isV2Position } = exitRequests[i] - // const { positionTicket, timestamp, totalShares, totalAssets, isV2Position } = exitRequests[i] - - // queuedShares += BigInt(totalShares || 0) - queuedAssets += BigInt(totalAssets || 0) - - // If the index is -1 then we cannot claim anything. Otherwise, the value is >= 0. - const exitQueueIndex = indexes[i][0] - - if (exitQueueIndex < 0n) { - pending.push(exitRequests[i]) - - continue - } - - // 24 hours must have elapsed since the position was created - const is24HoursPassed = await _checkTimestamp(timestamp, provider) - - if (is24HoursPassed) { - const item = { exitQueueIndex, positionTicket, timestamp, isV2Position } - - claims.push(item) - } - else { - pending.push(exitRequests[i]) - } - } - - if (!claims.length) { - const result = await vaultMulticall>({ - ...commonMulticallParams, - request: { - params: [ { method: 'convertToAssets', args: [ queuedShares ] } ], - callStatic: true, - }, - }) - const totalV1QueuedAssets = result[0]?.assets || 0n - - // If there are no positions with an index greater than 0 or their timestamp has failed the 24-hour check. - // Then we can use totalShares from the subgraph to show total - return { - pending, - duration, - positions: [], - withdrawable: 0n, - total: totalV1QueuedAssets + queuedAssets, - } - } - - // We need to calculate the exited assets for every position. - const exitedAssetsResponse = await vaultMulticall({ - ...commonMulticallParams, - request: { - params: claims.map(({ positionTicket, exitQueueIndex, timestamp }) => ({ - method: 'calculateExitedAssets', - args: [ userAddress, positionTicket, timestamp, exitQueueIndex ], - })), - callStatic: true, - }, - }) || [] - - // Calculate total withdrawable assets - let withdrawableAssets = 0n - - exitedAssetsResponse.forEach(({ exitedTickets, exitedAssets }, i) => { - const { isV2Position } = claims[i] - - if (isV2Position) { - // in V2 vaults exit queue exit tickets are assets, for v1 and v3+ will be shares - queuedAssets -= BigInt(exitedAssets || 0) - } - else { - queuedShares -= BigInt(exitedTickets || 0) - } - - withdrawableAssets += BigInt(exitedAssets || 0) - }) - - if (queuedShares > 0) { - const result = await vaultMulticall>({ - ...commonMulticallParams, - request: { - params: [ { method: 'convertToAssets', args: [ queuedShares ] } ], - callStatic: true, - }, - }) - - queuedAssets += result[0]?.assets || 0n - } - - const total = withdrawableAssets + queuedAssets - - return { - total, - pending, - duration, - positions: claims, - withdrawable: withdrawableAssets, - } -} - - -export default parseExitRequests From e5dfa502630cd44a9ac464c34bbe9e5977d767ed Mon Sep 17 00:00:00 2001 From: Mike Diamond Date: Thu, 26 Sep 2024 17:32:47 +0300 Subject: [PATCH 20/36] Vault user (#175) * [vault user] add allocators request * [vault user] update stake balance * [vault user] update stake balance * [vault user] update claim amount * [vault user] update claim amount * [vault user] update readme * [vault user] update readme --- README.md | 7 ++- changelog/next-release.md | 14 +++++- .../allocator/allocatorsQuery.graphql | 10 ++++ src/graphql/subgraph/allocator/index.ts | 2 + src/graphql/subgraph/index.ts | 1 + src/graphql/subgraph/rewardSplitters/index.ts | 3 ++ .../rewardSplitterShareHoldersQuery.graphql | 13 ++++++ .../rewardSplitter/requests/getClaimAmount.ts | 30 ++++++++++++ .../getClaimAmount/getAssetsFromShares.ts | 34 -------------- .../requests/getClaimAmount/getShares.ts | 35 -------------- .../requests/getClaimAmount/index.ts | 32 ------------- src/methods/vault/requests/getStakeBalance.ts | 46 ++++++------------- 12 files changed, 87 insertions(+), 140 deletions(-) create mode 100644 src/graphql/subgraph/allocator/allocatorsQuery.graphql create mode 100644 src/graphql/subgraph/allocator/index.ts create mode 100644 src/graphql/subgraph/rewardSplitters/rewardSplitterShareHoldersQuery.graphql create mode 100644 src/methods/rewardSplitter/requests/getClaimAmount.ts delete mode 100644 src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts delete mode 100644 src/methods/rewardSplitter/requests/getClaimAmount/getShares.ts delete mode 100644 src/methods/rewardSplitter/requests/getClaimAmount/index.ts diff --git a/README.md b/README.md index 0d2bd1ea..cb8c3810 100644 --- a/README.md +++ b/README.md @@ -776,10 +776,9 @@ type Output = { } ``` -| Name | Description | -|------|-------------| -| `shares` | Balance in vault tokens | -| `assets` | Balance in ETH | +| Name | Description | +|----------|-------------------------| +| `assets` | Balance in ETH | #### Example: diff --git a/changelog/next-release.md b/changelog/next-release.md index 879d1fe8..046e91ca 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -44,7 +44,6 @@ type AddedOutput = { ### 4. Removed output field ### `sdk.osToken.getPosition` -#### New output field: ```ts type RemovedOutput = { @@ -65,4 +64,15 @@ type RemovedOutput = { | Name | Type | Required | |--------------|-----------|----------| -| isClaimed | `boolean` | **No** | \ No newline at end of file +| isClaimed | `boolean` | **No** | + +--- + +### 7. Removed output field +### `sdk.vault.getStakeBalance` + +```ts +type RemovedOutput = { + shares: bigint +} +``` diff --git a/src/graphql/subgraph/allocator/allocatorsQuery.graphql b/src/graphql/subgraph/allocator/allocatorsQuery.graphql new file mode 100644 index 00000000..3cc1717f --- /dev/null +++ b/src/graphql/subgraph/allocator/allocatorsQuery.graphql @@ -0,0 +1,10 @@ +query Allocators($address: Bytes!, $vaultAddress: String!) { + allocators( + where: { + address: $address, + vault: $vaultAddress + } + ) { + assets + } +} diff --git a/src/graphql/subgraph/allocator/index.ts b/src/graphql/subgraph/allocator/index.ts new file mode 100644 index 00000000..38658030 --- /dev/null +++ b/src/graphql/subgraph/allocator/index.ts @@ -0,0 +1,2 @@ +export { fetchAllocatorsQuery } from './allocatorsQuery.graphql' +export type { AllocatorsQueryPayload, AllocatorsQueryVariables } from './allocatorsQuery.graphql' diff --git a/src/graphql/subgraph/index.ts b/src/graphql/subgraph/index.ts index b816e9da..f541aafe 100644 --- a/src/graphql/subgraph/index.ts +++ b/src/graphql/subgraph/index.ts @@ -1,6 +1,7 @@ export * as stats from './stats' export * as vault from './vault' export * as osToken from './osToken' +export * as allocator from './allocator' export * as eigenPods from './eigenPods' export * as exitQueue from './exitQueue' export * as transactions from './transactions' diff --git a/src/graphql/subgraph/rewardSplitters/index.ts b/src/graphql/subgraph/rewardSplitters/index.ts index 6e0cc167..59a131fb 100644 --- a/src/graphql/subgraph/rewardSplitters/index.ts +++ b/src/graphql/subgraph/rewardSplitters/index.ts @@ -1,2 +1,5 @@ export { fetchRewardSplittersQuery } from './rewardSplittersQuery.graphql' export type { RewardSplittersQueryPayload, RewardSplittersQueryVariables } from './rewardSplittersQuery.graphql' + +export { fetchRewardSplitterShareHoldersQuery } from './rewardSplitterShareHoldersQuery.graphql' +export type { RewardSplitterShareHoldersQueryPayload, RewardSplitterShareHoldersQueryVariables } from './rewardSplitterShareHoldersQuery.graphql' diff --git a/src/graphql/subgraph/rewardSplitters/rewardSplitterShareHoldersQuery.graphql b/src/graphql/subgraph/rewardSplitters/rewardSplitterShareHoldersQuery.graphql new file mode 100644 index 00000000..0cc6bbfc --- /dev/null +++ b/src/graphql/subgraph/rewardSplitters/rewardSplitterShareHoldersQuery.graphql @@ -0,0 +1,13 @@ +query RewardSplitterShareHolders($address: Bytes!, $vaultAddress: String!, $rewardSplitterAddress: ID!) { + rewardSplitterShareHolders( + where: { + address: $address, + vault: $vaultAddress + rewardSplitter_: { + id: $rewardSplitterAddress + } + } + ) { + earnedVaultAssets + } +} diff --git a/src/methods/rewardSplitter/requests/getClaimAmount.ts b/src/methods/rewardSplitter/requests/getClaimAmount.ts new file mode 100644 index 00000000..4a28e645 --- /dev/null +++ b/src/methods/rewardSplitter/requests/getClaimAmount.ts @@ -0,0 +1,30 @@ +import { apiUrls, validateArgs } from '../../../utils' +import graphql from '../../../graphql' + + +type GetClaimAmountInput = { + vaultAddress: string + userAddress: string + rewardSplitterAddress: string + options: StakeWise.Options + contracts: StakeWise.Contracts +} + +const getClaimAmount = (input: GetClaimAmountInput) => { + const { vaultAddress, userAddress, rewardSplitterAddress, options } = input + + validateArgs.address({ vaultAddress, userAddress, rewardSplitterAddress }) + + return graphql.subgraph.rewardSplitters.fetchRewardSplitterShareHoldersQuery({ + url: apiUrls.getSubgraphqlUrl(options), + variables: { + address: userAddress.toLowerCase(), + vaultAddress: vaultAddress.toLowerCase(), + rewardSplitterAddress: rewardSplitterAddress.toLowerCase(), + }, + modifyResult: (data) => BigInt(data.rewardSplitterShareHolders?.[0]?.earnedVaultAssets || 0), + }) +} + + +export default getClaimAmount diff --git a/src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts b/src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts deleted file mode 100644 index 376f259c..00000000 --- a/src/methods/rewardSplitter/requests/getClaimAmount/getAssetsFromShares.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { vaultMulticall } from '../../../../contracts' - - -type GetAssetsFromSharesInput = { - shares: bigint - vaultAddress: string - userAddress: string - options: StakeWise.Options - contracts: StakeWise.Contracts -} - -const getAssetsFromShares = async (input: GetAssetsFromSharesInput) => { - const { shares, vaultAddress, userAddress, options, contracts } = input - - const request = { - params: [ - { method: 'convertToAssets', args: [ shares ] }, - ], - callStatic: true, - } - - const result = await vaultMulticall<[ { assets: bigint } ]>({ - request, - options, - userAddress, - vaultAddress, - vaultContract: contracts.helpers.createVault({ vaultAddress }), - }) - - return result?.[0]?.assets | 0n -} - - -export default getAssetsFromShares diff --git a/src/methods/rewardSplitter/requests/getClaimAmount/getShares.ts b/src/methods/rewardSplitter/requests/getClaimAmount/getShares.ts deleted file mode 100644 index be29c174..00000000 --- a/src/methods/rewardSplitter/requests/getClaimAmount/getShares.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { rewardSplitterMulticall } from '../../../../contracts' - - -type GetSharesInput = { - vaultAddress: string - userAddress: string - rewardSplitterAddress: string - options: StakeWise.Options - contracts: StakeWise.Contracts -} - -const getShares = async (input: GetSharesInput) => { - const { vaultAddress, userAddress, rewardSplitterAddress, options, contracts } = input - - const request = { - params: [ - { method: 'syncRewards', args: [] }, - { method: 'rewardsOf', args: [ userAddress ] }, - ], - callStatic: true, - } - - const result = await rewardSplitterMulticall<[ [], [ bigint ] ]>({ - request, - options, - userAddress, - vaultAddress, - rewardSplitterContract: contracts.helpers.createRewardSplitter(rewardSplitterAddress), - }) - - return result?.[1]?.[0] || 0n -} - - -export default getShares diff --git a/src/methods/rewardSplitter/requests/getClaimAmount/index.ts b/src/methods/rewardSplitter/requests/getClaimAmount/index.ts deleted file mode 100644 index 7b499dec..00000000 --- a/src/methods/rewardSplitter/requests/getClaimAmount/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { validateArgs } from '../../../../utils' -import { wrapAbortPromise } from '../../../../modules/gql-module' - -import getShares from './getShares' -import getAssetsFromShares from './getAssetsFromShares' - - -type GetClaimAmountInput = { - vaultAddress: string - userAddress: string - rewardSplitterAddress: string - options: StakeWise.Options - contracts: StakeWise.Contracts -} - -const getClaimAmount = async (input: GetClaimAmountInput) => { - const { vaultAddress, userAddress, rewardSplitterAddress, options, contracts } = input - - validateArgs.address({ vaultAddress, userAddress, rewardSplitterAddress }) - - const commonInput = { vaultAddress, userAddress, rewardSplitterAddress, options, contracts } - const shares = await getShares({ ...commonInput, rewardSplitterAddress }) - - if (shares) { - return getAssetsFromShares({ ...commonInput, shares }) - } - - return 0n -} - - -export default wrapAbortPromise(getClaimAmount) diff --git a/src/methods/vault/requests/getStakeBalance.ts b/src/methods/vault/requests/getStakeBalance.ts index c8d48ebc..70bc527c 100644 --- a/src/methods/vault/requests/getStakeBalance.ts +++ b/src/methods/vault/requests/getStakeBalance.ts @@ -1,6 +1,5 @@ -import { validateArgs } from '../../../utils' -import { vaultMulticall } from '../../../contracts' -import { wrapAbortPromise } from '../../../modules/gql-module' +import { apiUrls, validateArgs } from '../../../utils' +import graphql from '../../../graphql' type GetStakeBalanceInput = { @@ -10,41 +9,22 @@ type GetStakeBalanceInput = { contracts: StakeWise.Contracts } -type Output = { - shares: bigint - assets: bigint -} - -const getStakeBalance = async (values: GetStakeBalanceInput) => { - const { contracts, options, vaultAddress, userAddress } = values +const getStakeBalance = (values: GetStakeBalanceInput) => { + const { options, vaultAddress, userAddress } = values validateArgs.address({ vaultAddress, userAddress }) - const vaultContract = contracts.helpers.createVault({ vaultAddress }) - - const balanceShares = await vaultContract.getShares(userAddress) - - const result = await vaultMulticall<[ [ bigint ] ]>({ - options, - userAddress, - vaultAddress, - vaultContract, - request: { - callStatic: true, - params: [ - { - method: 'convertToAssets', - args: [ balanceShares ], - }, - ], + return graphql.subgraph.allocator.fetchAllocatorsQuery({ + url: apiUrls.getSubgraphqlUrl(options), + variables: { + address: userAddress.toLowerCase(), + vaultAddress: vaultAddress.toLowerCase(), }, + modifyResult: (data) => ({ + assets: BigInt(data?.allocators?.[0]?.assets || 0), + }), }) - - return { - shares: balanceShares || 0n, - assets: result?.[0]?.[0] || 0n, - } } -export default wrapAbortPromise(getStakeBalance) +export default getStakeBalance From df65d64a69f5a4ece72031f98f9058469892991b Mon Sep 17 00:00:00 2001 From: Mike Diamond Date: Fri, 27 Sep 2024 13:18:12 +0300 Subject: [PATCH 21/36] [get config] update get config (#177) * [get config] update get config * [get config] update get config * [get config] update get config * [get config] update get config * [get config] update get config --- README.md | 34 ++++++++++++++- changelog/next-release.md | 7 ++-- src/methods/osToken/index.ts | 3 +- src/methods/osToken/requests/getConfig.ts | 20 +++++++++ .../osToken/requests/getOsTokenConfig.ts | 42 ------------------- src/methods/vault/requests/getVault/index.ts | 2 +- 6 files changed, 60 insertions(+), 48 deletions(-) create mode 100644 src/methods/osToken/requests/getConfig.ts delete mode 100644 src/methods/osToken/requests/getOsTokenConfig.ts diff --git a/README.md b/README.md index cb8c3810..05bb9e4e 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ const sdk = new StakeWiseSDK({ | [vault.getMaxWithdraw](#sdkvaultgetmaxwithdraw) | [osToken.getSharesFromAssets](#sdkostokengetsharesfromassets) | | | [vault.getHarvestParams](#sdkvaultgetharvestparams) | [osToken.getAssetsFromShares](#sdkostokengetassetsfromshares) | | | [vault.getStakeBalance](#sdkvaultgetstakebalance) | [osToken.getRate](#sdkostokengetrate) | | -| [vault.getScorePercentiles](#sdkvaultgetscorepercentiles) | | | +| [vault.getScorePercentiles](#sdkvaultgetscorepercentiles) | [osToken.getConfig](#sdkostokengetconfig) | | | [vault.getUserRewards](#sdkvaultgetuserrewards) | | | | [vault.getWhitelist](#sdkvaultgetwhitelist) | | | | [vault.getBlocklist](#sdkvaultgetblocklist) | | | @@ -1023,6 +1023,38 @@ type Output = string await sdk.utils.getRate() ``` --- +### `sdk.osToken.getConfig` + +#### Description: + +Deprecated, use `const { osTokenConfig } = await sdk.vault.getVault()` instead. +Returns basic information on the token + +#### Arguments: + +| Name | Type | Required | Description | +|--------------|----------|----------|---------------| +| vaultAddress | `string` | **Yes** | Vault address | + +#### Returns: + +```ts +type Output = { + ltvPercent: bigint + thresholdPercent: bigint +} +``` +| Name | Description | +|------|-------------| +| `ltvPercent` | The percent used to calculate how much user can mint OsToken shares | +| `thresholdPercent` | The liquidation threshold percent used to calculate health factor for OsToken position | + +#### Example: + +```ts +await sdk.osToken.getConfig({ vaultAddress: '0x...' }) +``` +--- ## RewardSplitter ### `sdk.rewardSplitter.create` diff --git a/changelog/next-release.md b/changelog/next-release.md index 046e91ca..4114f535 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -1,6 +1,3 @@ -- Breaking change: Removed `sdk.osToken.getConfig`. Use `sdk.vault.getVault` instead to get osToken config data `{ osTokenConfig: { ltvPercent, thresholdPercent } }`. -- Added canHarvest: boolean to `sdk.vault.getHarvestParams` response. - # Updates ### 1. `sdk.vault.getVault` @@ -76,3 +73,7 @@ type RemovedOutput = { shares: bigint } ``` +--- + +### 8. Deprecated method `sdk.osToken.getConfig` +### Use `sdk.vault.getVault` instead to get the result in `osTokenConfig` field. diff --git a/src/methods/osToken/index.ts b/src/methods/osToken/index.ts index 9b22d2e2..21dd3099 100644 --- a/src/methods/osToken/index.ts +++ b/src/methods/osToken/index.ts @@ -1,9 +1,9 @@ // Requests import getAPY from './requests/getOsTokenAPY' +import getConfig from './requests/getConfig' import getMaxMint from './requests/getMaxMint' import getRate from './requests/getOsTokenRate' import getPosition from './requests/getPosition' -import getConfig from './requests/getOsTokenConfig' import getBurnAmount from './helpers/getBurnAmount' import getHealthFactor from './helpers/getHealthFactor' import getSharesFromAssets from './requests/getSharesFromAssets' @@ -27,6 +27,7 @@ export default { */ getRate, /** + * @deprecated use sdk.vault.getVault instead to get data from osTokenConfig * @description os token ltvPercent and thresholdPercent for provided vault * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkostokengetconfig */ diff --git a/src/methods/osToken/requests/getConfig.ts b/src/methods/osToken/requests/getConfig.ts new file mode 100644 index 00000000..48a486cb --- /dev/null +++ b/src/methods/osToken/requests/getConfig.ts @@ -0,0 +1,20 @@ +import getVault from '../../vault/requests/getVault' + + +type GetConfigInput = { + options: StakeWise.Options + vaultAddress: string +} + +const getConfig = (input: GetConfigInput) => { + const { options, vaultAddress } = input + + return getVault({ + options, + vaultAddress, + }) + .then((vault) => vault.osTokenConfig) +} + + +export default getConfig diff --git a/src/methods/osToken/requests/getOsTokenConfig.ts b/src/methods/osToken/requests/getOsTokenConfig.ts deleted file mode 100644 index 74f27bbc..00000000 --- a/src/methods/osToken/requests/getOsTokenConfig.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { wrapAbortPromise } from '../../../modules/gql-module' -import { getVaultVersion } from '../../../utils' - - -export type GetOsTokenConfigInput = { - vaultAddress: string - contracts: StakeWise.Contracts -} - -type Output = { - ltvPercent: bigint - thresholdPercent: bigint -} - -const getOsTokenData = async (input: GetOsTokenConfigInput) => { - const { vaultAddress, contracts } = input - - const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) - - if (isV1Version) { - const [ thresholdPercent, ltvPercent ] = await Promise.all([ - contracts.base.mintTokenConfig.v1.liqThresholdPercent(), - contracts.base.mintTokenConfig.v1.ltvPercent(), - ]) - - return { - ltvPercent, - thresholdPercent, - } - } - else { - const [ _, thresholdPercent, ltvPercent ] = await contracts.base.mintTokenConfig.v2.getConfig(vaultAddress) - - return { - ltvPercent, - thresholdPercent, - } - } -} - - -export default wrapAbortPromise(getOsTokenData) diff --git a/src/methods/vault/requests/getVault/index.ts b/src/methods/vault/requests/getVault/index.ts index d8c3246c..46d5e3d3 100644 --- a/src/methods/vault/requests/getVault/index.ts +++ b/src/methods/vault/requests/getVault/index.ts @@ -10,7 +10,7 @@ type GetVaultInput = { vaultAddress: VaultQueryVariables['address'] } -const getVault = async (input: GetVaultInput) => { +const getVault = (input: GetVaultInput) => { const { options, vaultAddress } = input validateArgs.address({ vaultAddress }) From cbd4bf9c96cc397fb65b900f9f47ae31b3b021a8 Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Fri, 27 Sep 2024 16:59:50 +0300 Subject: [PATCH 22/36] Add new methods getUserStats & getVaultStats (#176) * Improve chart view logic in V3, add getUserStats, getVaultStats. * add deprecated to README * update docs * fixed import * improves, rename methods --- README.md | 119 ++++++++++++++-- changelog/next-release.md | 21 +++ src/graphql/subgraph/vault/index.ts | 6 + .../subgraph/vault/userStatsQuery.graphql | 29 ++++ .../subgraph/vault/vaultStatsQuery.graphql | 11 ++ src/methods/vault/index.ts | 15 ++ .../modifyExitRequests.ts | 2 +- .../vault/requests/getUserStats/index.ts | 32 +++++ .../getUserStats/modifyUserStats.spec.ts | 132 ++++++++++++++++++ .../requests/getUserStats/modifyUserStats.ts | 70 ++++++++++ .../vault/requests/getUserStats/types.ts | 17 +++ .../vault/requests/getVaultStats/index.ts | 30 ++++ .../getVaultStats/modifyVaultStats.spec.ts | 36 +++++ .../getVaultStats/modifyVaultStats.ts | 26 ++++ .../vault/requests/getVaultStats/types.ts | 6 + 15 files changed, 538 insertions(+), 14 deletions(-) create mode 100644 src/graphql/subgraph/vault/userStatsQuery.graphql create mode 100644 src/graphql/subgraph/vault/vaultStatsQuery.graphql create mode 100644 src/methods/vault/requests/getUserStats/index.ts create mode 100644 src/methods/vault/requests/getUserStats/modifyUserStats.spec.ts create mode 100644 src/methods/vault/requests/getUserStats/modifyUserStats.ts create mode 100644 src/methods/vault/requests/getUserStats/types.ts create mode 100644 src/methods/vault/requests/getVaultStats/index.ts create mode 100644 src/methods/vault/requests/getVaultStats/modifyVaultStats.spec.ts create mode 100644 src/methods/vault/requests/getVaultStats/modifyVaultStats.ts create mode 100644 src/methods/vault/requests/getVaultStats/types.ts diff --git a/README.md b/README.md index 05bb9e4e..1e978c19 100644 --- a/README.md +++ b/README.md @@ -89,21 +89,23 @@ const sdk = new StakeWiseSDK({ ## Quick Links ##### Request table: -| **Vault** | **osToken** | **RewardSplitter** | -|---------------------------------------------------------------|---------------------------------------------------------------|-------------------------------------------------------------------| -| [vault.getStakerActions](#sdkvaultgetstakeractions) | [osToken.getBurnAmount](#sdkostokengetburnamount) | [rewardSplitter.getClaimAmount](#sdkrewardsplittergetclaimamount) | -| [vault.getSnapshots](#sdkvaultgetsnapshots) | [osToken.getHealthFactor](#sdkostokengethealthfactor) | | -| [vault.getExitQueuePositions](#sdkvaultgetexitqueuepositions) | [osToken.getAPY](#sdkostokengetapy) | | -| [vault.getValidators](#sdkvaultgetvalidators) | [osToken.getPosition](#sdkostokengetposition) | | -| [vault.getVault](#sdkvaultgetvault) | [osToken.getMaxMint](#sdkostokengetmaxmint) | | +| **Vault** | **osToken** | **RewardSplitter** | +|---------------------------------------------------------------|--------------------------------------------------------------|-------------------------------------------------------------------| +| [vault.getStakerActions](#sdkvaultgetstakeractions) | [osToken.getBurnAmount](#sdkostokengetburnamount) | [rewardSplitter.getClaimAmount](#sdkrewardsplittergetclaimamount) | +| [vault.getSnapshots](#sdkvaultgetsnapshots) | [osToken.getHealthFactor](#sdkostokengethealthfactor) | | +| [vault.getExitQueuePositions](#sdkvaultgetexitqueuepositions) | [osToken.getAPY](#sdkostokengetapy) | | +| [vault.getValidators](#sdkvaultgetvalidators) | [osToken.getPosition](#sdkostokengetposition) | | +| [vault.getVault](#sdkvaultgetvault) | [osToken.getMaxMint](#sdkostokengetmaxmint) | | | [vault.getMaxWithdraw](#sdkvaultgetmaxwithdraw) | [osToken.getSharesFromAssets](#sdkostokengetsharesfromassets) | | | [vault.getHarvestParams](#sdkvaultgetharvestparams) | [osToken.getAssetsFromShares](#sdkostokengetassetsfromshares) | | -| [vault.getStakeBalance](#sdkvaultgetstakebalance) | [osToken.getRate](#sdkostokengetrate) | | -| [vault.getScorePercentiles](#sdkvaultgetscorepercentiles) | [osToken.getConfig](#sdkostokengetconfig) | | -| [vault.getUserRewards](#sdkvaultgetuserrewards) | | | -| [vault.getWhitelist](#sdkvaultgetwhitelist) | | | -| [vault.getBlocklist](#sdkvaultgetblocklist) | | | -| [vault.getRewardSplitters](#sdkvaultgetrewardsplitters) | | | +| [vault.getStakeBalance](#sdkvaultgetstakebalance) | [osToken.getRate](#sdkostokengetrate) | | +| [vault.getScorePercentiles](#sdkvaultgetscorepercentiles) | [osToken.getConfig](#sdkostokengetconfig) | | +| [vault.getUserRewards](#sdkvaultgetuserrewards) | | | +| [vault.getWhitelist](#sdkvaultgetwhitelist) | | | +| [vault.getBlocklist](#sdkvaultgetblocklist) | | | +| [vault.getRewardSplitters](#sdkvaultgetrewardsplitters) | | | +| [vault.getVaultStats](#sdkvaultgetvaultstats) | | | +| [vault.getUserStats](#sdkvaultgetuserstats) | | | | **Utils** | |-----------------------------------------------------| @@ -209,6 +211,8 @@ await sdk.vault.getStakerActions({ #### Description: +Deprecated, use `sdk.vault.getVaultStats` instead. + TVL and APY snapshots for the vault. With the help of this data it is possible to build a chart. #### Arguments: @@ -281,6 +285,8 @@ await sdk.vault.getScorePercentiles() #### Description: +Deprecated, use `sdk.vault.getUserStats` instead. + Daily rewards for the user who has made a deposit in the vault. With the help of this data it is possible to build a chart. #### Arguments: @@ -789,6 +795,93 @@ await sdk.vault.getStakeBalance({ }) ``` --- +### `sdk.vault.getVaultStats` + +#### Description: + +Getting the vault stats collection. With the help of this data it is possible to build a chart. + +#### Arguments: + +| Name | Type | Required | Description | +|--------|----------|----------|--------------------------| +| daysCount | `number` | **Yes** | The limit in days | +| vaultAddress | `string` | **Yes** | The address of the vault | + +#### Returns: + +```ts +type Output = { + apy: number + time: number + balance: number + rewards: number +} +``` + +| Name | Description | +|------|-----------------------------------------------------------------| +| `time` | Date and time for each data point | +| `apy` | Current APY based on time, rewards and balance. | +| `rewards` | Number of assets earned by the vault during the interval in ETH | +| `balance` | Total assets in the vault at the moment of time in ETH | + +#### Example: + +```ts +await sdk.vault.getVaultStats({ + daysCount: 30, + vaultAddress: '0x...', +}) +``` +--- +### `sdk.vault.getUsertStats` + +#### Description: + +Getting the user stats collection for current vault. +With the help of this data it is possible to build a chart. + +#### Arguments: + +| Name | Type | Required | Description | +|--------------|----------|----------|------------------------------| +| daysCount | `number` | **Yes** | The limit in days | +| userAddress | `string` | **Yes** | The user address | +| vaultAddress | `string` | **Yes** | The address of the vault | + +#### Returns: + +```ts +type Stat = { + time: number + value: number +} + +type Output = { + apy: Stat[] + balance: Stat[] + rewards: Stat[] +} +``` + +| Name | Description | +|------|---------------------------------------------------------------------------------------------------------| +| `time` | Date and time for each data point | +| `apy` | Current APY based on time, rewards and balance. The information is taken from allocatorStats_collection | +| `rewards` | Number of assets earned by the user in current vault during the interval in ETH | +| `balance` | Total assets by the user in current vault at the moment of time in ETH | + +#### Example: + +```ts +await sdk.vault.getUserStats({ + daysCount: 30, + userAddress: '0x...', + vaultAddress: '0x...', +}) +``` +--- ## API-osToken ### `sdk.osToken.getBurnAmount` diff --git a/changelog/next-release.md b/changelog/next-release.md index 4114f535..4b2baaa7 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -77,3 +77,24 @@ type RemovedOutput = { ### 8. Deprecated method `sdk.osToken.getConfig` ### Use `sdk.vault.getVault` instead to get the result in `osTokenConfig` field. + +--- + +### 9. Add methods +### `sdk.vault.getVaultStats` & `sdk.vault.getUserStats` +#### With the help of this data it is possible to build a chart. + +--- + +--- + +### 10. Deprecated method `sdk.vault.getSnapshots` +### Use `sdk.vault.getVaultStats` instead + +--- +--- + +### 11. Deprecated method `sdk.vault.getUserRewards` +### Use `sdk.vault.getUserStats` instead + +--- diff --git a/src/graphql/subgraph/vault/index.ts b/src/graphql/subgraph/vault/index.ts index 77ef49f7..b1d5c3f0 100644 --- a/src/graphql/subgraph/vault/index.ts +++ b/src/graphql/subgraph/vault/index.ts @@ -1,6 +1,12 @@ export { fetchVaultQuery } from './vaultQuery.graphql' export type { VaultQueryPayload, VaultQueryVariables } from './vaultQuery.graphql' +export { fetchUserStatsQuery } from './userStatsQuery.graphql' +export type { UserStatsQueryPayload, UserStatsQueryVariables } from './userStatsQuery.graphql' + +export { fetchVaultStatsQuery } from './vaultStatsQuery.graphql' +export type { VaultStatsQueryPayload, VaultStatsQueryVariables } from './vaultStatsQuery.graphql' + export { fetchHarvestParamsQuery } from './harvestParamsQuery.graphql' export type { HarvestParamsQueryPayload, HarvestParamsQueryVariables } from './harvestParamsQuery.graphql' diff --git a/src/graphql/subgraph/vault/userStatsQuery.graphql b/src/graphql/subgraph/vault/userStatsQuery.graphql new file mode 100644 index 00000000..f37c0459 --- /dev/null +++ b/src/graphql/subgraph/vault/userStatsQuery.graphql @@ -0,0 +1,29 @@ +query UserStats($user: Bytes! $vaultAddress: String! $daysCount: Int!) { + allocator: allocatorStats_collection( + interval: day + where: { allocator_: { address: $user, vault: $vaultAddress } } + first: $daysCount + ) { + timestamp + earnedAssets + totalAssets + } + exitRequest: exitRequestStats_collection( + interval: day + where: { exitRequest_: { receiver: $user, vault: $vaultAddress } } + first: $daysCount + ) { + timestamp + earnedAssets + totalAssets + } + rewardSplitter: rewardSplitterShareHolderStats_collection( + interval: day + where: { rewardSpliterShareHolder_: { address: $user, vault: $vaultAddress }} + first: $daysCount + ) { + timestamp + earnedAssets + totalAssets + } +} diff --git a/src/graphql/subgraph/vault/vaultStatsQuery.graphql b/src/graphql/subgraph/vault/vaultStatsQuery.graphql new file mode 100644 index 00000000..f6fdd6d9 --- /dev/null +++ b/src/graphql/subgraph/vault/vaultStatsQuery.graphql @@ -0,0 +1,11 @@ +query VaultStats($vaultAddress: String! $daysCount: Int!) { + vaultStats: vaultStats_collection( + interval: day + where: { vault: $vaultAddress } + first: $daysCount + ) { + timestamp + earnedAssets + totalAssets + } +} diff --git a/src/methods/vault/index.ts b/src/methods/vault/index.ts index e11444d4..f39667df 100644 --- a/src/methods/vault/index.ts +++ b/src/methods/vault/index.ts @@ -4,6 +4,8 @@ import getEigenPods from './requests/getEigenPods' import getSnapshots from './requests/getSnapshots' import getWhitelist from './requests/getWhitelist' import getBlocklist from './requests/getBlocklist' +import getUserStats from './requests/getUserStats' +import getVaultStats from './requests/getVaultStats' import getValidators from './requests/getValidators' import getUserRewards from './requests/getUserRewards' import getMaxWithdraw from './requests/getMaxWithdraw' @@ -66,6 +68,7 @@ export default { * @description Daily rewards for the user who has made a deposit in the vault. * With the help of this data it is possible to build a chart. * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetuserrewards + * @deprecated use https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetuserstats */ getUserRewards, /** @@ -87,6 +90,7 @@ export default { /** * @description TVL and APY snapshots for the vault. With the help of this data it is possible to build a chart. * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetsnapshots + * @deprecated use https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetvaultstats */ getSnapshots, /** @@ -108,6 +112,17 @@ export default { * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetvault */ getVault, + /** + * @description Returns the vault stats collection. With the help of this data it is possible to build a chart. + * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetvaultstats + */ + getVaultStats, + /** + * @description Returns the user stats collection for current vault. + * With the help of this data it is possible to build a chart. + * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetuserstats + */ + getUserStats, }, transactions: { /** diff --git a/src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts b/src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts index e4a70972..8530d6bf 100644 --- a/src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts +++ b/src/methods/vault/requests/getExitQueuePositions/modifyExitRequests.ts @@ -1,4 +1,4 @@ -import { ExitQueueQueryPayload } from 'graphql/subgraph/exitQueue' +import { ExitQueueQueryPayload } from '../../../../graphql/subgraph/exitQueue' type ExitRequest = Omit & { diff --git a/src/methods/vault/requests/getUserStats/index.ts b/src/methods/vault/requests/getUserStats/index.ts new file mode 100644 index 00000000..bd4337c6 --- /dev/null +++ b/src/methods/vault/requests/getUserStats/index.ts @@ -0,0 +1,32 @@ +import type { UserStatsQueryVariables } from '../../../../graphql/subgraph/vault' +import modifyUserStats from './modifyUserStats' +import { apiUrls, validateArgs } from '../../../../utils' +import graphql from '../../../../graphql' + + +type GetUserStatsInput = { + daysCount: number + options: StakeWise.Options + userAddress: UserStatsQueryVariables['user'] + vaultAddress: UserStatsQueryVariables['vaultAddress'] +} + +const getUserStats = (input: GetUserStatsInput) => { + const { options, userAddress, vaultAddress, daysCount } = input + + validateArgs.address({ vaultAddress, userAddress }) + validateArgs.number({ daysCount }) + + return graphql.subgraph.vault.fetchUserStatsQuery({ + url: apiUrls.getSubgraphqlUrl(options), + variables: { + daysCount, + user: userAddress.toLowerCase(), + vaultAddress: vaultAddress.toLowerCase(), + } as UserStatsQueryVariables, + modifyResult: modifyUserStats, + }) +} + + +export default getUserStats diff --git a/src/methods/vault/requests/getUserStats/modifyUserStats.spec.ts b/src/methods/vault/requests/getUserStats/modifyUserStats.spec.ts new file mode 100644 index 00000000..ffd349fd --- /dev/null +++ b/src/methods/vault/requests/getUserStats/modifyUserStats.spec.ts @@ -0,0 +1,132 @@ +import { formatEther } from 'ethers' + +import type { ModifiedUserStats } from './types' +import modifyUserStats from './modifyUserStats' +import type { UserStatsQueryPayload } from '../../../../graphql/subgraph/vault' + + +describe('modifyUserStats function', () => { + it('should correctly modify User Stats collection', () => { + const sampleInput: UserStatsQueryPayload = { + allocator: [ + { + timestamp: '1727136000000000', + earnedAssets: '27734011365427', + totalAssets: '715748104014280751', + }, + { + timestamp: '1727049600000000', + earnedAssets: '31538735933515', + totalAssets: '715720370002915324', + }, + { + timestamp: '1726963200000000', + earnedAssets: '28263735668759', + totalAssets: '715688831266981809', + }, + ], + exitRequest: [ + { + timestamp: '1727136000000000', + earnedAssets: '27734011365427', + totalAssets: '715748104014280751', + }, + { + timestamp: '1726876800000000', + earnedAssets: '36906487302928', + totalAssets: '715660567531313050', + }, + ], + rewardSplitter: [ + { + timestamp: '1727049600000000', + earnedAssets: '31538735933515', + totalAssets: '715720370002915324', + }, + { + timestamp: '1726790400000000', + earnedAssets: '31763194717568', + totalAssets: '715623661044010122', + }, + ], + } + + const expectedResult: ModifiedUserStats = { + balance: [ + { + time: 1727136000, + value: Number(formatEther('1431496208028561600')), + }, + { + time: 1727049600, + value: Number(formatEther('1431440740005830700')), + }, + { + time: 1726963200, + value: Number(formatEther('715688831266981809')), + }, + { + time: 1726876800, + value: Number(formatEther('715660567531313050')), + }, + { + time: 1726790400, + value: Number(formatEther('715623661044010122')), + }, + ], + rewards: [ + { + time: 1727136000, + value: Number(formatEther('55468022730854')), + }, + { + time: 1727049600, + value: Number(formatEther('63077471867030')), + }, + { + time: 1726963200, + value: Number(formatEther('28263735668759')), + }, + { + time: 1726876800, + value: Number(formatEther('36906487302928')), + }, + { + time: 1726790400, + value: Number(formatEther('31763194717568')), + }, + ], + apy: [ + { + time: 1727136000, + value: ( + Number(formatEther('27734011365427')) * 365 * 100) + / (Number(formatEther('715748104014280751')) - Number(formatEther('27734011365427')) + ), + }, + { + time: 1727049600, + value: ( + Number(formatEther('31538735933515')) * 365 * 100) + / (Number(formatEther('715720370002915324')) - Number(formatEther('31538735933515')) + ), + }, + { + time: 1726963200, + value: ( + Number(formatEther('28263735668759')) * 365 * 100) + / (Number(formatEther('715688831266981809')) - Number(formatEther('28263735668759')) + ), + }, + ], + } + + const result = modifyUserStats(sampleInput) + + expect(result).toEqual({ + apy: expectedResult.apy.sort((a, b) => a.time - b.time), + balance: expectedResult.balance.sort((a, b) => a.time - b.time), + rewards: expectedResult.rewards.sort((a, b) => a.time - b.time), + }) + }) +}) diff --git a/src/methods/vault/requests/getUserStats/modifyUserStats.ts b/src/methods/vault/requests/getUserStats/modifyUserStats.ts new file mode 100644 index 00000000..50e757f1 --- /dev/null +++ b/src/methods/vault/requests/getUserStats/modifyUserStats.ts @@ -0,0 +1,70 @@ +import { formatEther } from 'ethers' + +import type { ModifiedUserStats, UserStatsMap } from './types' +import type { UserStatsQueryPayload } from '../../../../graphql/subgraph/vault' + + +const updateUserStatsMap = ( + userStatsMap: UserStatsMap, + stat: { totalAssets: string, earnedAssets: string, timestamp: string }, + includeApy = false +) => { + const timeInSeconds = Number(stat.timestamp) / 1000000 + const balance = Number(formatEther(stat.totalAssets || '0')) + const rewards = Number(formatEther(stat.earnedAssets || '0')) + const totalApy = includeApy ? (rewards * 365 * 100) / (balance - rewards) : 0 + + if (!userStatsMap.balance[stat.timestamp]) { + userStatsMap.balance[stat.timestamp] = { value: 0, time: timeInSeconds } + } + + if (!userStatsMap.rewards[stat.timestamp]) { + userStatsMap.rewards[stat.timestamp] = { value: 0, time: timeInSeconds } + } + + if (includeApy && !userStatsMap.apy[stat.timestamp]) { + userStatsMap.apy[stat.timestamp] = { value: 0, time: timeInSeconds } + } + + userStatsMap.balance[stat.timestamp].value += balance + userStatsMap.rewards[stat.timestamp].value += rewards + + if (includeApy) { + userStatsMap.apy[stat.timestamp].value += totalApy + } +} + +const modifyUserStats = (data: UserStatsQueryPayload): ModifiedUserStats => { + const allocatorStats = data?.allocator || [] + const exitRequestStats = data?.exitRequest || [] + const rewardSplitterStats = data?.rewardSplitter || [] + + const userStatsMap: UserStatsMap = { + apy: {}, + balance: {}, + rewards: {}, + } + + allocatorStats.forEach((stat) => { + updateUserStatsMap(userStatsMap, stat, true) + }) + + exitRequestStats.forEach((stat) => { + updateUserStatsMap(userStatsMap, stat) + }) + + rewardSplitterStats.forEach((stat) => { + updateUserStatsMap(userStatsMap, stat) + }) + + const result = { + apy: Object.values(userStatsMap.apy).sort((a, b) => a.time - b.time), + balance: Object.values(userStatsMap.balance).sort((a, b) => a.time - b.time), + rewards: Object.values(userStatsMap.rewards).sort((a, b) => a.time - b.time), + } + + return result +} + + +export default modifyUserStats diff --git a/src/methods/vault/requests/getUserStats/types.ts b/src/methods/vault/requests/getUserStats/types.ts new file mode 100644 index 00000000..37e80456 --- /dev/null +++ b/src/methods/vault/requests/getUserStats/types.ts @@ -0,0 +1,17 @@ +type ChartStat = { + value: number + time: number +} + +export type UserStatsMap = { + apy: Record + balance: Record + rewards: Record +} + +export type ModifiedUserStats = { + apy: ChartStat[] + balance: ChartStat[] + rewards: ChartStat[] +} + diff --git a/src/methods/vault/requests/getVaultStats/index.ts b/src/methods/vault/requests/getVaultStats/index.ts new file mode 100644 index 00000000..08ca567a --- /dev/null +++ b/src/methods/vault/requests/getVaultStats/index.ts @@ -0,0 +1,30 @@ +import type { VaultStatsQueryVariables } from '../../../../graphql/subgraph/vault' +import modifyVaultStats from './modifyVaultStats' +import { apiUrls, validateArgs } from '../../../../utils' +import graphql from '../../../../graphql' + + +type GetVaultStatsInput = { + options: StakeWise.Options + vaultAddress: VaultStatsQueryVariables['vaultAddress'] + daysCount: number +} + +const getVaultStats = (input: GetVaultStatsInput) => { + const { options, vaultAddress, daysCount } = input + + validateArgs.address({ vaultAddress }) + validateArgs.number({ daysCount }) + + return graphql.subgraph.vault.fetchVaultStatsQuery({ + url: apiUrls.getSubgraphqlUrl(options), + variables: { + daysCount, + vaultAddress: vaultAddress.toLowerCase(), + } as VaultStatsQueryVariables, + modifyResult: modifyVaultStats, + }) +} + + +export default getVaultStats diff --git a/src/methods/vault/requests/getVaultStats/modifyVaultStats.spec.ts b/src/methods/vault/requests/getVaultStats/modifyVaultStats.spec.ts new file mode 100644 index 00000000..e4c872fc --- /dev/null +++ b/src/methods/vault/requests/getVaultStats/modifyVaultStats.spec.ts @@ -0,0 +1,36 @@ +import { formatEther } from 'ethers' + +import type { ModifiedVaultStats } from './types' +import modifyVaultStats from './modifyVaultStats' +import type { VaultStatsQueryPayload } from '../../../../graphql/subgraph/vault' + + +describe('modifyVaultStats function', () => { + it('should correctly modify Vault Stats collection', () => { + const sampleInput: VaultStatsQueryPayload = { + vaultStats: [ + { + timestamp: '1727049600000000', + earnedAssets: '337535438824070468', + totalAssets: '6894313501899116340545', + }, + ], + } + + const rewards = Number(formatEther('337535438824070468')) + const balance = Number(formatEther('6894313501899116340545')) + + const expectedResult: ModifiedVaultStats[] = [ + { + rewards, + balance, + time: 1727049600, + apy: (rewards * 365 * 100) / (balance - rewards), + }, + ] + + const result = modifyVaultStats(sampleInput) + + expect(result).toEqual(expectedResult) + }) +}) diff --git a/src/methods/vault/requests/getVaultStats/modifyVaultStats.ts b/src/methods/vault/requests/getVaultStats/modifyVaultStats.ts new file mode 100644 index 00000000..11e747e4 --- /dev/null +++ b/src/methods/vault/requests/getVaultStats/modifyVaultStats.ts @@ -0,0 +1,26 @@ +import { formatEther } from 'ethers' + +import { ModifiedVaultStats } from './types' +import type { VaultStatsQueryPayload } from '../../../../graphql/subgraph/vault' + + +const modifyVaultStats = (data: VaultStatsQueryPayload): ModifiedVaultStats[] => { + const vaultStats = data?.vaultStats || [] + + return vaultStats.map((stat) => { + const timeInSeconds = Number(stat.timestamp) / 1000000 + const balance = Number(formatEther(stat.totalAssets || '0')) + const rewards = Number(formatEther(stat.earnedAssets || '0')) + const totalApy = (rewards * 365 * 100) / (balance - rewards) + + return { + balance, + rewards, + apy: totalApy, + time: timeInSeconds, + } + }) +} + + +export default modifyVaultStats diff --git a/src/methods/vault/requests/getVaultStats/types.ts b/src/methods/vault/requests/getVaultStats/types.ts new file mode 100644 index 00000000..ecf108eb --- /dev/null +++ b/src/methods/vault/requests/getVaultStats/types.ts @@ -0,0 +1,6 @@ +export type ModifiedVaultStats = { + apy: number + time: number + balance: number + rewards: number +} From e6031cd7587620e13e7254bfadf6aea0862e2659 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Fri, 27 Sep 2024 19:06:40 +0500 Subject: [PATCH 23/36] new addresses --- src/utils/configs/chiado.ts | 2 +- src/utils/configs/gnosis.ts | 2 +- src/utils/configs/holesky.ts | 2 +- src/utils/configs/mainnet.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/configs/chiado.ts b/src/utils/configs/chiado.ts index 0df01e95..a2dbe1cd 100644 --- a/src/utils/configs/chiado.ts +++ b/src/utils/configs/chiado.ts @@ -45,7 +45,7 @@ export default { erc20BlocklistVault: '0x35482A11E21157E0C706d1A562483902421dB341', }, special: { - stakeCalculator: ZeroAddress, + stakeCalculator: '0xac148e19241c6e087dd6ed777d5f1d85f4ffc46a', }, }, tokens: { diff --git a/src/utils/configs/gnosis.ts b/src/utils/configs/gnosis.ts index d8abc0ce..b6f21ad2 100644 --- a/src/utils/configs/gnosis.ts +++ b/src/utils/configs/gnosis.ts @@ -45,7 +45,7 @@ export default { erc20BlocklistVault: '0x99E4300326867FE3f97864a74e500d19654c19e9', }, special: { - stakeCalculator: '0x9747e1fF73f1759217AFD212Dd36d21360D0880A', + stakeCalculator: '0x90b82e4b3aa385b4a02b7ebc1892a4bed6b5c465', }, }, tokens: { diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 8f6c9f40..9176716d 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -45,7 +45,7 @@ export default { erc20BlocklistVault: '0x82FE8C78CaE0013471179e76224ef89941bAaa75', }, special: { - stakeCalculator: '0x63De511Ff504E70109Bb8312d1329f2C88c14f77', + stakeCalculator: '0x7455d03c7137b6597ebaccb57c13ca62b39a75a4', }, }, tokens: { diff --git a/src/utils/configs/mainnet.ts b/src/utils/configs/mainnet.ts index aa99772e..fb77ddd9 100644 --- a/src/utils/configs/mainnet.ts +++ b/src/utils/configs/mainnet.ts @@ -48,7 +48,7 @@ export default { erc20BlocklistVault: '0x1bE3Ad178d85CE1b6a7fCF5baEFe68F26541b07C', }, special: { - stakeCalculator: ZeroAddress, + stakeCalculator: '0x29c708d94521af2c88402858049bd33e4606a3a2', }, }, tokens: { From 22fb447ab4bfc5efcc61d9d68e41aec387599fd8 Mon Sep 17 00:00:00 2001 From: CAst Date: Mon, 30 Sep 2024 17:35:03 +0500 Subject: [PATCH 24/36] [new-stake-calculator] set new addresses (#178) --- src/contracts/abis/StakeCalculatorAbi.json | 90 +++++++++++++++++++++- src/utils/configs/chiado.ts | 2 +- src/utils/configs/gnosis.ts | 2 +- src/utils/configs/holesky.ts | 2 +- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/contracts/abis/StakeCalculatorAbi.json b/src/contracts/abis/StakeCalculatorAbi.json index 70eeba9e..38d189a4 100644 --- a/src/contracts/abis/StakeCalculatorAbi.json +++ b/src/contracts/abis/StakeCalculatorAbi.json @@ -16,6 +16,11 @@ "name": "osTokenConfigV2", "type": "address" }, + { + "internalType": "address", + "name": "osToken", + "type": "address" + }, { "internalType": "address", "name": "osTokenController", @@ -77,7 +82,7 @@ "type": "tuple" } ], - "internalType": "struct Helpers.StakeInput", + "internalType": "struct StakeHelpers.StakeInput", "name": "inputData", "type": "tuple" } @@ -97,7 +102,7 @@ "type": "uint256" } ], - "internalType": "struct Helpers.StakeOutput", + "internalType": "struct StakeHelpers.StakeOutput", "name": "outputData", "type": "tuple" } @@ -152,7 +157,7 @@ "type": "tuple" } ], - "internalType": "struct Helpers.UnstakeInput", + "internalType": "struct StakeHelpers.UnstakeInput", "name": "inputData", "type": "tuple" } @@ -177,12 +182,89 @@ "type": "uint256" } ], - "internalType": "struct Helpers.UnstakeOutput", + "internalType": "struct StakeHelpers.UnstakeOutput", "name": "outputData", "type": "tuple" } ], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "rewardsRoot", + "type": "bytes32" + }, + { + "internalType": "int160", + "name": "reward", + "type": "int160" + }, + { + "internalType": "uint160", + "name": "unlockedMevReward", + "type": "uint160" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + } + ], + "internalType": "struct IKeeperRewards.HarvestParams", + "name": "harvestParams", + "type": "tuple" + } + ], + "internalType": "struct StakeHelpers.BalanceInput", + "name": "inputData", + "type": "tuple" + } + ], + "name": "getBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "receivedAssets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" } ] diff --git a/src/utils/configs/chiado.ts b/src/utils/configs/chiado.ts index a2dbe1cd..313f7e68 100644 --- a/src/utils/configs/chiado.ts +++ b/src/utils/configs/chiado.ts @@ -45,7 +45,7 @@ export default { erc20BlocklistVault: '0x35482A11E21157E0C706d1A562483902421dB341', }, special: { - stakeCalculator: '0xac148e19241c6e087dd6ed777d5f1d85f4ffc46a', + stakeCalculator: '0x29c708d94521af2c88402858049bd33e4606a3a2', }, }, tokens: { diff --git a/src/utils/configs/gnosis.ts b/src/utils/configs/gnosis.ts index b6f21ad2..07092678 100644 --- a/src/utils/configs/gnosis.ts +++ b/src/utils/configs/gnosis.ts @@ -45,7 +45,7 @@ export default { erc20BlocklistVault: '0x99E4300326867FE3f97864a74e500d19654c19e9', }, special: { - stakeCalculator: '0x90b82e4b3aa385b4a02b7ebc1892a4bed6b5c465', + stakeCalculator: '0xfc8e3e7c919b4392d9f5b27015688e49c80015f0', }, }, tokens: { diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 9176716d..22516647 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -45,7 +45,7 @@ export default { erc20BlocklistVault: '0x82FE8C78CaE0013471179e76224ef89941bAaa75', }, special: { - stakeCalculator: '0x7455d03c7137b6597ebaccb57c13ca62b39a75a4', + stakeCalculator: '0x90b82e4b3aa385b4a02b7ebc1892a4bed6b5c465', }, }, tokens: { From 319b9643d265b1601fbdea0d9aa6107d8090709d Mon Sep 17 00:00:00 2001 From: CAst Date: Wed, 2 Oct 2024 19:36:14 +0500 Subject: [PATCH 25/36] [add-genesis-to-vault] (#180) --- README.md | 61 ++++++++++--------- src/StakeWiseSDK.ts | 3 +- src/contracts/vault/createVaultContract.ts | 3 +- src/graphql/subgraph/vault/vaultQuery.graphql | 1 + 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 1e978c19..450d73e6 100644 --- a/README.md +++ b/README.md @@ -666,36 +666,37 @@ type Output = { | Name | Description | |-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `apy` | Current vault apy | -| `isErc20` | Does the vault have its own ERC20 token | -| `capacity` | Maximum TVL of Vault | -| `createdAt` | Date of Creation | -| `feePercent` | Commission rate | -| `isPrivate` | Whether the storage is private | -| `isRestake` | Indicates whether the Vault is a restaking vault | -| `isBlocklist` | Whether the storage has blocklist | -| `vaultAdmin` | Vault administrator address | -| `totalAssets` | TVL of Vault | -| `feeRecipient` | Vault fee address | -| `whitelistManager` | Whitelist manager | -| `vaultAddress` | Address of vault | -| `mevRecipient` | Validator fee recipient | -| `whitelistCount` | Number of addresses in the [whitelist](#sdkvaultgetwhitelist) | -| `blocklistCount` | Number of addresses in the [blocklist](#sdkvaultgetblocklist) | -| `imageUrl` | Link for vault logo | -| `blocklistManager` | Blocklist manager | -| `depositDataManager` | Keys manager address | -| `isSmoothingPool` | Smoothing poll or Vault escrow | -| `tokenName` | ERC20 token name | -| `tokenSymbol` | ERC20 token symbol | -| `displayName` | Name of vault | -| `description` | Description of vault | -| `whitelist` | List of authorized users for deposits | -| `blocklist` | List of blocked users for deposits | -| `performance` | Vault performance indicator (percent) | -| `version` | Vault version | -| `restakeOperatorsManager` | If the Vault is a restaking vault, restake operators manager can add/remove restake operators | -| `restakeWithdrawalsManager` | If the Vault is a restaking vault, restake withdrawals manager can manage EigenLayer withdrawals | +| `apy` | Current vault apy | +| `isErc20` | Does the vault have its own ERC20 token | +| `capacity` | Maximum TVL of Vault | +| `createdAt` | Date of Creation | +| `feePercent` | Commission rate | +| `isPrivate` | Whether the vault is private | +| `isGenesis` | Is a stakewise vault | +| `isRestake` | Indicates whether the Vault is a restaking vault | +| `isBlocklist` | Whether the vault has blocklist | +| `vaultAdmin` | Vault administrator address | +| `totalAssets` | TVL of Vault | +| `feeRecipient` | Vault fee address | +| `whitelistManager` | Whitelist manager | +| `vaultAddress` | Address of vault | +| `mevRecipient` | Validator fee recipient | +| `whitelistCount` | Number of addresses in the [whitelist](#sdkvaultgetwhitelist) | +| `blocklistCount` | Number of addresses in the [blocklist](#sdkvaultgetblocklist) | +| `imageUrl` | Link for vault logo | +| `blocklistManager` | Blocklist manager | +| `depositDataManager` | Keys manager address | +| `isSmoothingPool` | Smoothing poll or Vault escrow | +| `tokenName` | ERC20 token name | +| `tokenSymbol` | ERC20 token symbol | +| `displayName` | Name of vault | +| `description` | Description of vault | +| `whitelist` | List of authorized users for deposits | +| `blocklist` | List of blocked users for deposits | +| `performance` | Vault performance indicator (percent) | +| `version` | Vault version | +| `restakeOperatorsManager` | If the Vault is a restaking vault, restake operators manager can add/remove restake operators | +| `restakeWithdrawalsManager` | If the Vault is a restaking vault, restake withdrawals manager can manage EigenLayer withdrawals | | `osTokenConfig` | contains the ltvPercent, which is the percentage used to calculate how much a user can mint in OsToken shares, and thresholdPercent, which is the liquidation threshold percentage used to calculate the health factor for the OsToken position | #### Example: diff --git a/src/StakeWiseSDK.ts b/src/StakeWiseSDK.ts index 6ef7916e..f7697e08 100644 --- a/src/StakeWiseSDK.ts +++ b/src/StakeWiseSDK.ts @@ -55,13 +55,14 @@ class StakeWiseSDK { async vaultMulticall(values: VaultMulticallInput) { const { userAddress, vaultAddress, request } = values - const { isBlocklist, isPrivate, isRestake } = await this.vault.getVault({ vaultAddress }) + const { isBlocklist, isPrivate, isRestake, isGenesis } = await this.vault.getVault({ vaultAddress }) const vaultContract = this.contracts.helpers.createVault({ options: { chainId: this.config.network.chainId, isBlocklist, isPrivate, + isGenesis, isRestake, }, vaultAddress, diff --git a/src/contracts/vault/createVaultContract.ts b/src/contracts/vault/createVaultContract.ts index cfa85771..42ec23fc 100644 --- a/src/contracts/vault/createVaultContract.ts +++ b/src/contracts/vault/createVaultContract.ts @@ -26,9 +26,8 @@ import createContract from '../createContract' import { ModifiedVault } from '../../methods/vault/requests/getVault/types' -type Options = Partial> & { +type Options = Partial> & { chainId?: Network - isGenesis?: boolean } type CreateContractsInput = { diff --git a/src/graphql/subgraph/vault/vaultQuery.graphql b/src/graphql/subgraph/vault/vaultQuery.graphql index 8a0216ec..180bce90 100644 --- a/src/graphql/subgraph/vault/vaultQuery.graphql +++ b/src/graphql/subgraph/vault/vaultQuery.graphql @@ -18,6 +18,7 @@ query Vault($address: ID!) { createdAt mevEscrow tokenName + isGenesis feePercent totalAssets isBlocklist From 5d48fc97dee0a1f20a826dc5e721f17b81ae28cf Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Thu, 3 Oct 2024 11:54:43 +0300 Subject: [PATCH 26/36] Add new methods getFiatRates & getUserExchangeRewards (#179) * add new methods getFiatRates & getUserExchangeRewards * remove unused * update text in docs * remove usdToDaiRate * remove unused methods, update docs * update docs * improve date in milliseconds --- README.md | 156 ++++++++---------- changelog/next-release.md | 31 +++- src/graphql/backend/vault/index.ts | 3 - .../backend/vault/userRewardsQuery.graphql | 10 -- .../subgraph/stats/fiatRatesQuery.graphql | 7 + src/graphql/subgraph/stats/index.ts | 3 + src/graphql/subgraph/vault/index.ts | 3 + .../subgraph/vault/userRewardsQuery.graphql | 18 ++ src/methods/utils/getFiatRates.ts | 42 +++++ src/methods/utils/index.ts | 1 + src/methods/vault/index.ts | 9 - .../vault/requests/getSnapshots/index.ts | 31 ---- .../getSnapshots/modifySnapshots.spec.ts | 61 ------- .../requests/getSnapshots/modifySnapshots.ts | 35 ---- .../vault/requests/getSnapshots/types.ts | 9 - .../vault/requests/getUserRewards/index.ts | 50 ++++-- .../getUserRewards/modifyUserRewards.spec.ts | 86 +++++----- .../getUserRewards/modifyUserRewards.ts | 51 ++++-- .../vault/requests/getUserRewards/types.ts | 7 +- 19 files changed, 275 insertions(+), 338 deletions(-) delete mode 100644 src/graphql/backend/vault/userRewardsQuery.graphql create mode 100644 src/graphql/subgraph/stats/fiatRatesQuery.graphql create mode 100644 src/graphql/subgraph/vault/userRewardsQuery.graphql create mode 100644 src/methods/utils/getFiatRates.ts delete mode 100644 src/methods/vault/requests/getSnapshots/index.ts delete mode 100644 src/methods/vault/requests/getSnapshots/modifySnapshots.spec.ts delete mode 100644 src/methods/vault/requests/getSnapshots/modifySnapshots.ts delete mode 100644 src/methods/vault/requests/getSnapshots/types.ts diff --git a/README.md b/README.md index 450d73e6..ae4040cf 100644 --- a/README.md +++ b/README.md @@ -89,28 +89,28 @@ const sdk = new StakeWiseSDK({ ## Quick Links ##### Request table: -| **Vault** | **osToken** | **RewardSplitter** | -|---------------------------------------------------------------|--------------------------------------------------------------|-------------------------------------------------------------------| -| [vault.getStakerActions](#sdkvaultgetstakeractions) | [osToken.getBurnAmount](#sdkostokengetburnamount) | [rewardSplitter.getClaimAmount](#sdkrewardsplittergetclaimamount) | -| [vault.getSnapshots](#sdkvaultgetsnapshots) | [osToken.getHealthFactor](#sdkostokengethealthfactor) | | -| [vault.getExitQueuePositions](#sdkvaultgetexitqueuepositions) | [osToken.getAPY](#sdkostokengetapy) | | -| [vault.getValidators](#sdkvaultgetvalidators) | [osToken.getPosition](#sdkostokengetposition) | | -| [vault.getVault](#sdkvaultgetvault) | [osToken.getMaxMint](#sdkostokengetmaxmint) | | -| [vault.getMaxWithdraw](#sdkvaultgetmaxwithdraw) | [osToken.getSharesFromAssets](#sdkostokengetsharesfromassets) | | -| [vault.getHarvestParams](#sdkvaultgetharvestparams) | [osToken.getAssetsFromShares](#sdkostokengetassetsfromshares) | | -| [vault.getStakeBalance](#sdkvaultgetstakebalance) | [osToken.getRate](#sdkostokengetrate) | | -| [vault.getScorePercentiles](#sdkvaultgetscorepercentiles) | [osToken.getConfig](#sdkostokengetconfig) | | -| [vault.getUserRewards](#sdkvaultgetuserrewards) | | | -| [vault.getWhitelist](#sdkvaultgetwhitelist) | | | -| [vault.getBlocklist](#sdkvaultgetblocklist) | | | -| [vault.getRewardSplitters](#sdkvaultgetrewardsplitters) | | | -| [vault.getVaultStats](#sdkvaultgetvaultstats) | | | -| [vault.getUserStats](#sdkvaultgetuserstats) | | | +| **Vault** | **osToken** | **RewardSplitter** | +|-----------------------------------------------------------------|--------------------------------------------------------------|-------------------------------------------------------------------| +| [vault.getStakerActions](#sdkvaultgetstakeractions) | [osToken.getBurnAmount](#sdkostokengetburnamount) | [rewardSplitter.getClaimAmount](#sdkrewardsplittergetclaimamount) | +| [vault.getExitQueuePositions](#sdkvaultgetexitqueuepositions) | [osToken.getAPY](#sdkostokengetapy) | | +| [vault.getValidators](#sdkvaultgetvalidators) | [osToken.getPosition](#sdkostokengetposition) | | +| [vault.getVault](#sdkvaultgetvault) | [osToken.getMaxMint](#sdkostokengetmaxmint) | | +| [vault.getMaxWithdraw](#sdkvaultgetmaxwithdraw) | [osToken.getSharesFromAssets](#sdkostokengetsharesfromassets) | | +| [vault.getHarvestParams](#sdkvaultgetharvestparams) | [osToken.getAssetsFromShares](#sdkostokengetassetsfromshares) | | +| [vault.getStakeBalance](#sdkvaultgetstakebalance) | [osToken.getRate](#sdkostokengetrate) | | +| [vault.getScorePercentiles](#sdkvaultgetscorepercentiles) | [osToken.getConfig](#sdkostokengetconfig) | | +| [vault.getUserRewards](#sdkvaultgetuserrewards) | [osToken.getHealthFactor](#sdkostokengethealthfactor) | | +| [vault.getWhitelist](#sdkvaultgetwhitelist) | | | +| [vault.getBlocklist](#sdkvaultgetblocklist) | | | +| [vault.getRewardSplitters](#sdkvaultgetrewardsplitters) | | | +| [vault.getVaultStats](#sdkvaultgetvaultstats) | | | +| [vault.getUserStats](#sdkvaultgetuserstats) | | | | **Utils** | |-----------------------------------------------------| | [utils.getSwiseUsdPrice](#sdkutilsgetswiseusdprice) | | [utils.getTransactions](#sdkutilsgettransactions) | +| [utils.getFiatRates](#sdkutilsgetfiatrates) | All of these methods (except synchronous getHealthFactor) return a promise that can be @@ -207,49 +207,6 @@ await sdk.vault.getStakerActions({ }) ``` --- -### `sdk.vault.getSnapshots` - -#### Description: - -Deprecated, use `sdk.vault.getVaultStats` instead. - -TVL and APY snapshots for the vault. With the help of this data it is possible to build a chart. - -#### Arguments: - -| Name | Type | Type | Description | -|--------------|----------|-----------------|---------| -| vaultAddress | `string` | **Yes** | - | -| dateFrom | `number` | **Yes** | Time to start | - -#### Returns: - -```ts -type Snapshot = { - APY: number - TVL: string -} - -type Output = { - days: Record - first: Snapshot -} -``` - -| Name | Description | -|------|-------------| -| `days` | The result of the query on your parameters, is returned as an object where the keys are timestamps | -| `first` | We always send the very first saved snapshot regardless of the request parameters, this helps for rendering the chart | - -#### Example: - -```ts -await sdk.vault.getSnapshots({ - vaultAddress: '0x...', - dateFrom: 1695730032793, -}) -``` ---- ### `sdk.vault.getScorePercentiles` #### Description: @@ -285,40 +242,37 @@ await sdk.vault.getScorePercentiles() #### Description: -Deprecated, use `sdk.vault.getUserStats` instead. -Daily rewards for the user who has made a deposit in the vault. With the help of this data it is possible to build a chart. +Daily rewards for the user who has made a deposit in the vault. #### Arguments: -| Name | Type | Type | Description | -|------|----------|-------------|---| -| vaultAddress | `string` | **Yes** | - | -| userAddress | `string` | **Yes** | - | -| dateFrom | `number` | **Yes** | Time to start | -| dateTo | `number` | **No** | Time to end | -| fillGaps | `boolean` | **No** | Fill in the empty days with zeros | +| Name | Type | Required | Description | +|------|----------|----------|---| +| dateFrom | `number` | **Yes** | Time to start in milliseconds | +| dateTo | `number` | **Yes** | Time to end in milliseconds | +| userAddress | `string` | **Yes** | The user address | +| vaultAddress | `string` | **Yes** | The address of the vault | #### Returns: ```ts -type UserReward = { - date: number - sumRewards: string - dailyRewards: string - dailyRewardsEur: string - dailyRewardsGbp: string - dailyRewardsUsd: string -} - type Output = { - days: Record + date: number + dailyRewards: number + dailyRewardsEur: number + dailyRewardsGbp: number + dailyRewardsUsd: number } ``` -| Name | Description | -|------|-------------| -| `days` | The result of the query on your parameters, is returned as an object where the keys are timestamps | +| Name | Description | +|------|---------------------------| +| `date` | Сurrent rate date | +| `dailyRewards` | Daily reward asset in ETH | +| `dailyRewardsEur` | Daily reward asset in EUR | +| `dailyRewardsGbp` | Daily reward asset in GBP | +| `dailyRewardsUsd` | Daily reward asset in USD | #### Example: @@ -326,7 +280,8 @@ type Output = { await sdk.vault.getUserRewards({ userAddress: '0x...', vaultAddress: '0x...', - dateFrom: 1695730032793, + dateTo: 1727827200000, + dateFrom: 1721606400000, }) ``` --- @@ -866,12 +821,12 @@ type Output = { } ``` -| Name | Description | -|------|---------------------------------------------------------------------------------------------------------| -| `time` | Date and time for each data point | -| `apy` | Current APY based on time, rewards and balance. The information is taken from allocatorStats_collection | -| `rewards` | Number of assets earned by the user in current vault during the interval in ETH | -| `balance` | Total assets by the user in current vault at the moment of time in ETH | +| Name | Description | +|------|--------------------------------------------------------------------------------------------------------| +| `time` | Date and time for each data point | +| `apy` | Current APY based on time, rewards and balance. | +| `rewards` | Number of assets earned by the user in current vault during the interval in ETH | +| `balance` | Total assets by the user in current vault at the moment of time in ETH | #### Example: @@ -883,6 +838,7 @@ await sdk.vault.getUserStats({ }) ``` --- + ## API-osToken ### `sdk.osToken.getBurnAmount` @@ -1370,6 +1326,28 @@ type Output = Array<{ await sdk.utils.getTransactions({ hash: '0x...' }) ``` --- +### `sdk.utils.getFiatRates` + +#### Description: + +Returns the USD, EUR, GBP exchange rates for the current asset + +#### Returns: + +```ts +type Output = { + assetsUsdRate: number + usdToEurRate: number + usdToGbpRate: number +} +``` + +#### Example: + +```ts +await sdk.utils.getFiatRates() +``` +--- ## Transactions Transactions work through the provider you sent when creating an instance of our SDK class. Or, if you are a custodian, you can get the transaction data and sign it yourself. Each transaction also gives you the opportunity to get an approximate gas for sending it. For custodians, it is more reliable to calculate the gas yourself. Each transaction has encode and estimateGas methods for your convenience diff --git a/changelog/next-release.md b/changelog/next-release.md index 4b2baaa7..fdc2fc51 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -86,15 +86,38 @@ type RemovedOutput = { --- ---- -### 10. Deprecated method `sdk.vault.getSnapshots` +### 10. Removed method `sdk.vault.getSnapshots` ### Use `sdk.vault.getVaultStats` instead --- + +### 11. Update method `sdk.vault.getUserRewards` +#### Update output format: + +```ts +type Output = { + date: number + dailyRewards: number + dailyRewardsEur: number + dailyRewardsGbp: number + dailyRewardsUsd: number +}[] +``` + +#### New arguments: + +| Name | Type | Type | Description | +|------|----------|-------------|---| +| dateFrom | `number` | **Yes** | Time to start in milliseconds | +| dateTo | `number` | **Yes** | Time to end in milliseconds | +| userAddress | `string` | **Yes** | The user address | +| vaultAddress | `string` | **Yes** | The address of the vault | + --- -### 11. Deprecated method `sdk.vault.getUserRewards` -### Use `sdk.vault.getUserStats` instead +### 12. Added method getFiatRates +### `sdk.utils.getFiatRates` --- + diff --git a/src/graphql/backend/vault/index.ts b/src/graphql/backend/vault/index.ts index e589a5c8..8eeeeb3e 100644 --- a/src/graphql/backend/vault/index.ts +++ b/src/graphql/backend/vault/index.ts @@ -4,9 +4,6 @@ export type { SnapshotsQueryPayload, SnapshotsQueryVariables } from './snapshots export { fetchValidatorsQuery } from './validatorsQuery.graphql' export type { ValidatorsQueryPayload, ValidatorsQueryVariables } from './validatorsQuery.graphql' -export { fetchUserRewardsQuery } from './userRewardsQuery.graphql' -export type { UserRewardsQueryPayload, UserRewardsQueryVariables } from './userRewardsQuery.graphql' - export { fetchScorePercentilesQuery } from './scorePercentilesQuery.graphql' export type { ScorePercentilesQueryPayload, ScorePercentilesQueryVariables } from './scorePercentilesQuery.graphql' diff --git a/src/graphql/backend/vault/userRewardsQuery.graphql b/src/graphql/backend/vault/userRewardsQuery.graphql deleted file mode 100644 index dc89e39f..00000000 --- a/src/graphql/backend/vault/userRewardsQuery.graphql +++ /dev/null @@ -1,10 +0,0 @@ -query UserRewards($user: String!, $vaultAddress: String!, $dateFrom: DateAsTimestamp!, $dateTo: DateAsTimestamp, $fillGaps: Boolean = true) { - userRewards(user: $user, vaultAddress: $vaultAddress, dateFrom: $dateFrom, dateTo: $dateTo, fillGaps: $fillGaps) { - date - sumRewards - dailyRewards - dailyRewardsEur - dailyRewardsGbp - dailyRewardsUsd - } -} diff --git a/src/graphql/subgraph/stats/fiatRatesQuery.graphql b/src/graphql/subgraph/stats/fiatRatesQuery.graphql new file mode 100644 index 00000000..8324fd3a --- /dev/null +++ b/src/graphql/subgraph/stats/fiatRatesQuery.graphql @@ -0,0 +1,7 @@ +query FiatRates { + networks { + assetsUsdRate + usdToEurRate + usdToGbpRate + } +} diff --git a/src/graphql/subgraph/stats/index.ts b/src/graphql/subgraph/stats/index.ts index 843767c8..95c5b1eb 100644 --- a/src/graphql/subgraph/stats/index.ts +++ b/src/graphql/subgraph/stats/index.ts @@ -1,2 +1,5 @@ export { fetchStatsQuery } from './statsQuery.graphql' export type { StatsQueryPayload, StatsQueryVariables } from './statsQuery.graphql' + +export { fetchFiatRatesQuery } from './fiatRatesQuery.graphql' +export type { FiatRatesQueryPayload, FiatRatesQueryVariables } from './fiatRatesQuery.graphql' diff --git a/src/graphql/subgraph/vault/index.ts b/src/graphql/subgraph/vault/index.ts index b1d5c3f0..3f7c9923 100644 --- a/src/graphql/subgraph/vault/index.ts +++ b/src/graphql/subgraph/vault/index.ts @@ -7,6 +7,9 @@ export type { UserStatsQueryPayload, UserStatsQueryVariables } from './userStats export { fetchVaultStatsQuery } from './vaultStatsQuery.graphql' export type { VaultStatsQueryPayload, VaultStatsQueryVariables } from './vaultStatsQuery.graphql' +export { fetchUserRewardsQuery } from './userRewardsQuery.graphql' +export type { UserRewardsQueryPayload, UserRewardsQueryVariables } from './userRewardsQuery.graphql' + export { fetchHarvestParamsQuery } from './harvestParamsQuery.graphql' export type { HarvestParamsQueryPayload, HarvestParamsQueryVariables } from './harvestParamsQuery.graphql' diff --git a/src/graphql/subgraph/vault/userRewardsQuery.graphql b/src/graphql/subgraph/vault/userRewardsQuery.graphql new file mode 100644 index 00000000..b5d6a53e --- /dev/null +++ b/src/graphql/subgraph/vault/userRewardsQuery.graphql @@ -0,0 +1,18 @@ +query UserRewards($user: Bytes!, $vaultAddress: String!, $dateFrom: Timestamp!, $dateTo: Timestamp!) { + exchangeRate: exchangeRateStats_collection( + interval: day + where: { timestamp_gte: $dateFrom, timestamp_lte: $dateTo } + ) { + timestamp + assetsUsdRate + usdToEurRate + usdToGbpRate + } + allocator: allocatorStats_collection( + interval: day + where: { timestamp_gte: $dateFrom, timestamp_lte: $dateTo, allocator_: { address: $user, vault: $vaultAddress } } + ) { + timestamp + earnedAssets + } +} diff --git a/src/methods/utils/getFiatRates.ts b/src/methods/utils/getFiatRates.ts new file mode 100644 index 00000000..84913305 --- /dev/null +++ b/src/methods/utils/getFiatRates.ts @@ -0,0 +1,42 @@ +import graphql from '../../graphql' +import { apiUrls, configs, Network } from '../../utils' + + +type GetFiatRatesInput = { + options: StakeWise.Options +} + +const getMainnetGbpRate = () => { + return graphql.subgraph.stats.fetchFiatRatesQuery({ + url: configs[Network.Mainnet].api.subgraph, + modifyResult: (data): number => { + const usdInGbp = Number(data.networks[0].usdToGbpRate) + + return usdInGbp + }, + }) +} + +const getFiatRates = (values: GetFiatRatesInput) => { + const { options } = values + + return graphql.subgraph.stats.fetchFiatRatesQuery({ + url: apiUrls.getSubgraphqlUrl(options), + modifyResult: async (data) => { + const usd = Number(data.networks[0].assetsUsdRate) + const usdInEur = Number(data.networks[0].usdToEurRate) + + const isGnosis = [ Network.Gnosis, Network.Chiado ].includes(options.network) + const usdInGbp = isGnosis ? await getMainnetGbpRate() : Number(data.networks[0].usdToGbpRate) + + return { + assetsUsdRate: usd, + usdToEurRate: usdInEur, + usdToGbpRate: usdInGbp, + } + }, + }) +} + + +export default getFiatRates diff --git a/src/methods/utils/index.ts b/src/methods/utils/index.ts index 522af2f2..356d223e 100644 --- a/src/methods/utils/index.ts +++ b/src/methods/utils/index.ts @@ -1,4 +1,5 @@ export type { BaseInput } from './types' +export { default as getFiatRates } from './getFiatRates' export { default as getTransactions } from './getTransactions' export { default as getSwiseUsdPrice } from './getSwiseUsdPrice' export { default as getStakewiseStats } from './getStakewiseStats' diff --git a/src/methods/vault/index.ts b/src/methods/vault/index.ts index f39667df..4bcbc3d7 100644 --- a/src/methods/vault/index.ts +++ b/src/methods/vault/index.ts @@ -1,7 +1,6 @@ // Requests import getVault from './requests/getVault' import getEigenPods from './requests/getEigenPods' -import getSnapshots from './requests/getSnapshots' import getWhitelist from './requests/getWhitelist' import getBlocklist from './requests/getBlocklist' import getUserStats from './requests/getUserStats' @@ -66,9 +65,7 @@ export default { getStakeBalance, /** * @description Daily rewards for the user who has made a deposit in the vault. - * With the help of this data it is possible to build a chart. * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetuserrewards - * @deprecated use https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetuserstats */ getUserRewards, /** @@ -87,12 +84,6 @@ export default { * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgeteigenpods */ getEigenPods, - /** - * @description TVL and APY snapshots for the vault. With the help of this data it is possible to build a chart. - * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetsnapshots - * @deprecated use https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetvaultstats - */ - getSnapshots, /** * @description Fetch the whitelist for private vaults. Only addresses included in * this list are eligible to stake in the private vault. The number of addresses in diff --git a/src/methods/vault/requests/getSnapshots/index.ts b/src/methods/vault/requests/getSnapshots/index.ts deleted file mode 100644 index fe078381..00000000 --- a/src/methods/vault/requests/getSnapshots/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { SnapshotsQueryVariables } from '../../../../graphql/backend/vault' -import { apiUrls, validateArgs } from '../../../../utils' -import modifySnapshots from './modifySnapshots' -import graphql from '../../../../graphql' -import { ModifiedSnapshots } from './types' - - -type GetSnapshotsInput = { - options: StakeWise.Options - vaultAddress: SnapshotsQueryVariables['vaultAddress'] - dateFrom: number -} - -const getSnapshots = (input: GetSnapshotsInput) => { - const { options, vaultAddress, dateFrom } = input - - validateArgs.address({ vaultAddress }) - validateArgs.number({ dateFrom }) - - return graphql.backend.vault.fetchSnapshotsQuery({ - url: apiUrls.getBackendUrl(options), - variables: { - vaultAddress: vaultAddress.toLowerCase(), - dateFrom: String(dateFrom), - } as SnapshotsQueryVariables, - modifyResult: modifySnapshots, - }) -} - - -export default getSnapshots diff --git a/src/methods/vault/requests/getSnapshots/modifySnapshots.spec.ts b/src/methods/vault/requests/getSnapshots/modifySnapshots.spec.ts deleted file mode 100644 index c8320617..00000000 --- a/src/methods/vault/requests/getSnapshots/modifySnapshots.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import type { SnapshotsQueryPayload } from '../../../../graphql/backend/vault' -import modifySnapshots, { modifySnapshot } from './modifySnapshots' - - -describe('modifyVaultSnapshot and modifyVaultSnapshots functions', () => { - const sampleInput: SnapshotsQueryPayload = { - vaultSnapshots: [ - { - date: '1700870400', - totalAssets: '3906945363776011390139', - weeklyApy: '1.8793377858', - }, - { - date: '1700956800', - totalAssets: '3907107984571011390139', - weeklyApy: '1.6767640360', - }, - ], - firstSnapshots: [ - { - date: '1700870400', - totalAssets: '3906945363776011390139', - weeklyApy: '1.8793377858', - }, - ], - } - - it('should correctly modify a single vault snapshot', () => { - const vaultSnapshot = sampleInput.vaultSnapshots[0] - - const result = modifySnapshot(vaultSnapshot) - - expect(result).toEqual({ - APY: Number(vaultSnapshot.weeklyApy), - TVL: 3906.945363776011, - }) - }) - - it('should correctly modify multiple vault snapshots', () => { - const expectedResult = { - days: { - 1700870400: { - APY: Number(sampleInput.vaultSnapshots[0].weeklyApy), - TVL: 3906.945363776011, - }, - 1700956800: { - APY: Number(sampleInput.vaultSnapshots[1].weeklyApy), - TVL: 3907.1079845710115, - }, - }, - first: { - APY: Number(sampleInput.firstSnapshots[0].weeklyApy), - TVL: 3906.945363776011, - }, - } - - const result = modifySnapshots(sampleInput) - - expect(result).toEqual(expectedResult) - }) -}) diff --git a/src/methods/vault/requests/getSnapshots/modifySnapshots.ts b/src/methods/vault/requests/getSnapshots/modifySnapshots.ts deleted file mode 100644 index 7ad0bdf0..00000000 --- a/src/methods/vault/requests/getSnapshots/modifySnapshots.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { formatEther } from 'ethers' - -import { ModifiedSnapshots } from './types' -import type { SnapshotsQueryPayload } from '../../../../graphql/backend/vault' - - -export const modifySnapshot = (vaultSnapshot: Omit) => { - const apyValue = Number(vaultSnapshot.weeklyApy) || 0 - const tvlValue = vaultSnapshot.totalAssets || '0' - - return { - APY: apyValue, - TVL: Number(formatEther(tvlValue)), - } -} - -const modifySnapshots = (input: SnapshotsQueryPayload): ModifiedSnapshots => { - const days = input.vaultSnapshots.reduce((acc, { date, ...rest }) => { - acc[Number(date)] = modifySnapshot(rest) - - return acc - }, {} as ModifiedSnapshots['days']) - - const first = input.firstSnapshots[0] - ? modifySnapshot(input.firstSnapshots[0]) - : null - - return { - days, - first, - } -} - - -export default modifySnapshots diff --git a/src/methods/vault/requests/getSnapshots/types.ts b/src/methods/vault/requests/getSnapshots/types.ts deleted file mode 100644 index 0a5beb01..00000000 --- a/src/methods/vault/requests/getSnapshots/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -type Snapshot = { - APY: number - TVL: number -} - -export type ModifiedSnapshots = { - days: Record - first: Snapshot | null -} diff --git a/src/methods/vault/requests/getUserRewards/index.ts b/src/methods/vault/requests/getUserRewards/index.ts index bc3e997c..1965b0e7 100644 --- a/src/methods/vault/requests/getUserRewards/index.ts +++ b/src/methods/vault/requests/getUserRewards/index.ts @@ -1,39 +1,53 @@ -import type { UserRewardsQueryVariables } from '../../../../graphql/backend/vault' -import { apiUrls, validateArgs } from '../../../../utils' +import type { UserRewardsQueryVariables } from '../../../../graphql/subgraph/vault' +import { apiUrls, Network, validateArgs, configs } from '../../../../utils' import modifyUserRewards from './modifyUserRewards' import graphql from '../../../../graphql' -import { ModifyUserReward } from './types' +import type { ModifyUserRewards, GbpRate } from './types' type GetUserRewardsInput = { + dateTo: number + dateFrom: number options: StakeWise.Options userAddress: UserRewardsQueryVariables['user'] vaultAddress: UserRewardsQueryVariables['vaultAddress'] - dateFrom: number - dateTo?: number - fillGaps?: boolean } -const getUserRewards = (input: GetUserRewardsInput) => { - const { options, vaultAddress, userAddress, dateFrom, dateTo, fillGaps } = input +const getMainnetGbpRate = (input: GetUserRewardsInput) => { + const { dateFrom, dateTo, userAddress, vaultAddress } = input + + return graphql.subgraph.vault.fetchUserRewardsQuery({ + url: configs[Network.Mainnet].api.subgraph, + variables: { + dateTo: String(dateTo * 1_000), + user: userAddress.toLowerCase(), + dateFrom: String(dateFrom * 1_000), + vaultAddress: vaultAddress.toLowerCase(), + } as UserRewardsQueryVariables, + modifyResult: (data) : GbpRate[] => { + return data.exchangeRate.map(({ usdToGbpRate }) => ({ usdToGbpRate })) + }, + }) +} + +const getUserRewards = async (input: GetUserRewardsInput) => { + const { options, vaultAddress, userAddress, dateFrom, dateTo } = input validateArgs.address({ vaultAddress, userAddress }) - validateArgs.number({ dateFrom }) + validateArgs.number({ dateFrom, dateTo }) - if (dateTo) { - validateArgs.number({ dateTo }) - } + const isGnosis = [ Network.Gnosis, Network.Chiado ].includes(options.network) + const mainnetGbpRates = isGnosis ? await getMainnetGbpRate(input) : [] - return graphql.backend.vault.fetchUserRewardsQuery({ - url: apiUrls.getBackendUrl(options), + return graphql.subgraph.vault.fetchUserRewardsQuery({ + url: apiUrls.getSubgraphqlUrl(options), variables: { - fillGaps, - dateFrom: String(dateFrom), + dateTo: String(dateTo * 1_000), user: userAddress.toLowerCase(), - dateTo: dateTo ? String(dateTo) : undefined, + dateFrom: String(dateFrom * 1_000), vaultAddress: vaultAddress.toLowerCase(), } as UserRewardsQueryVariables, - modifyResult: modifyUserRewards, + modifyResult: modifyUserRewards(mainnetGbpRates), }) } diff --git a/src/methods/vault/requests/getUserRewards/modifyUserRewards.spec.ts b/src/methods/vault/requests/getUserRewards/modifyUserRewards.spec.ts index 41a3367b..f187c444 100644 --- a/src/methods/vault/requests/getUserRewards/modifyUserRewards.spec.ts +++ b/src/methods/vault/requests/getUserRewards/modifyUserRewards.spec.ts @@ -1,65 +1,55 @@ -import type { UserRewardsQueryPayload } from '../../../../graphql/backend/vault' -import modifyUserRewards, { modifyUserReward } from './modifyUserRewards' +import type { UserRewardsQueryPayload } from '../../../../graphql/subgraph/vault' +import modifyUserRewards from './modifyUserRewards' +import { formatEther } from 'ethers' -describe('modifyUserReward and modifyUserRewards functions', () => { +describe('modifyUserRewards and modifyUserRewards functions', () => { const sampleInput: UserRewardsQueryPayload = { - userRewards: [ + allocator: [ { - date: '1694908800', - sumRewards: '344379922475148628745', - dailyRewards: '344379922475148628745', - dailyRewardsEur: '0.10', - dailyRewardsGbp: '0.09', - dailyRewardsUsd: '0.11', + timestamp: '1727136000000000', + earnedAssets: '27734011365427', }, { - date: '1694995200', - sumRewards: '344382187878289278175', - dailyRewards: '0', - dailyRewardsEur: '0.10', - dailyRewardsGbp: '0.09', - dailyRewardsUsd: '0.11', + timestamp: '1727049600000000', + earnedAssets: '31538735933515', + }, + ], + exchangeRate: [ + { + timestamp: '1727136000000000', + assetsUsdRate: '2668.52572642', + usdToEurRate: '0.8938307799567385902500938522318955', + usdToGbpRate: '0.7452231198020687393805705428205205', + }, + { + timestamp: '1727049600000000', + assetsUsdRate: '2648.01679703', + usdToEurRate: '0.8993614533681086428635668675240579', + usdToGbpRate: '0.7486430844095077671720007486430844', }, ], } - it('should correctly modify a single reward', () => { - const userReward = sampleInput.userRewards[0] - - const result = modifyUserReward(userReward) - - expect(result).toEqual({ - date: 1694908800, - sumRewards: 344.37992247514865, - dailyRewards: 344.37992247514865, - dailyRewardsEur: 0.10, - dailyRewardsGbp: 0.09, - dailyRewardsUsd: 0.11, - }) - }) - it('should correctly modify multiple rewards', () => { - const expectedResult = { - 1694908800: { - date: 1694908800, - sumRewards: 344.37992247514865, - dailyRewards: 344.37992247514865, - dailyRewardsEur: 0.10, - dailyRewardsGbp: 0.09, - dailyRewardsUsd: 0.11, + const expectedResult = [ + { + date: 1727049600000, + dailyRewards: Number(formatEther('31538735933515')), + dailyRewardsUsd: 0.08351510250904134, + dailyRewardsEur: 0.075110263970718, + dailyRewardsGbp: 0.06252300393714494, }, - 1694995200: { - date: 1694995200, - sumRewards: 344.3821878782893, - dailyRewards: 0, - dailyRewardsEur: 0.10, - dailyRewardsGbp: 0.09, - dailyRewardsUsd: 0.11, + { + date: 1727136000000, + dailyRewards: Number(formatEther('27734011365427')), + dailyRewardsUsd: 0.07400892282546662, + dailyRewardsEur: 0.0661514532128449, + dailyRewardsGbp: 0.05515316036118477, }, - } + ] - const result = modifyUserRewards(sampleInput) + const result = modifyUserRewards([])(sampleInput) expect(result).toEqual(expectedResult) }) diff --git a/src/methods/vault/requests/getUserRewards/modifyUserRewards.ts b/src/methods/vault/requests/getUserRewards/modifyUserRewards.ts index 828a360c..8d6c0cd4 100644 --- a/src/methods/vault/requests/getUserRewards/modifyUserRewards.ts +++ b/src/methods/vault/requests/getUserRewards/modifyUserRewards.ts @@ -1,31 +1,48 @@ import { formatEther } from 'ethers' -import { ModifyUserReward } from './types' -import type { UserRewardsQueryPayload } from '../../../../graphql/backend/vault' +import type { ModifyUserRewards, GbpRate } from './types' +import type { UserRewardsQueryPayload } from '../../../../graphql/subgraph/vault' -export const modifyUserReward = (reward: UserRewardsQueryPayload['userRewards'][number]) => { - const sumRewards = String(reward.sumRewards) || '0' - const dailyRewards = String(reward.dailyRewards) || '0' +type Input = { + reward: UserRewardsQueryPayload['allocator'][number] + assetsUsdRate: number + usdToEurRate: number + usdToGbpRate: number +} + +export const modifyReward = (input: Input) => { + const { reward, assetsUsdRate, usdToGbpRate, usdToEurRate } = input + + const timeInMilliSeconds = Number(reward.timestamp) / 1_000 + const earnedAssetsInEther = Number(formatEther(reward.earnedAssets)) + const earnedAssetsInUsd = earnedAssetsInEther * assetsUsdRate return { - date: Number(reward.date), - sumRewards: Number(formatEther(sumRewards)), - dailyRewards: Number(formatEther(dailyRewards)), - dailyRewardsEur: Number(reward.dailyRewardsEur) || 0, - dailyRewardsGbp: Number(reward.dailyRewardsGbp) || 0, - dailyRewardsUsd: Number(reward.dailyRewardsUsd) || 0, + date: timeInMilliSeconds, + dailyRewards: earnedAssetsInEther, + dailyRewardsUsd: earnedAssetsInUsd || 0, + dailyRewardsEur: earnedAssetsInUsd * Number(usdToEurRate) || 0, + dailyRewardsGbp: earnedAssetsInUsd * Number(usdToGbpRate) || 0, } } -const modifyUserRewards = (input: UserRewardsQueryPayload): ModifyUserReward => { - const days = input.userRewards.reduce((acc, { date, ...rest }) => { - acc[Number(date)] = modifyUserReward({ date, ...rest }) +const modifyUserRewards = (mainnetGbpRates: GbpRate[]) => (data: UserRewardsQueryPayload): ModifyUserRewards[] => { + const allocatorStats = data?.allocator || [] + const exchangeRateStats = data?.exchangeRate || [] + + const result = allocatorStats.map((stat, index) => { + const gbpRate = mainnetGbpRates.length ? mainnetGbpRates[index]?.usdToGbpRate : exchangeRateStats[index]?.usdToGbpRate - return acc - }, {} as ModifyUserReward) + return modifyReward({ + reward: stat, + usdToGbpRate: Number(gbpRate), + usdToEurRate: Number(exchangeRateStats[index]?.usdToEurRate), + assetsUsdRate: Number(exchangeRateStats[index]?.assetsUsdRate), + }) + }) - return days || {} + return result.sort((a, b) => a.date - b.date) } diff --git a/src/methods/vault/requests/getUserRewards/types.ts b/src/methods/vault/requests/getUserRewards/types.ts index 64db8668..a2cbd314 100644 --- a/src/methods/vault/requests/getUserRewards/types.ts +++ b/src/methods/vault/requests/getUserRewards/types.ts @@ -1,10 +1,9 @@ -type UserReward = { +export type GbpRate = { usdToGbpRate: string } + +export type ModifyUserRewards = { date: number - sumRewards: number dailyRewards: number dailyRewardsEur: number dailyRewardsGbp: number dailyRewardsUsd: number } - -export type ModifyUserReward = Record From 9255d2d9868bf01da0242a5de3b75591cb0f0c45 Mon Sep 17 00:00:00 2001 From: CAst Date: Fri, 4 Oct 2024 15:15:29 +0500 Subject: [PATCH 27/36] [polishing] remove old & change harvest (#181) --- README.md | 10 ++++--- changelog/next-release.md | 30 +++++++++++-------- .../multicall/util/getHarvestArgs.ts | 10 ++++--- src/methods/osToken/index.ts | 7 ----- .../vault/requests/getHarvestParams.ts | 9 +++++- .../requests/getVault/modifyVault.spec.ts | 3 +- .../vault/requests/getVault/modifyVault.ts | 1 - src/methods/vault/requests/getVault/types.ts | 5 ---- .../deposit/nativeToken/common.ts | 7 ++--- .../deposit/nativeToken/deposit.ts | 7 ++--- .../deposit/nativeToken/depositEncode.ts | 7 ++--- .../deposit/nativeToken/depositGas.ts | 7 ++--- 12 files changed, 51 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index ae4040cf..b9cfea78 100644 --- a/README.md +++ b/README.md @@ -702,11 +702,13 @@ Necessary to update the vault state ```ts type Output = { - reward: string - proof: Array canHarvest: boolean - rewardsRoot: string - unlockedMevReward: string + params: { + reward: string + proof: Array + rewardsRoot: string + unlockedMevReward: string + } } ``` diff --git a/changelog/next-release.md b/changelog/next-release.md index fdc2fc51..f60eb4d3 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -9,31 +9,34 @@ type AddedOutput = { ltvPercent: string thresholdPercent: string } + isGenesis: boolean } ``` -| Name | Description | -|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Name | Description | +|------|-------------| | `osTokenConfig` | contains the `ltvPercent`, which is the percentage used to calculate how much a user can mint in OsToken shares, and `thresholdPercent`, which is the liquidation threshold percentage used to calculate the health factor for the OsToken position | +| `isGenesis` | This vault is owned by stakewise | --- ### 2. `sdk.vault.getHarvestParams` -#### New output field: +#### New output format: ```ts -type AddedOutput = { - canHarvest: boolean +type Output = { + canHarvest: boolean // NEW + params: { + reward: string + proof: Array + rewardsRoot: string + unlockedMevReward: string + } } ``` --- -### 3. Removed method -### `sdk.vault.getVault` - ---- - ### 3. Removed method ### `sdk.osToken.getAvgRewardsPerSecond` @@ -52,6 +55,7 @@ type RemovedOutput = { ### 5. Added method getStakewiseStats ### `sdk.utils.getStakewiseStats` +#### Getting common stakewise data for the network --- @@ -86,7 +90,6 @@ type RemovedOutput = { --- - ### 10. Removed method `sdk.vault.getSnapshots` ### Use `sdk.vault.getVaultStats` instead @@ -96,13 +99,13 @@ type RemovedOutput = { #### Update output format: ```ts -type Output = { +type Output = Array<{ date: number dailyRewards: number dailyRewardsEur: number dailyRewardsGbp: number dailyRewardsUsd: number -}[] +}> ``` #### New arguments: @@ -118,6 +121,7 @@ type Output = { ### 12. Added method getFiatRates ### `sdk.utils.getFiatRates` +#### Getting fiat values for the network --- diff --git a/src/contracts/multicall/util/getHarvestArgs.ts b/src/contracts/multicall/util/getHarvestArgs.ts index 351c78eb..38156867 100644 --- a/src/contracts/multicall/util/getHarvestArgs.ts +++ b/src/contracts/multicall/util/getHarvestArgs.ts @@ -7,16 +7,18 @@ type Input = { vaultAddress: string } -const getHarvestArgs = async (props: Input): Promise => { +type Output = Promise | null> + +const getHarvestArgs = async (props: Input): Output => { const { options, vaultAddress } = props - const harvestParams = await getHarvestParams({ + const { params, canHarvest } = await getHarvestParams({ options, vaultAddress, }) - if (harvestParams?.canHarvest) { - return harvestParams + if (canHarvest) { + return params } return null diff --git a/src/methods/osToken/index.ts b/src/methods/osToken/index.ts index 21dd3099..2771d146 100644 --- a/src/methods/osToken/index.ts +++ b/src/methods/osToken/index.ts @@ -1,6 +1,5 @@ // Requests import getAPY from './requests/getOsTokenAPY' -import getConfig from './requests/getConfig' import getMaxMint from './requests/getMaxMint' import getRate from './requests/getOsTokenRate' import getPosition from './requests/getPosition' @@ -26,12 +25,6 @@ export default { * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkostokengetrate */ getRate, - /** - * @deprecated use sdk.vault.getVault instead to get data from osTokenConfig - * @description os token ltvPercent and thresholdPercent for provided vault - * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkostokengetconfig - */ - getConfig, /** * @description Maximum number of **shares** for minting * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkostokengetmaxmint diff --git a/src/methods/vault/requests/getHarvestParams.ts b/src/methods/vault/requests/getHarvestParams.ts index e54aeef1..89d121a8 100644 --- a/src/methods/vault/requests/getHarvestParams.ts +++ b/src/methods/vault/requests/getHarvestParams.ts @@ -17,7 +17,14 @@ const getHarvestParams = (values: GetHarvestParamsInput) => { variables: { address: vaultAddress.toLowerCase(), }, - modifyResult: (data) => data.harvestParams, + modifyResult: (data) => { + const { canHarvest, ...params } = data.harvestParams + + return { + canHarvest, + params, + } + }, }) } diff --git a/src/methods/vault/requests/getVault/modifyVault.spec.ts b/src/methods/vault/requests/getVault/modifyVault.spec.ts index dfe157a9..9894f0ce 100644 --- a/src/methods/vault/requests/getVault/modifyVault.spec.ts +++ b/src/methods/vault/requests/getVault/modifyVault.spec.ts @@ -14,6 +14,7 @@ describe('modifyVault', () => { feePercent: 200, isPrivate: false, isRestake: true, + isGenesis: true, isBlocklist: false, version: '1', performance: '10', @@ -56,6 +57,7 @@ describe('modifyVault', () => { performance: 10, isPrivate: false, isRestake: true, + isGenesis: true, isBlocklist: false, blocklistCount: 0, whitelistCount: 0, @@ -70,7 +72,6 @@ describe('modifyVault', () => { depositDataRoot: 'mockValidators', description: 'This is a mock vault', vaultAdmin: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', - whitelister: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', vaultAddress: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', feeRecipient: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', mevRecipient: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', diff --git a/src/methods/vault/requests/getVault/modifyVault.ts b/src/methods/vault/requests/getVault/modifyVault.ts index 60d061b0..bc940752 100644 --- a/src/methods/vault/requests/getVault/modifyVault.ts +++ b/src/methods/vault/requests/getVault/modifyVault.ts @@ -53,7 +53,6 @@ const modifyVault = (input: ModifyVaultInput): ModifiedVault => { feeRecipient: getAddress(feeRecipient), blocklistCount: Number(blocklistCount), whitelistCount: Number(whitelistCount), - whitelister: vault.whitelister ? getAddress(vault.whitelister) : '', whitelistManager: vault.whitelister ? getAddress(vault.whitelister) : '', validatorsManager: validatorsManager ? getAddress(validatorsManager) : '', depositDataManager: depositDataManager ? getAddress(depositDataManager) : '', diff --git a/src/methods/vault/requests/getVault/types.ts b/src/methods/vault/requests/getVault/types.ts index 6bf71326..333ecfee 100644 --- a/src/methods/vault/requests/getVault/types.ts +++ b/src/methods/vault/requests/getVault/types.ts @@ -30,9 +30,4 @@ export type ModifiedVault = Omit< ltvPercent: string // The percent used to calculate how much user can mint OsToken shares thresholdPercent: string // The liquidation threshold percent used to calculate health factor for OsToken position } - - /** - * @deprecated use whitelistManager - */ - whitelister: string } diff --git a/src/methods/vault/transactions/deposit/nativeToken/common.ts b/src/methods/vault/transactions/deposit/nativeToken/common.ts index e9201ada..f6ff8867 100644 --- a/src/methods/vault/transactions/deposit/nativeToken/common.ts +++ b/src/methods/vault/transactions/deposit/nativeToken/common.ts @@ -5,19 +5,18 @@ import { validateArgs } from '../../../../../utils' export const commonLogic = async (values: DepositInput) => { - const { contracts, vaultAddress, userAddress, assets } = values + const { contracts, vaultAddress, assets } = values validateArgs.bigint({ assets }) - validateArgs.address({ vaultAddress, userAddress }) + validateArgs.address({ vaultAddress }) const vaultContract = contracts.helpers.createVault({ vaultAddress }) - const canHarvest = await contracts.base.keeper.canHarvest(vaultAddress) const overrides = { value: assets, } - return { vaultContract, canHarvest, overrides } + return { vaultContract, overrides } } diff --git a/src/methods/vault/transactions/deposit/nativeToken/deposit.ts b/src/methods/vault/transactions/deposit/nativeToken/deposit.ts index 9da45cb2..42c1e57e 100644 --- a/src/methods/vault/transactions/deposit/nativeToken/deposit.ts +++ b/src/methods/vault/transactions/deposit/nativeToken/deposit.ts @@ -8,15 +8,14 @@ import getHarvestParams from '../../../requests/getHarvestParams' const deposit: Deposit = async (values) => { const { options, provider, vaultAddress, userAddress } = values - const { vaultContract, canHarvest, overrides } = await commonLogic(values) + const { params, canHarvest } = await getHarvestParams({ options, vaultAddress }) + const { vaultContract, overrides } = await commonLogic(values) const signer = await provider.getSigner(userAddress) const signedContract = vaultContract.connect(signer) if (canHarvest) { - const harvestParams = await getHarvestParams({ options, vaultAddress }) - - const response = await signedContract.updateStateAndDeposit(userAddress, referrer, harvestParams, overrides) + const response = await signedContract.updateStateAndDeposit(userAddress, referrer, params, overrides) return response.hash } diff --git a/src/methods/vault/transactions/deposit/nativeToken/depositEncode.ts b/src/methods/vault/transactions/deposit/nativeToken/depositEncode.ts index 5c4ea72a..b22a8812 100644 --- a/src/methods/vault/transactions/deposit/nativeToken/depositEncode.ts +++ b/src/methods/vault/transactions/deposit/nativeToken/depositEncode.ts @@ -10,12 +10,11 @@ type DepositDataOutput = StakeWise.TransactionData & { const depositEncode = async (values: DepositInput): Promise => { const { options, vaultAddress, userAddress } = values - const { vaultContract, canHarvest, overrides } = await commonLogic(values) + const { vaultContract, overrides } = await commonLogic(values) + const { params, canHarvest } = await getHarvestParams({ options, vaultAddress }) if (canHarvest) { - const harvestParams = await getHarvestParams({ options, vaultAddress }) - - const rx = await vaultContract.updateStateAndDeposit.populateTransaction(userAddress, referrer, harvestParams, overrides) + const rx = await vaultContract.updateStateAndDeposit.populateTransaction(userAddress, referrer, params, overrides) return { ...rx, diff --git a/src/methods/vault/transactions/deposit/nativeToken/depositGas.ts b/src/methods/vault/transactions/deposit/nativeToken/depositGas.ts index eedd53e9..cd2f3b76 100644 --- a/src/methods/vault/transactions/deposit/nativeToken/depositGas.ts +++ b/src/methods/vault/transactions/deposit/nativeToken/depositGas.ts @@ -7,7 +7,8 @@ import getHarvestParams from '../../../requests/getHarvestParams' const depositGas = async (values: DepositInput) => { const { options, provider, vaultAddress, userAddress } = values - const { vaultContract, canHarvest, overrides } = await commonLogic(values) + const { vaultContract, overrides } = await commonLogic(values) + const { params, canHarvest } = await getHarvestParams({ options, vaultAddress }) const signer = await provider.getSigner(userAddress) const signedContract = vaultContract.connect(signer) @@ -15,9 +16,7 @@ const depositGas = async (values: DepositInput) => { let estimatedGas = 0n if (canHarvest) { - const harvestParams = await getHarvestParams({ options, vaultAddress }) - - estimatedGas = await signedContract.updateStateAndDeposit.estimateGas(userAddress, referrer, harvestParams, overrides) + estimatedGas = await signedContract.updateStateAndDeposit.estimateGas(userAddress, referrer, params, overrides) } else { estimatedGas = await signedContract.deposit.estimateGas(userAddress, referrer, overrides) From 55851574eeda831399a19b112390b53c46e0ebb2 Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Mon, 7 Oct 2024 11:25:10 +0300 Subject: [PATCH 28/36] Replace depositDataRoot & depositDataManager (#182) * replace (depositDataRoot & depositDataManager) V1 logic from vault.operate, to (vault.setDepositDataRoot & vault.setDepositDataManager) instead * add version * rename to input * PR improves --- README.md | 13 +++----- changelog/next-release.md | 11 +++++++ .../vault/transactions/operate/checkAccess.ts | 13 ++------ .../vault/transactions/operate/common.ts | 32 ++----------------- .../vault/transactions/operate/types.d.ts | 4 --- .../setDepositDataManager/index.ts | 23 +++++++++++-- .../transactions/setDepositDataRoot/index.ts | 24 ++++++++++++-- .../params/getDepositDataManagerParams.ts | 24 -------------- .../util/params/getDepositDataRootParams.ts | 24 -------------- .../vault/transactions/util/params/index.ts | 2 -- 10 files changed, 61 insertions(+), 109 deletions(-) delete mode 100644 src/methods/vault/transactions/util/params/getDepositDataManagerParams.ts delete mode 100644 src/methods/vault/transactions/util/params/getDepositDataRootParams.ts diff --git a/README.md b/README.md index b9cfea78..734d1e0b 100644 --- a/README.md +++ b/README.md @@ -621,6 +621,7 @@ type Output = { | Name | Description | |-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `version` | Vault version | | `apy` | Current vault apy | | `isErc20` | Does the vault have its own ERC20 token | | `capacity` | Maximum TVL of Vault | @@ -649,7 +650,6 @@ type Output = { | `whitelist` | List of authorized users for deposits | | `blocklist` | List of blocked users for deposits | | `performance` | Vault performance indicator (percent) | -| `version` | Vault version | | `restakeOperatorsManager` | If the Vault is a restaking vault, restake operators manager can add/remove restake operators | | `restakeWithdrawalsManager` | If the Vault is a restaking vault, restake withdrawals manager can manage EigenLayer withdrawals | | `osTokenConfig` | contains the ltvPercent, which is the percentage used to calculate how much a user can mint in OsToken shares, and thresholdPercent, which is the liquidation threshold percentage used to calculate the health factor for the OsToken position | @@ -1704,7 +1704,7 @@ const gas = await sdk.vault.updateEigenPodOperator.estimateGas(params) #### Description: -Updates the vault by authorized personnel such as the vault admin, whitelistManager, blocklist manager, validators manager, or deposit-data manager. +Updates the vault by authorized personnel such as the vault admin, whitelistManager, blocklist manager, validators manager. #### Arguments: @@ -1712,14 +1712,12 @@ Updates the vault by authorized personnel such as the vault admin, whitelistMana | Name | Type | Required | Access | Description | |---------------------------|----------------------------------------------|----------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | whitelistManager | `Array<{ address: string, isNew: boolean }>` | **No** | whitelistManager | List of addresses to update the whitelist. Use `isNew: true` to add a new address, `isNew: false` to remove an existing one. Max count at time - 700 addresses. | -| blocklist | `Array<{ address: string, isNew: boolean }>` | **No** | Blocklist manager | List of addresses to update the blocklist. Use `isNew: true` to add a new address, `isNew: false` to remove an existing one. Max count at time - 700 addresses. | -| depositDataManager | `string` | **No** | Deposit-data manager | Address of the vault keys manager. Support only **first version** on valults. For second verion use `vault.setDepositDataManager` | +| blocklist | `Array<{ address: string, isNew: boolean }>` | **No** | Blocklist manager | List of addresses to update the blocklist. Use `isNew: true` to add a new address, `isNew: false` to remove an existing one. Max count at time - 700 addresses. | | validatorsManager | `string` | **No** | Admin | Address of the vault deposit data manager. Support only **second version** on valults. | | restakeWithdrawalsManager | `string` | **No** | Admin | The restake withdrawals manager must be assigned to the wallet connected to the operator service. It is responsible for withdrawing exiting validators from the EigenLayer. | | restakeOperatorsManager | `string` | **No** | Admin | The restake operators manager can add EigenPods and update EigenLayer operators. | | whitelistManager | `string` | **No** | Admin | Address of the vault whitelistManager | -| feeRecipient | `string` | **No** | Admin | Address of the vault fee recipient | -| depositDataRoot | `string` | **No** | Keys manager | The vault validators merkle tree root. Support only **first version** on valults. For second verion use `vault.setDepositDataRoot` | +| feeRecipient | `string` | **No** | Admin | Address of the vault fee recipient | | blocklistManager | `string` | **No** | Admin | The blocklisted vault blocklist manager | | image | `string` | **No** | Admin | The vault image in base64 string format (will be uploaded to IPFS; maximum size is 1 MB) | | displayName | `string` | **No** | Admin | The vault display name (will be uploaded to IPFS; maximum size is 30 characters) | @@ -1738,18 +1736,15 @@ const params = { displayName: '...', description: '...', feeRecipient: '0x...', - depositDataRoot: '0x...', blocklistManager: '0x...', whitelistManager: '0x...', validatorsManager: '0x...', - depositDataManager: '0x...', restakeOperatorsManager: '0x...', restakeWithdrawalsManager: '0x...', } // Data to update the vault by vault keys manager. const params = { - depositDataRoot: '...', vaultAddress: '0x...', userAddress: '0x...', } diff --git a/changelog/next-release.md b/changelog/next-release.md index f60eb4d3..68b3290a 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -125,3 +125,14 @@ type Output = Array<{ --- +### 13. Removed input field +### `sdk.vault.operate` +#### Removed depositDataRoot use `vault.setDepositDataRoot` instead +#### Removed depositDataManager use `vault.setDepositDataManager` instead + +```ts +type RemovedInput = { + depositDataManager: string + depositDataRoot: string +} +``` diff --git a/src/methods/vault/transactions/operate/checkAccess.ts b/src/methods/vault/transactions/operate/checkAccess.ts index 41f29924..9f3867a5 100644 --- a/src/methods/vault/transactions/operate/checkAccess.ts +++ b/src/methods/vault/transactions/operate/checkAccess.ts @@ -4,7 +4,6 @@ import { checkAdminAccess, checkWhitelisterAccess, checkBlocklistManagerAccess, - checkDepositDataManagerAccess, } from '../util' @@ -13,8 +12,8 @@ type Action = (props: Input) => Promise const checkAccess = (action: Action) => ( async (values: Input) => { const { - blocklist, whitelist, depositDataManager, whitelistManager, feeRecipient, - depositDataRoot, blocklistManager, metadataIpfsHash, validatorsManager, restakeOperatorsManager, restakeWithdrawalsManager, + blocklist, whitelist, whitelistManager, feeRecipient, + blocklistManager, metadataIpfsHash, validatorsManager, restakeOperatorsManager, restakeWithdrawalsManager, } = values try { @@ -29,12 +28,9 @@ const checkAccess = (action: Action) => ( || blocklistManager || metadataIpfsHash || validatorsManager - || depositDataManager || restakeOperatorsManager || restakeWithdrawalsManager ) - - const isDepositData = Boolean(depositDataRoot) const isWhitelistManager = Boolean(whitelist) const isBlocklistManager = Boolean(blocklist) @@ -45,11 +41,6 @@ const checkAccess = (action: Action) => ( checkAdminAccess(values) ) } - if (isDepositData) { - checkPromises.push( - checkDepositDataManagerAccess(values) - ) - } if (isWhitelistManager) { checkPromises.push( checkWhitelisterAccess(values) diff --git a/src/methods/vault/transactions/operate/common.ts b/src/methods/vault/transactions/operate/common.ts index 104981c6..b987befa 100644 --- a/src/methods/vault/transactions/operate/common.ts +++ b/src/methods/vault/transactions/operate/common.ts @@ -1,4 +1,4 @@ -import { validateArgs, getVaultVersion } from '../../../../utils' +import { validateArgs } from '../../../../utils' import type { MulticallTransactionInput } from './types' import { vaultMulticall } from '../../../../contracts' import type { VaultMulticallBaseInput } from '../../../../contracts' @@ -9,10 +9,8 @@ import { getWhitelistParams, getWhitelisterParams, getFeeRecipientParams, - getDepositDataRootParams, getBlocklistManagerParams, getValidatorsManagerParams, - getDepositDataManagerParams, getRestakeOperatorsManagerParams, getRestakeWithdrawalsManagerParams, } from '../util' @@ -20,8 +18,8 @@ import { export const commonLogic = async (values: MulticallTransactionInput) => { const { - depositDataRoot, blocklistManager, metadataIpfsHash, - blocklist, whitelist, depositDataManager, whitelistManager, feeRecipient, + blocklistManager, metadataIpfsHash, + blocklist, whitelist, whitelistManager, feeRecipient, options, contracts, userAddress, vaultAddress, provider, validatorsManager, restakeOperatorsManager, restakeWithdrawalsManager, } = values @@ -59,18 +57,6 @@ export const commonLogic = async (values: MulticallTransactionInput) => { } } - const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) - - if (!isV1Version) { - if (depositDataRoot) { - throw new Error('To set depositDataRoot in version 2 of vault, use the vault.setDepositDataRoot() method') - } - - if (depositDataManager) { - throw new Error('To set depositDataManager in version 2 of vault, use the vault.setDepositDataManager() method') - } - } - const baseMulticall: VaultMulticallBaseInput = { vaultContract, vaultAddress, @@ -100,12 +86,6 @@ export const commonLogic = async (values: MulticallTransactionInput) => { params.push(...whitelistParams) } - if (depositDataManager) { - const depositDataManagerParams = getDepositDataManagerParams({ ...baseInput, depositDataManager }) - - params.push(...depositDataManagerParams) - } - if (whitelistManager) { const whitelisterParams = getWhitelisterParams({ ...baseInput, whitelistManager }) @@ -118,12 +98,6 @@ export const commonLogic = async (values: MulticallTransactionInput) => { params.push(...feeRecipientParams) } - if (depositDataRoot) { - const validatorsRootParams = getDepositDataRootParams({ ...baseInput, depositDataRoot }) - - params.push(...validatorsRootParams) - } - if (typeof metadataIpfsHash !== 'undefined') { const metadataParams = getMetadataParams({ ...baseInput, metadataIpfsHash }) diff --git a/src/methods/vault/transactions/operate/types.d.ts b/src/methods/vault/transactions/operate/types.d.ts index f5ff00be..43cbe06c 100644 --- a/src/methods/vault/transactions/operate/types.d.ts +++ b/src/methods/vault/transactions/operate/types.d.ts @@ -7,10 +7,8 @@ import type { UpdateBlocklistParams } from '../util/params/getBlocklistParams' import type { UpdateWhitelistParams } from '../util/params/getWhitelistParams' import type { SetWhitelisterParams } from '../util/params/getWhitelisterParams' import type { SetFeeRecipientParams } from '../util/params/getFeeRecipientParams' -import type { SetValidatorsRootParams } from '../util/params/getValidatorsRootParams' import type { SetBlocklistManagerParams } from '../util/params/getBlocklistManagerParams' import type { SetValidatorsManagerParams } from '../util/params/getValidatorsManagerParams' -import type { SetDepositDataManagerParams } from '../util/params/getDepositDataManagerParams' import type { SetRestakeOperatorsManagerParams } from '../util/params/getRestakeOperatorsManagerParams' import type { SetRestakeWithdrawalsManagerParams } from '../util/params/getRestakeWithdrawalsManagerParams' @@ -27,10 +25,8 @@ type MulticallCommonParams = & SetFeeRecipientParams & UpdateBlocklistParams & UpdateWhitelistParams - & SetValidatorsRootParams & SetBlocklistManagerParams & SetValidatorsManagerParams - & SetDepositDataManagerParams & SetRestakeOperatorsManagerParams & SetRestakeWithdrawalsManagerParams diff --git a/src/methods/vault/transactions/setDepositDataManager/index.ts b/src/methods/vault/transactions/setDepositDataManager/index.ts index 9f2df2b1..646d0466 100644 --- a/src/methods/vault/transactions/setDepositDataManager/index.ts +++ b/src/methods/vault/transactions/setDepositDataManager/index.ts @@ -4,13 +4,30 @@ import type { SetDepositDataManagerRoot } from './types' import setDepositDataManagerGas from './setDepositDataManagerGas' import setDepositDataManagerEncode from './setDepositDataManagerEncode' +import { getVaultVersion } from '../../../../utils' -const setDepositDataManager: SetDepositDataManagerRoot = async (values) => { - const { provider, userAddress, managerAddress, vaultAddress } = values - const contract = commonLogic(values) +const setDepositDataManager: SetDepositDataManagerRoot = async (values) => { + const { provider, userAddress, managerAddress, vaultAddress, contracts, options } = values const signer = await provider.getSigner(userAddress) + + const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) + + if (isV1Version) { + const vaultContract = contracts.helpers.createVault({ + vaultAddress, + options: { + chainId: options.network, + }, + }) + const signedVaultContract = vaultContract.connect(signer) + const result = await signedVaultContract.setKeysManager(managerAddress) + + return result.hash + } + + const contract = commonLogic(values) const signedDepositDataRegistryContract = contract.connect(signer) const result = await signedDepositDataRegistryContract.setDepositDataManager(vaultAddress, managerAddress) diff --git a/src/methods/vault/transactions/setDepositDataRoot/index.ts b/src/methods/vault/transactions/setDepositDataRoot/index.ts index 215299d7..55f5fee8 100644 --- a/src/methods/vault/transactions/setDepositDataRoot/index.ts +++ b/src/methods/vault/transactions/setDepositDataRoot/index.ts @@ -4,13 +4,31 @@ import type { SetDepositDataRoot } from './types' import setDepositDataRootGas from './setDepositDataRootGas' import setDepositDataRootEncode from './setDepositDataRootEncode' +import { getVaultVersion } from '../../../../utils' -const setDepositDataRoot: SetDepositDataRoot = async (values) => { - const { provider, userAddress, vaultAddress, depositDataRoot } = values - const contract = commonLogic(values) +const setDepositDataRoot: SetDepositDataRoot = async (values) => { + const { provider, userAddress, vaultAddress, depositDataRoot, contracts, options } = values const signer = await provider.getSigner(userAddress) + + const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) + + if (isV1Version) { + const vaultContract = contracts.helpers.createVault({ + vaultAddress, + options: { + chainId: options.network, + }, + }) + + const signedVaultContract = vaultContract.connect(signer) + const result = await signedVaultContract.setValidatorsRoot(depositDataRoot) + + return result.hash + } + + const contract = commonLogic(values) const signedDepositDataRegistryContract = contract.connect(signer) const result = await signedDepositDataRegistryContract.setDepositDataRoot(vaultAddress, depositDataRoot) diff --git a/src/methods/vault/transactions/util/params/getDepositDataManagerParams.ts b/src/methods/vault/transactions/util/params/getDepositDataManagerParams.ts deleted file mode 100644 index e4752ee9..00000000 --- a/src/methods/vault/transactions/util/params/getDepositDataManagerParams.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { validateArgs } from '../../../../../utils' -import { vaultMulticall } from '../../../../../contracts' - - -export type SetDepositDataManagerParams = { - depositDataManager: string -} - -const getDepositDataManagerParams = (values: SetDepositDataManagerParams) => { - const { depositDataManager } = values - - validateArgs.address({ depositDataManager }) - - const params: Parameters[0]['request']['params'] = [ - { - method: 'setKeysManager', args: [ depositDataManager ], - }, - ] - - return params -} - - -export default getDepositDataManagerParams diff --git a/src/methods/vault/transactions/util/params/getDepositDataRootParams.ts b/src/methods/vault/transactions/util/params/getDepositDataRootParams.ts deleted file mode 100644 index 3c670749..00000000 --- a/src/methods/vault/transactions/util/params/getDepositDataRootParams.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { validateArgs } from '../../../../../utils' -import { vaultMulticall } from '../../../../../contracts' - - -export type SetDepositDataRootParams = { - depositDataRoot: string -} - -const getDepositDataRootParams = (values: SetDepositDataRootParams) => { - const { depositDataRoot } = values - - validateArgs.string({ depositDataRoot }) - - const params: Parameters[0]['request']['params'] = [ - { - method: 'setValidatorsRoot', args: [ depositDataRoot ], - }, - ] - - return params -} - - -export default getDepositDataRootParams diff --git a/src/methods/vault/transactions/util/params/index.ts b/src/methods/vault/transactions/util/params/index.ts index 8915c7d5..9fcd3975 100644 --- a/src/methods/vault/transactions/util/params/index.ts +++ b/src/methods/vault/transactions/util/params/index.ts @@ -3,9 +3,7 @@ export { default as getBlocklistParams } from './getBlocklistParams' export { default as getWhitelistParams } from './getWhitelistParams' export { default as getWhitelisterParams } from './getWhitelisterParams' export { default as getFeeRecipientParams } from './getFeeRecipientParams' -export { default as getDepositDataRootParams } from './getDepositDataRootParams' export { default as getBlocklistManagerParams } from './getBlocklistManagerParams' export { default as getValidatorsManagerParams } from './getValidatorsManagerParams' -export { default as getDepositDataManagerParams } from './getDepositDataManagerParams' export { default as getRestakeOperatorsManagerParams } from './getRestakeOperatorsManagerParams' export { default as getRestakeWithdrawalsManagerParams } from './getRestakeWithdrawalsManagerParams' From df6d5a131f2978522bbb9548260b75755dae9b94 Mon Sep 17 00:00:00 2001 From: dfkadyr Date: Wed, 9 Oct 2024 11:16:13 +0300 Subject: [PATCH 29/36] new-improves --- .../subgraph/rewardSplitters/rewardSplittersQuery.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphql/subgraph/rewardSplitters/rewardSplittersQuery.graphql b/src/graphql/subgraph/rewardSplitters/rewardSplittersQuery.graphql index 35aade8c..d7d1324d 100644 --- a/src/graphql/subgraph/rewardSplitters/rewardSplittersQuery.graphql +++ b/src/graphql/subgraph/rewardSplitters/rewardSplittersQuery.graphql @@ -3,7 +3,7 @@ query RewardSplitters($where: RewardSplitter_filter) { id owner totalShares - shareHolders(orderBy: shares, orderDirection: desc) { + shareHolders(orderBy: shares, orderDirection: desc, where: { shares_gt: 0 }) { id shares address From b558aff0c45e3f547e90f3c94acf477208ca8274 Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Mon, 14 Oct 2024 17:26:26 +0500 Subject: [PATCH 30/36] hide score percentiles --- src/graphql/backend/vault/index.ts | 3 --- .../backend/vault/scorePercentilesQuery.graphql | 7 ------- .../vault/requests/getScorePercentiles/index.ts | 14 ++++++++++---- 3 files changed, 10 insertions(+), 14 deletions(-) delete mode 100644 src/graphql/backend/vault/scorePercentilesQuery.graphql diff --git a/src/graphql/backend/vault/index.ts b/src/graphql/backend/vault/index.ts index 8eeeeb3e..94177e7b 100644 --- a/src/graphql/backend/vault/index.ts +++ b/src/graphql/backend/vault/index.ts @@ -4,8 +4,5 @@ export type { SnapshotsQueryPayload, SnapshotsQueryVariables } from './snapshots export { fetchValidatorsQuery } from './validatorsQuery.graphql' export type { ValidatorsQueryPayload, ValidatorsQueryVariables } from './validatorsQuery.graphql' -export { fetchScorePercentilesQuery } from './scorePercentilesQuery.graphql' -export type { ScorePercentilesQueryPayload, ScorePercentilesQueryVariables } from './scorePercentilesQuery.graphql' - export { submitUploadMetadataMutation } from './uploadMetadataMutation.graphql' export type { UploadMetadataMutationPayload, UploadMetadataMutationVariables } from './uploadMetadataMutation.graphql' diff --git a/src/graphql/backend/vault/scorePercentilesQuery.graphql b/src/graphql/backend/vault/scorePercentilesQuery.graphql deleted file mode 100644 index d46843ef..00000000 --- a/src/graphql/backend/vault/scorePercentilesQuery.graphql +++ /dev/null @@ -1,7 +0,0 @@ -query ScorePercentiles { - scorePercentiles { - percentile25, - percentile50, - percentile75 - } -} diff --git a/src/methods/vault/requests/getScorePercentiles/index.ts b/src/methods/vault/requests/getScorePercentiles/index.ts index e79d9794..18a34fae 100644 --- a/src/methods/vault/requests/getScorePercentiles/index.ts +++ b/src/methods/vault/requests/getScorePercentiles/index.ts @@ -13,10 +13,16 @@ type GetScorePercentilesInput = { const getScorePercentiles = (input: GetScorePercentilesInput) => { const { options } = input - return graphql.backend.vault.fetchScorePercentilesQuery({ - url: apiUrls.getBackendUrl(options), - modifyResult: (data: ScorePercentilesQueryPayload) => modifyScorePercentiles(data), - }) + // return graphql.backend.vault.fetchScorePercentilesQuery({ + // url: apiUrls.getBackendUrl(options), + // modifyResult: (data: ScorePercentilesQueryPayload) => modifyScorePercentiles(data), + // }) + + return { + percentile25: 1, + percentile50: 2, + percentile75: 3, + } } From 6a62ffa4912b406374a529ec3aeb22b89aee44de Mon Sep 17 00:00:00 2001 From: Andrey Kopylov Date: Mon, 14 Oct 2024 17:38:33 +0500 Subject: [PATCH 31/36] fix types --- src/methods/vault/requests/getScorePercentiles/index.ts | 2 +- .../requests/getScorePercentiles/modifyScorePercentiles.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/methods/vault/requests/getScorePercentiles/index.ts b/src/methods/vault/requests/getScorePercentiles/index.ts index 18a34fae..4d84c33a 100644 --- a/src/methods/vault/requests/getScorePercentiles/index.ts +++ b/src/methods/vault/requests/getScorePercentiles/index.ts @@ -1,4 +1,4 @@ -import type { ScorePercentilesQueryPayload } from '../../../../graphql/backend/vault' +// import type { ScorePercentilesQueryPayload } from '../../../../graphql/backend/vault' import { apiUrls } from '../../../../utils' import graphql from '../../../../graphql' diff --git a/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts b/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts index a3e172f1..77317633 100644 --- a/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts +++ b/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts @@ -1,8 +1,10 @@ -import type { ScorePercentilesQueryPayload } from '../../../../graphql/backend/vault' +// import type { ScorePercentilesQueryPayload } from '../../../../graphql/backend/vault' import { ModifiedScorePercentiles } from './types' -const modifyScorePercentiles = (input: ScorePercentilesQueryPayload): ModifiedScorePercentiles => { +type Input = any // ScorePercentilesQueryPayload + +const modifyScorePercentiles = (input: Input): ModifiedScorePercentiles => { const { scorePercentiles } = input return ({ From c6c8f7b1e6e80ea9f7a3b2c5737a9912eeb85711 Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Wed, 16 Oct 2024 15:19:55 +0300 Subject: [PATCH 32/36] Remove ScorePercentiles logic (#185) * remove ScorePercentiles logic * improve docs --- README.md | 34 +------------------ changelog/next-release.md | 6 ++++ src/methods/vault/index.ts | 7 ---- .../requests/getScorePercentiles/index.ts | 29 ---------------- .../modifyScorePercentiles.spec.ts | 23 ------------- .../modifyScorePercentiles.ts | 18 ---------- .../requests/getScorePercentiles/types.ts | 5 --- 7 files changed, 7 insertions(+), 115 deletions(-) delete mode 100644 src/methods/vault/requests/getScorePercentiles/index.ts delete mode 100644 src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.spec.ts delete mode 100644 src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts delete mode 100644 src/methods/vault/requests/getScorePercentiles/types.ts diff --git a/README.md b/README.md index 734d1e0b..25832908 100644 --- a/README.md +++ b/README.md @@ -98,13 +98,12 @@ const sdk = new StakeWiseSDK({ | [vault.getMaxWithdraw](#sdkvaultgetmaxwithdraw) | [osToken.getSharesFromAssets](#sdkostokengetsharesfromassets) | | | [vault.getHarvestParams](#sdkvaultgetharvestparams) | [osToken.getAssetsFromShares](#sdkostokengetassetsfromshares) | | | [vault.getStakeBalance](#sdkvaultgetstakebalance) | [osToken.getRate](#sdkostokengetrate) | | -| [vault.getScorePercentiles](#sdkvaultgetscorepercentiles) | [osToken.getConfig](#sdkostokengetconfig) | | +| [vault.getUserStats](#sdkvaultgetuserstats) | [osToken.getConfig](#sdkostokengetconfig) | | | [vault.getUserRewards](#sdkvaultgetuserrewards) | [osToken.getHealthFactor](#sdkostokengethealthfactor) | | | [vault.getWhitelist](#sdkvaultgetwhitelist) | | | | [vault.getBlocklist](#sdkvaultgetblocklist) | | | | [vault.getRewardSplitters](#sdkvaultgetrewardsplitters) | | | | [vault.getVaultStats](#sdkvaultgetvaultstats) | | | -| [vault.getUserStats](#sdkvaultgetuserstats) | | | | **Utils** | |-----------------------------------------------------| @@ -207,37 +206,6 @@ await sdk.vault.getStakerActions({ }) ``` --- -### `sdk.vault.getScorePercentiles` - -#### Description: - -This method is used to fetch information indicating the effectiveness or performance level of the vault. -The retrieved data includes percentiles corresponding to various statuses. - -#### Returns: - -```ts -type Output = { - percentile25: number - percentile50: number - percentile75: number -} -``` - -| Name | Description | -|------|---------------------------------------------------------------------------------------------------------| -| `percentile25` | Represents the value corresponding to the **lowest** status. It is associated with the color (red) | -| `percentile50` | Represents the value corresponding to the **moderate** status. It is associated with the color (orange) | -| `percentile75` | Represents the value corresponding to the **good** status. It is associated with the color (light green) | - -_For values greater than percentile75 the status corresponds to **excellent** with color (green)_ - -#### Example: - -```ts -await sdk.vault.getScorePercentiles() -``` ---- ### `sdk.vault.getUserRewards` #### Description: diff --git a/changelog/next-release.md b/changelog/next-release.md index 68b3290a..2ba119fa 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -136,3 +136,9 @@ type RemovedInput = { depositDataRoot: string } ``` + +--- + +### 14. Removed method `sdk.vault.getScorePercentiles` + +--- diff --git a/src/methods/vault/index.ts b/src/methods/vault/index.ts index 4bcbc3d7..e562b80f 100644 --- a/src/methods/vault/index.ts +++ b/src/methods/vault/index.ts @@ -12,7 +12,6 @@ import getStakeBalance from './requests/getStakeBalance' import getHarvestParams from './requests/getHarvestParams' import getStakerActions from './requests/getStakerActions' import getRewardSplitters from './requests/getRewardSplitters' -import getScorePercentiles from './requests/getScorePercentiles' import getExitQueuePositions from './requests/getExitQueuePositions' // Transactions @@ -35,12 +34,6 @@ export default { * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetexitqueuepositions */ getExitQueuePositions, - /** - * @description This method is used to fetch information indicating the effectiveness - * or performance level of the vault. The retrieved data includes percentiles corresponding to various statuses. - * @see https://github.com/stakewise/v3-sdk/?tab=readme-ov-file#sdkvaultgetscorepercentiles - */ - getScorePercentiles, /** * @description Fetch the list of created reward splitters. A reward splitter is a contract * designed to distribute vault rewards among multiple fee recipients in predefined proportions. diff --git a/src/methods/vault/requests/getScorePercentiles/index.ts b/src/methods/vault/requests/getScorePercentiles/index.ts deleted file mode 100644 index 4d84c33a..00000000 --- a/src/methods/vault/requests/getScorePercentiles/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -// import type { ScorePercentilesQueryPayload } from '../../../../graphql/backend/vault' -import { apiUrls } from '../../../../utils' -import graphql from '../../../../graphql' - -import modifyScorePercentiles from './modifyScorePercentiles' -import { ModifiedScorePercentiles } from './types' - - -type GetScorePercentilesInput = { - options: StakeWise.Options -} - -const getScorePercentiles = (input: GetScorePercentilesInput) => { - const { options } = input - - // return graphql.backend.vault.fetchScorePercentilesQuery({ - // url: apiUrls.getBackendUrl(options), - // modifyResult: (data: ScorePercentilesQueryPayload) => modifyScorePercentiles(data), - // }) - - return { - percentile25: 1, - percentile50: 2, - percentile75: 3, - } -} - - -export default getScorePercentiles diff --git a/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.spec.ts b/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.spec.ts deleted file mode 100644 index eb8d3e56..00000000 --- a/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ScorePercentilesQueryPayload } from '../../../../graphql/backend/vault' -import modifyScorePercentiles from './modifyScorePercentiles' - - -describe('modifyScorePercentiles functions', () => { - const sampleInput: ScorePercentilesQueryPayload = { - scorePercentiles: { - percentile25: '95.00', - percentile50: '97.00', - percentile75: '98.00', - }, - } - - it('should correctly modify a score percentiles', () => { - const result = modifyScorePercentiles(sampleInput) - - expect(result).toEqual({ - percentile25: 95.00, - percentile50: 97.00, - percentile75: 98.00, - }) - }) -}) diff --git a/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts b/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts deleted file mode 100644 index 77317633..00000000 --- a/src/methods/vault/requests/getScorePercentiles/modifyScorePercentiles.ts +++ /dev/null @@ -1,18 +0,0 @@ -// import type { ScorePercentilesQueryPayload } from '../../../../graphql/backend/vault' -import { ModifiedScorePercentiles } from './types' - - -type Input = any // ScorePercentilesQueryPayload - -const modifyScorePercentiles = (input: Input): ModifiedScorePercentiles => { - const { scorePercentiles } = input - - return ({ - percentile25: Number(scorePercentiles.percentile25), - percentile50: Number(scorePercentiles.percentile50), - percentile75: Number(scorePercentiles.percentile75), - }) -} - - -export default modifyScorePercentiles diff --git a/src/methods/vault/requests/getScorePercentiles/types.ts b/src/methods/vault/requests/getScorePercentiles/types.ts deleted file mode 100644 index e715de85..00000000 --- a/src/methods/vault/requests/getScorePercentiles/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type ModifiedScorePercentiles = { - percentile25: number - percentile50: number - percentile75: number -} From 0d812e64ba00241addb2440c983206b6a763108f Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Fri, 18 Oct 2024 17:37:06 +0300 Subject: [PATCH 33/36] remove duplicates (#186) * refactor checkRestakeOperatorsManagerAccess * update subgraphUrl logic --- codegen.ts | 4 ++- src/StakeWiseSDK.ts | 10 ++++++++ .../createEigenPod/checkAccess.ts | 25 ------------------- .../transactions/createEigenPod/index.ts | 3 ++- .../setEigenPodOperator/checkAccess.ts | 25 ------------------- .../transactions/setEigenPodOperator/index.ts | 3 ++- .../updateEigenPodOperator/checkAccess.ts | 25 ------------------- .../updateEigenPodOperator/index.ts | 4 ++- .../checkRestakeOperatorsManagerAccess.ts | 21 +++++++++++++++- 9 files changed, 40 insertions(+), 80 deletions(-) delete mode 100644 src/methods/vault/transactions/createEigenPod/checkAccess.ts delete mode 100644 src/methods/vault/transactions/setEigenPodOperator/checkAccess.ts delete mode 100644 src/methods/vault/transactions/updateEigenPodOperator/checkAccess.ts diff --git a/codegen.ts b/codegen.ts index cbddb575..aa5b609f 100644 --- a/codegen.ts +++ b/codegen.ts @@ -16,10 +16,12 @@ if (process.env.NETWORK === 'gnosis') { const config = configs[network] const subgraphIndex = Number(process.env.SUBGRAPH_INDEX || 0) -const subgraphUrl = Array.isArray(config.api.subgraph) +let subgraphUrl = Array.isArray(config.api.subgraph) ? config.api.subgraph[subgraphIndex] : config.api.subgraph +subgraphUrl = subgraphUrl.replace('prod', 'stage') + const urls: Record = { backend: config.api.backend, subgraph: subgraphUrl, diff --git a/src/StakeWiseSDK.ts b/src/StakeWiseSDK.ts index f7697e08..3c0c68df 100644 --- a/src/StakeWiseSDK.ts +++ b/src/StakeWiseSDK.ts @@ -44,6 +44,16 @@ class StakeWiseSDK { this.provider = provider this.contracts = contracts + if (options.endpoints?.subgraph) { + // @ts-ignore: It's better to just overwrite + this.config.api.subgraph = options.endpoints.subgraph + } + + if (options.endpoints?.api) { + // @ts-ignore: It's better to just overwrite + this.config.api.backend = options.endpoints.api + } + const argsForMethods = { options, contracts, provider } this.utils = methods.createUtils(argsForMethods) diff --git a/src/methods/vault/transactions/createEigenPod/checkAccess.ts b/src/methods/vault/transactions/createEigenPod/checkAccess.ts deleted file mode 100644 index 99a99985..00000000 --- a/src/methods/vault/transactions/createEigenPod/checkAccess.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { checkRestakeOperatorsManagerAccess } from '../util' -import type { CreateEigenPodInput as Input } from './types' - - -type Action = (props: Input) => Promise - -const checkAccess = (action: Action) => ( - async (values: Input) => { - try { - const result = await action(values) - - return result - } - catch (actionError) { - return checkRestakeOperatorsManagerAccess(values) - .then( - () => Promise.reject(actionError), - (error) => Promise.reject(error) - ) - } - } -) - - -export default checkAccess diff --git a/src/methods/vault/transactions/createEigenPod/index.ts b/src/methods/vault/transactions/createEigenPod/index.ts index 5cfb466e..004fbd3d 100644 --- a/src/methods/vault/transactions/createEigenPod/index.ts +++ b/src/methods/vault/transactions/createEigenPod/index.ts @@ -1,9 +1,10 @@ import { commonLogic } from './common' -import checkAccess from './checkAccess' import type { CreateEigenPod } from './types' import createEigenPodGas from './createEigenPodGas' import createEigenPodEncode from './createEigenPodEncode' +import { checkRestakeOperatorsManagerAccess as checkAccess } from '../util' + const createEigenPod: CreateEigenPod = async (values) => { const { provider, userAddress } = values diff --git a/src/methods/vault/transactions/setEigenPodOperator/checkAccess.ts b/src/methods/vault/transactions/setEigenPodOperator/checkAccess.ts deleted file mode 100644 index d8da67c8..00000000 --- a/src/methods/vault/transactions/setEigenPodOperator/checkAccess.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { checkRestakeOperatorsManagerAccess } from '../util' -import type { SetEigenPodOperatorInput as Input } from './types' - - -type Action = (props: Input) => Promise - -const checkAccess = (action: Action) => ( - async (values: Input) => { - try { - const result = await action(values) - - return result - } - catch (actionError) { - return checkRestakeOperatorsManagerAccess(values) - .then( - () => Promise.reject(actionError), - (error) => Promise.reject(error) - ) - } - } -) - - -export default checkAccess diff --git a/src/methods/vault/transactions/setEigenPodOperator/index.ts b/src/methods/vault/transactions/setEigenPodOperator/index.ts index 71ae815a..1824bc59 100644 --- a/src/methods/vault/transactions/setEigenPodOperator/index.ts +++ b/src/methods/vault/transactions/setEigenPodOperator/index.ts @@ -1,9 +1,10 @@ import { commonLogic } from './common' -import checkAccess from './checkAccess' import type { SetEigenPodOperator } from './types' import setEigenPodOperatorGas from './setEigenPodOperatorGas' import setEigenPodOperatorEncode from './setEigenPodOperatorEncode' +import { checkRestakeOperatorsManagerAccess as checkAccess } from '../util' + const setEigenPodOperator: SetEigenPodOperator = async (values) => { const { provider, userAddress, operatorAddress } = values diff --git a/src/methods/vault/transactions/updateEigenPodOperator/checkAccess.ts b/src/methods/vault/transactions/updateEigenPodOperator/checkAccess.ts deleted file mode 100644 index 718366af..00000000 --- a/src/methods/vault/transactions/updateEigenPodOperator/checkAccess.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { checkRestakeOperatorsManagerAccess } from '../util' -import type { UpdateEigenPodOperatorInput as Input } from './types' - - -type Action = (props: Input) => Promise - -const checkAccess = (action: Action) => ( - async (values: Input) => { - try { - const result = await action(values) - - return result - } - catch (actionError) { - return checkRestakeOperatorsManagerAccess(values) - .then( - () => Promise.reject(actionError), - (error) => Promise.reject(error) - ) - } - } -) - - -export default checkAccess diff --git a/src/methods/vault/transactions/updateEigenPodOperator/index.ts b/src/methods/vault/transactions/updateEigenPodOperator/index.ts index f675f8f1..d1246eab 100644 --- a/src/methods/vault/transactions/updateEigenPodOperator/index.ts +++ b/src/methods/vault/transactions/updateEigenPodOperator/index.ts @@ -1,8 +1,10 @@ import { commonLogic } from './common' -import checkAccess from './checkAccess' import updateEigenPodOperatorGas from './updateEigenPodOperatorGas' import updateEigenPodOperatorEncode from './updateEigenPodOperatorEncode' import type { UpdateEigenPodOperator } from './types' + +import { checkRestakeOperatorsManagerAccess as checkAccess } from '../util' + import { eigenPodOwnerMulticall } from '../../../../contracts' diff --git a/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts b/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts index cc2a7d8c..6c620f37 100644 --- a/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts +++ b/src/methods/vault/transactions/util/check/checkRestakeOperatorsManagerAccess.ts @@ -1,7 +1,9 @@ import type { CheckInput } from './types' -const checkRestakeOperatorsManagerAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { +type Action = (props: Input) => Promise + +const checkAccess = async ({ userAddress, vaultAddress, contracts }: CheckInput) => { try { const restakingVaultContract = contracts.helpers.createVault({ options: { isRestake: true }, @@ -18,5 +20,22 @@ const checkRestakeOperatorsManagerAccess = async ({ userAddress, vaultAddress, c catch {} } +const checkRestakeOperatorsManagerAccess = (action: Action) => ( + async (values: Input) => { + try { + const result = await action(values) + + return result + } + catch (actionError) { + return checkAccess(values as unknown as CheckInput) + .then( + () => Promise.reject(actionError), + (error) => Promise.reject(error) + ) + } + } +) + export default checkRestakeOperatorsManagerAccess From 95e9d4c7ad5e5356e593348275dc03d983a9eb10 Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Wed, 23 Oct 2024 16:13:29 +0300 Subject: [PATCH 34/36] Improve ltv percent logic (#193) * improve ltv percent logic * remove unused --- src/methods/osToken/helpers/getBurnAmount.ts | 5 ++-- src/methods/osToken/requests/getMaxMint.ts | 9 +++---- src/methods/vault/requests/getMaxWithdraw.ts | 9 +++---- src/utils/getValidLtvPercent.ts | 28 -------------------- src/utils/index.ts | 1 - 5 files changed, 8 insertions(+), 44 deletions(-) delete mode 100644 src/utils/getValidLtvPercent.ts diff --git a/src/methods/osToken/helpers/getBurnAmount.ts b/src/methods/osToken/helpers/getBurnAmount.ts index 85bb3168..7b9e2a99 100644 --- a/src/methods/osToken/helpers/getBurnAmount.ts +++ b/src/methods/osToken/helpers/getBurnAmount.ts @@ -1,4 +1,4 @@ -import { validateArgs, getValidLtvPercent } from '../../../utils' +import { constants, validateArgs } from '../../../utils' import { wrapAbortPromise } from '../../../modules/gql-module' @@ -23,9 +23,8 @@ const getBurnAmount = async (values: GetBurnAmountInput) => { return 0n } - const percent = await getValidLtvPercent({ vaultAddress, ltvPercent, contracts }) + const stakedWithPercent = (stakedAssets - newStakedAssets) * ltvPercent / constants.blockchain.amount1 - const stakedWithPercent = (stakedAssets - newStakedAssets) * percent / 10_000n const assetsToBurn = mintedAssets - stakedWithPercent if (assetsToBurn > 0) { diff --git a/src/methods/osToken/requests/getMaxMint.ts b/src/methods/osToken/requests/getMaxMint.ts index 91ab8b90..38eb0d63 100644 --- a/src/methods/osToken/requests/getMaxMint.ts +++ b/src/methods/osToken/requests/getMaxMint.ts @@ -1,4 +1,4 @@ -import { constants, validateArgs, getValidLtvPercent } from '../../../utils' +import { constants, validateArgs } from '../../../utils' import { wrapAbortPromise } from '../../../modules/gql-module' @@ -20,12 +20,9 @@ const getMaxMint = async (values: GetMaxMintInput) => { return 0n } - const [ avgRewardPerSecond, percent ] = await Promise.all([ - contracts.base.mintTokenController.avgRewardPerSecond(), - getValidLtvPercent({ vaultAddress, ltvPercent, contracts }), - ]) + const avgRewardPerSecond = await contracts.base.mintTokenController.avgRewardPerSecond() - const maxMintedAssets = stakedAssets * percent / 10_000n + const maxMintedAssets = stakedAssets * ltvPercent / constants.blockchain.amount1 const maxMintedAssetsHourReward = (maxMintedAssets * avgRewardPerSecond * 3600n) / constants.blockchain.amount1 const canMintAssets = maxMintedAssets - maxMintedAssetsHourReward - mintedAssets diff --git a/src/methods/vault/requests/getMaxWithdraw.ts b/src/methods/vault/requests/getMaxWithdraw.ts index 145a2566..9cbd35b7 100644 --- a/src/methods/vault/requests/getMaxWithdraw.ts +++ b/src/methods/vault/requests/getMaxWithdraw.ts @@ -1,6 +1,6 @@ import { parseEther } from 'ethers' -import { constants, validateArgs, getValidLtvPercent } from '../../../utils' +import { constants, validateArgs } from '../../../utils' import { wrapAbortPromise } from '../../../modules/gql-module' @@ -28,14 +28,11 @@ const getMaxWithdraw = async (values: GetMaxWithdrawInput) => { return 0n } - const [ avgRewardPerSecond, percent ] = await Promise.all([ - contracts.base.mintTokenController.avgRewardPerSecond(), - getValidLtvPercent({ vaultAddress, ltvPercent, contracts }), - ]) + const avgRewardPerSecond = await contracts.base.mintTokenController.avgRewardPerSecond() const secondsInHour = 60n * 60n const gap = avgRewardPerSecond * secondsInHour * mintedAssets / constants.blockchain.amount1 - const lockedAssets = (mintedAssets + gap) * 10_000n / percent + const lockedAssets = (mintedAssets + gap) * constants.blockchain.amount1 / ltvPercent const maxWithdrawAssets = stakedAssets - lockedAssets return maxWithdrawAssets > min ? maxWithdrawAssets : 0n diff --git a/src/utils/getValidLtvPercent.ts b/src/utils/getValidLtvPercent.ts deleted file mode 100644 index 4cd6cffc..00000000 --- a/src/utils/getValidLtvPercent.ts +++ /dev/null @@ -1,28 +0,0 @@ -import validateArgs from './validateArgs' -import getVaultVersion from './getVaultVersion' - - -type Input = { - ltvPercent: bigint - vaultAddress: string - contracts: StakeWise.Contracts -} - -const getValidLtvPercent = async (values: Input) => { - const { ltvPercent, vaultAddress, contracts } = values - - validateArgs.address({ vaultAddress }) - validateArgs.bigint({ ltvPercent }) - - const { isV1Version } = await getVaultVersion({ vaultAddress, contracts }) - - // in second+ version 100% ltv percent = 1 ether in wei - const percent = isV1Version - ? ltvPercent - : ltvPercent / 100000000000000n - - return percent -} - - -export default getValidLtvPercent diff --git a/src/utils/index.ts b/src/utils/index.ts index 5c7ae5d9..ea34ee7d 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -10,4 +10,3 @@ export { default as createProvider } from './createProvider' export { default as getVaultVersion } from './getVaultVersion' export { default as getNetworkTypes } from './getNetworkTypes' export { default as getVaultFactory } from './getVaultFactory' -export { default as getValidLtvPercent } from './getValidLtvPercent' From 73bdd0a3b511685fa4964521aa66bf09d6e6273d Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Wed, 23 Oct 2024 17:30:27 +0300 Subject: [PATCH 35/36] add v2 to getVaultVersion, update holesky factories, add queuedShares (#190) --- README.md | 3 +++ changelog/next-release.md | 2 ++ src/graphql/subgraph/vault/vaultQuery.graphql | 1 + src/utils/configs/holesky.ts | 12 ++++++------ src/utils/getVaultVersion.ts | 8 ++++++++ 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 25832908..3124fc0e 100644 --- a/README.md +++ b/README.md @@ -560,6 +560,7 @@ type Output = { createdAt: number feePercent: number isPrivate: boolean + isGenesis: boolean isRestake: boolean vaultAdmin: string totalAssets: string @@ -567,6 +568,7 @@ type Output = { feeRecipient: string vaultAddress: string mevRecipient: string + queuedShares: string whitelistCount: number blocklistCount: number imageUrl: string | null @@ -597,6 +599,7 @@ type Output = { | `feePercent` | Commission rate | | `isPrivate` | Whether the vault is private | | `isGenesis` | Is a stakewise vault | +| `queuedShares` | The total number of queued shares| | `isRestake` | Indicates whether the Vault is a restaking vault | | `isBlocklist` | Whether the vault has blocklist | | `vaultAdmin` | Vault administrator address | diff --git a/changelog/next-release.md b/changelog/next-release.md index 2ba119fa..e3f45257 100644 --- a/changelog/next-release.md +++ b/changelog/next-release.md @@ -10,6 +10,7 @@ type AddedOutput = { thresholdPercent: string } isGenesis: boolean + queuedShares: string } ``` @@ -17,6 +18,7 @@ type AddedOutput = { |------|-------------| | `osTokenConfig` | contains the `ltvPercent`, which is the percentage used to calculate how much a user can mint in OsToken shares, and `thresholdPercent`, which is the liquidation threshold percentage used to calculate the health factor for the OsToken position | | `isGenesis` | This vault is owned by stakewise | +| `queuedShares` | The total number of queued shares | --- ### 2. `sdk.vault.getHarvestParams` diff --git a/src/graphql/subgraph/vault/vaultQuery.graphql b/src/graphql/subgraph/vault/vaultQuery.graphql index 180bce90..2e0c972e 100644 --- a/src/graphql/subgraph/vault/vaultQuery.graphql +++ b/src/graphql/subgraph/vault/vaultQuery.graphql @@ -27,6 +27,7 @@ query Vault($address: ID!) { whitelister tokenSymbol feeRecipient + queuedShares blocklistCount whitelistCount depositDataRoot diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 22516647..3748e134 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -35,14 +35,14 @@ export default { rewardSplitterFactory: '0x2Ed24638b3aB48cF0076f19199c78A62bfEb5889', }, factories: { - vault: '0xA1424Bd00e6940A58B1232ad4160A77dD0AC3099', - erc20Vault: '0xc6e7d05B3F6e73E3A86C6deAE0Da1fce993cF833', + vault: '0x4E3D8197c2cb9bCd29e3DCeAE3670d3d5e774017', + erc20Vault: '0x1bE3Ad178d85CE1b6a7fCF5baEFe68F26541b07C', - privateVault: '0x8023518b2192FB5384DAdc596765B3dD1cdFe471', - erc20PrivateVault: '0x481f28C0D733614aF87897E43d0D52C451799592', + privateVault: '0x7a4F9912a812d932da57d73Cb5E5784B2c1cBA4A', + erc20PrivateVault: '0x3573a482D0e50f85F6B09E4DB404Ce94Da760033', - blocklistVault: '0x90a9428b8c58cA80B28aAF46B936D42e87797449', - erc20BlocklistVault: '0x82FE8C78CaE0013471179e76224ef89941bAaa75', + blocklistVault: '0x58FDD303ab66722130C01533e7A1177f2b3a2949', + erc20BlocklistVault: '0x32634dEc69D4523D2f980Be92494dC03bD4C9fce', }, special: { stakeCalculator: '0x90b82e4b3aa385b4a02b7ebc1892a4bed6b5c465', diff --git a/src/utils/getVaultVersion.ts b/src/utils/getVaultVersion.ts index 4fde5302..b344b0ab 100644 --- a/src/utils/getVaultVersion.ts +++ b/src/utils/getVaultVersion.ts @@ -10,9 +10,17 @@ const getVaultVersion = async (values: Input) => { const version = await vaultContract.version() const isV1Version = version === 1n + const isV2Version = version === 2n + + const isMoreV1 = version > 1n + const isMoreV2 = version > 2n return { + version: Number(version), isV1Version, + isV2Version, + isMoreV1, + isMoreV2, } } From 61ddf1df6a91b23a7f8c925fe6435515b0b75eff Mon Sep 17 00:00:00 2001 From: Kadyr Dzhemaledinov Date: Thu, 24 Oct 2024 15:01:59 +0300 Subject: [PATCH 36/36] update holesky & mainnet factories (#194) --- src/utils/configs/holesky.ts | 12 ++++++------ src/utils/configs/mainnet.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/utils/configs/holesky.ts b/src/utils/configs/holesky.ts index 3748e134..0b3aa3c0 100644 --- a/src/utils/configs/holesky.ts +++ b/src/utils/configs/holesky.ts @@ -35,14 +35,14 @@ export default { rewardSplitterFactory: '0x2Ed24638b3aB48cF0076f19199c78A62bfEb5889', }, factories: { - vault: '0x4E3D8197c2cb9bCd29e3DCeAE3670d3d5e774017', - erc20Vault: '0x1bE3Ad178d85CE1b6a7fCF5baEFe68F26541b07C', + vault: '0x215f4c69c3d1461c7aA38c9c73c27e10cFB0eeE4', + erc20Vault: '0x439b60d3C886e711Dad30CF23a2BbD5388febcd9', - privateVault: '0x7a4F9912a812d932da57d73Cb5E5784B2c1cBA4A', - erc20PrivateVault: '0x3573a482D0e50f85F6B09E4DB404Ce94Da760033', + privateVault: '0xedeBE792C6190Be612Cbe97F628137fAa8C36ee5', + erc20PrivateVault: '0xaC9125646185Cb58e86E77d5f402eFa3fAfAFc84', - blocklistVault: '0x58FDD303ab66722130C01533e7A1177f2b3a2949', - erc20BlocklistVault: '0x32634dEc69D4523D2f980Be92494dC03bD4C9fce', + blocklistVault: '0x5FCd8Bb2e3DDE5809b2106039B741C041bd49E4e', + erc20BlocklistVault: '0xeBe12d858E55DDc5FC5A8153dC3e117824fbf5d2', }, special: { stakeCalculator: '0x90b82e4b3aa385b4a02b7ebc1892a4bed6b5c465', diff --git a/src/utils/configs/mainnet.ts b/src/utils/configs/mainnet.ts index fb77ddd9..65706283 100644 --- a/src/utils/configs/mainnet.ts +++ b/src/utils/configs/mainnet.ts @@ -38,14 +38,14 @@ export default { rewardSplitterFactory: '0x256aF27ce81282A0491A5361172c1Db08f6cC5F8', }, factories: { - vault: '0xfaa05900019f6E465086bcE16Bb3F06992715D53', - erc20Vault: '0x7a4F9912a812d932da57d73Cb5E5784B2c1cBA4A', + vault: '0xe9F3E6115fEd87F36bf10c8C111FB7b20B27bA0f', + erc20Vault: '0x8750594B33516232e751C8B9C350a660cD5f1BB8', - privateVault: '0xb7832C9e93e54661354C8B88F3Ce7c0915f4C896', - erc20PrivateVault: '0x58FDD303ab66722130C01533e7A1177f2b3a2949', + privateVault: '0xf3C94c38b4def16a20715b90918052c34AdaF3B8', + erc20PrivateVault: '0x5518052f2d898f062ee59964004A560F24E2eE7d', - blocklistVault: '0x4E3D8197c2cb9bCd29e3DCeAE3670d3d5e774017', - erc20BlocklistVault: '0x1bE3Ad178d85CE1b6a7fCF5baEFe68F26541b07C', + blocklistVault: '0x2a0335fb13Cbf86A76A7f9D9d038389788667960', + erc20BlocklistVault: '0x5f31eD13eBF81B67a9f9498F3d1D2Da553058988', }, special: { stakeCalculator: '0x29c708d94521af2c88402858049bd33e4606a3a2',