diff --git a/biome.json b/biome.json index 117325fa..92ce4fe5 100644 --- a/biome.json +++ b/biome.json @@ -40,7 +40,8 @@ }, "suspicious": { "useGetterReturn": "off", - "noAssignInExpressions": "off" + "noAssignInExpressions": "off", + "noFallthroughSwitchClause": "off" } } } diff --git a/packages/blue-api-sdk/package.json b/packages/blue-api-sdk/package.json index 41a6cc5e..05b6dd09 100644 --- a/packages/blue-api-sdk/package.json +++ b/packages/blue-api-sdk/package.json @@ -2,6 +2,7 @@ "name": "@morpho-org/blue-api-sdk", "version": "2.0.0-alpha.6", "author": "Morpho Association ", + "type": "module", "main": "src/index.ts", "files": [ "lib" @@ -31,6 +32,13 @@ }, "publishConfig": { "main": "lib/index.js", + "types": "lib/index.d.ts", + "exports": { + ".": { + "types": "./lib/index.d.ts", + "default": "./lib/index.js" + } + }, "access": "public" } } diff --git a/packages/blue-api-sdk/src/converter.ts b/packages/blue-api-sdk/src/converter.ts index cbb1e2c0..aa7b75cd 100644 --- a/packages/blue-api-sdk/src/converter.ts +++ b/packages/blue-api-sdk/src/converter.ts @@ -1,7 +1,7 @@ import { AccrualPosition, AccrualVault, - Address, + type Address, Market, MarketConfig, MathLib, @@ -15,7 +15,7 @@ import { } from "@morpho-org/blue-sdk"; import { Time, isDefined } from "@morpho-org/morpho-ts"; -import { +import type { Chain as BlueApiChain, Market as BlueApiMarket, MarketPosition as BlueApiMarketPosition, @@ -28,7 +28,7 @@ import { VaultAllocation as BlueApiVaultAllocation, VaultState as BlueApiVaultState, Maybe, -} from "./types"; +} from "./types.js"; export interface PartialBlueApiTokenPrice { priceUsd?: BlueApiToken["priceUsd"]; @@ -316,7 +316,7 @@ export class BlueSdkConverter { return new AccrualVault( { ...state, - config: this.getVaultConfig(dto), + ...this.getVaultConfig(dto), fee: this.options.parseNumber(state.fee, 18), pendingOwner: state.pendingOwner ?? "0x0000000000000000000000000000000000000000", diff --git a/packages/blue-api-sdk/src/index.ts b/packages/blue-api-sdk/src/index.ts index c771e327..808f2cb8 100644 --- a/packages/blue-api-sdk/src/index.ts +++ b/packages/blue-api-sdk/src/index.ts @@ -1,4 +1,4 @@ -export * from "./types"; -export * from "./converter"; -export * from "./warnings"; -export * from "./cache"; +export * from "./types.js"; +export * from "./converter.js"; +export * from "./warnings.js"; +export * from "./cache.js"; diff --git a/packages/blue-sdk-ethers/package.json b/packages/blue-sdk-ethers/package.json index 346767cb..d38bf566 100644 --- a/packages/blue-sdk-ethers/package.json +++ b/packages/blue-sdk-ethers/package.json @@ -3,6 +3,7 @@ "version": "2.0.0-alpha.6", "author": "Morpho Association ", "license": "MIT", + "type": "module", "main": "src/index.ts", "files": [ "lib" @@ -46,6 +47,13 @@ }, "publishConfig": { "main": "lib/index.js", + "types": "lib/index.d.ts", + "exports": { + ".": { + "types": "./lib/index.d.ts", + "default": "./lib/index.js" + } + }, "access": "public" } } diff --git a/packages/blue-sdk-ethers/src/fetch/Vault.ts b/packages/blue-sdk-ethers/src/fetch/Vault.ts index f2d1c260..17e2d67a 100644 --- a/packages/blue-sdk-ethers/src/fetch/Vault.ts +++ b/packages/blue-sdk-ethers/src/fetch/Vault.ts @@ -1,19 +1,19 @@ -import { Provider, resolveProperties } from "ethers"; +import { type Provider, resolveProperties } from "ethers"; import { MetaMorpho__factory, PublicAllocator__factory } from "ethers-types"; import { AccrualVault, - Address, + type Address, ChainUtils, - MarketId, + type MarketId, Vault, - VaultConfig, - VaultPublicAllocatorConfig, + type VaultConfig, + type VaultPublicAllocatorConfig, getChainAddresses, } from "@morpho-org/blue-sdk"; -import { FetchOptions } from "../types"; -import { fetchVaultConfig } from "./VaultConfig"; -import { fetchVaultMarketAllocation } from "./VaultMarketAllocation"; +import type { FetchOptions } from "../types.js"; +import { fetchVaultConfig } from "./VaultConfig.js"; +import { fetchVaultMarketAllocation } from "./VaultMarketAllocation.js"; export async function fetchVault( address: Address, diff --git a/packages/blue-sdk-ethers/test/e2e/Vault.test.ts b/packages/blue-sdk-ethers/test/e2e/Vault.test.ts index 1175bb8b..1b896c6c 100644 --- a/packages/blue-sdk-ethers/test/e2e/Vault.test.ts +++ b/packages/blue-sdk-ethers/test/e2e/Vault.test.ts @@ -3,10 +3,10 @@ import { ZeroAddress } from "ethers"; import { MetaMorpho__factory, PublicAllocator__factory } from "ethers-types"; import { ethers } from "hardhat"; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import type { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { setNextBlockTimestamp } from "@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time"; -import { ChainId, MarketId, addresses } from "@morpho-org/blue-sdk"; +import { ChainId, type MarketId, addresses } from "@morpho-org/blue-sdk"; import { setUp } from "@morpho-org/morpho-test"; import { Vault } from "../../src/augment/Vault"; diff --git a/packages/blue-sdk-viem-bundler/src/helpers/operations.ts b/packages/blue-sdk-viem-bundler/src/helpers/operations.ts index 369060b6..884785a5 100644 --- a/packages/blue-sdk-viem-bundler/src/helpers/operations.ts +++ b/packages/blue-sdk-viem-bundler/src/helpers/operations.ts @@ -1,8 +1,8 @@ import { - Address, + type Address, DEFAULT_SLIPPAGE_TOLERANCE, DEFAULT_SUPPLY_TARGET_UTILIZATION, - MarketId, + type MarketId, MarketUtils, MathLib, NATIVE_ADDRESS, @@ -13,13 +13,13 @@ import { permissionedWrapperTokens, } from "@morpho-org/blue-sdk"; import { - Erc20Operations, - MaybeDraft, - Operation, - Operations, - PublicAllocatorOptions, - SimulationResult, - SimulationState, + type Erc20Operations, + type MaybeDraft, + type Operation, + type Operations, + type PublicAllocatorOptions, + type SimulationResult, + type SimulationState, handleOperation, handleOperations, produceImmutable, @@ -29,7 +29,7 @@ import { entries, getLast, getValue, keys } from "@morpho-org/morpho-ts"; import { maxUint256 } from "viem"; import { BundlerErrors } from "../errors"; -import { +import type { BundlerOperation, CallbackBundlerOperation, InputBundlerOperation, @@ -273,13 +273,13 @@ export const populateSubBundle = ( const borrowedAssets = mainOperation.type === "Blue_Borrow" - ? mainOperation.args.assets ?? - market.toBorrowAssets(mainOperation.args.shares) + ? (mainOperation.args.assets ?? + market.toBorrowAssets(mainOperation.args.shares)) : 0n; const withdrawnAssets = mainOperation.type === "Blue_Withdraw" - ? mainOperation.args.assets ?? - market.toSupplyAssets(mainOperation.args.shares) + ? (mainOperation.args.assets ?? + market.toSupplyAssets(mainOperation.args.shares)) : 0n; const newTotalSupplyAssets = market.totalSupplyAssets - withdrawnAssets; @@ -673,7 +673,7 @@ export const finalizeBundle = ( token = startData.getMarket(operation.args.id).config.collateralToken; break; case "MetaMorpho_Withdraw": - token = startData.getVault(operation.address).config.asset; + token = startData.getVault(operation.address).asset; break; default: return; @@ -836,7 +836,9 @@ export const populateBundle = ( ); return subBundleOperations; - } catch (error: any) { + } catch (error) { + if (!(error instanceof Error)) throw error; + throw new BundlerErrors.Bundle(error, index, inputOperation, steps); } }); diff --git a/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/deposit.ts b/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/deposit.ts index 1f5c8219..64f39caa 100644 --- a/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/deposit.ts +++ b/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/deposit.ts @@ -61,7 +61,7 @@ export const handleMetaMorphoDepositOperation: OperationHandler< { type: "Erc20_Transfer", sender: address, - address: vault.config.asset, + address: vault.asset, args: { amount: assets, from: sender, diff --git a/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/reallocate.ts b/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/reallocate.ts index 625bce41..0dda9980 100644 --- a/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/reallocate.ts +++ b/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/reallocate.ts @@ -1,4 +1,4 @@ -import { maxUint256, zeroAddress } from "viem"; +import { maxUint256 } from "viem"; import { MathLib } from "@morpho-org/blue-sdk"; @@ -38,8 +38,6 @@ export const handleMetaMorphoReallocateOperation: OperationHandler< handleBlueOperation( { type: "Blue_Withdraw", - // Bypass balance check because the vault's token balance is not stored - // and it is checked with invariant `totalWithdrawn == totalSupplied`. sender: address, args: { id, @@ -71,9 +69,7 @@ export const handleMetaMorphoReallocateOperation: OperationHandler< handleBlueOperation( { type: "Blue_Supply", - // Bypass balance check because the vault's token balance is not stored - // and it is checked with invariant `totalWithdrawn == totalSupplied`. - sender: zeroAddress, + sender: address, args: { id, assets: suppliedAssets, @@ -93,4 +89,12 @@ export const handleMetaMorphoReallocateOperation: OperationHandler< totalSupplied, totalWithdrawn, ); + + // Update totalAssets as soon as the vault is interacted with (onchain, it's a dynamic view function). + // But do not accrue vault fee! + const accruedVault = data + .tryGetAccrualVault(address) + ?.accrueInterest(data.block.timestamp); + if (accruedVault != null) + data.getVault(address).totalAssets = accruedVault.totalAssets; }; diff --git a/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/withdraw.ts b/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/withdraw.ts index e37786fc..9d74e780 100644 --- a/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/withdraw.ts +++ b/packages/blue-sdk-viem-simulation/src/handlers/metamorpho/withdraw.ts @@ -116,7 +116,7 @@ export const handleMetaMorphoWithdrawOperation: OperationHandler< { type: "Erc20_Transfer", sender: address, - address: vault.config.asset, + address: vault.asset, args: { amount: assets, from: address, diff --git a/packages/blue-sdk-viem-simulation/test/e2e/handlers/blue/accrueInterest.test.ts b/packages/blue-sdk-viem-simulation/test/e2e/handlers/blue/accrueInterest.test.ts index e641c980..cac02d43 100644 --- a/packages/blue-sdk-viem-simulation/test/e2e/handlers/blue/accrueInterest.test.ts +++ b/packages/blue-sdk-viem-simulation/test/e2e/handlers/blue/accrueInterest.test.ts @@ -66,13 +66,10 @@ describe("Blue_AccrueInterest", () => { abi: blueAbi, functionName: "accrueInterest", args: [ - { - collateralToken: usdc_wstEth.collateralToken, - loanToken: usdc_wstEth.loanToken, - oracle: usdc_wstEth.oracle, - irm: usdc_wstEth.irm, - lltv: usdc_wstEth.lltv, - }, + usdc_wstEth as Pick< + typeof usdc_wstEth, + "collateralToken" | "loanToken" | "oracle" | "irm" | "lltv" + >, ], }); diff --git a/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/publicReallocate.test.ts b/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/publicReallocate.test.ts index a32527d6..19c00a06 100644 --- a/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/publicReallocate.test.ts +++ b/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/publicReallocate.test.ts @@ -1,112 +1,147 @@ -import { expect } from "chai"; -import { parseEther, parseUnits } from "ethers"; -import { MetaMorpho__factory, PublicAllocator__factory } from "ethers-types"; -import { ethers } from "hardhat"; -import _omit from "lodash/omit"; - -import type { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { setNextBlockTimestamp } from "@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time"; - -import { BlueService, ChainService, getLast } from "@morpho-org/blue-core-sdk"; -import { MetaMorphoService } from "@morpho-org/blue-metamorpho-sdk"; -import { ChainId, addresses } from "@morpho-org/blue-sdk"; -import { MAINNET_MARKETS } from "@morpho-org/blue-sdk/lib/tests/mocks/markets"; -import { mine, setUp } from "@morpho-org/morpho-test"; - -import { SimulationService, simulateOperations } from "../../../../src"; -import { steakUsdc } from "../../fixtures"; +import { ChainId, NATIVE_ADDRESS, addresses } from "@morpho-org/blue-sdk"; +import { metaMorphoAbi, publicAllocatorAbi } from "@morpho-org/blue-sdk-viem"; +import { markets, vaults } from "@morpho-org/morpho-test"; +import { getLast } from "@morpho-org/morpho-ts"; +import { renderHook, waitFor } from "@morpho-org/test"; +import { parseEther, parseUnits } from "viem"; +import { describe, expect } from "vitest"; +import { + type MinimalBlock, + simulateOperations, + useSimulationState, +} from "../../../../src/index.js"; +import { test } from "../../setup.js"; + +const { publicAllocator } = addresses[ChainId.EthMainnet]; +const { usdc_wstEth, usdc_idle, usdc_wbtc, usdc_wbIB01 } = + markets[ChainId.EthMainnet]; +const { steakUsdc } = vaults[ChainId.EthMainnet]; describe("MetaMorpho_PublicReallocate", () => { - let signer: SignerWithAddress; - - let simulationService: SimulationService; - - setUp(async () => { - signer = (await ethers.getSigners())[0]!; - }); - - afterEach(async () => { - simulationService?.chainService.close(); - simulationService?.metaMorphoService.blueService.close(); - simulationService?.metaMorphoService.close(); - simulationService?.close(); - }); - - test("should simulate public reallocation accurately", async () => { - const vault = MetaMorpho__factory.connect(steakUsdc.address, signer); - - const owner = await ethers.getImpersonatedSigner(await vault.owner()); - - const publicAllocator = PublicAllocator__factory.connect( - addresses[ChainId.EthMainnet].publicAllocator, - owner, - ); + test("should simulate public reallocation accurately", async ({ + wagmi: { config, client }, + }) => { + const owner = await client.readContract({ + address: steakUsdc.address, + abi: metaMorphoAbi, + functionName: "owner", + }); const fee = parseEther("0.005"); const assets = parseUnits("1000", 6); - await publicAllocator.setFee(steakUsdc.address, fee); - await publicAllocator.setFlowCaps(steakUsdc.address, [ - { - id: MAINNET_MARKETS.usdc_wstEth.id, - caps: { - maxIn: 0n, - maxOut: assets, - }, - }, - { - id: MAINNET_MARKETS.usdc_idle.id, - caps: { - maxIn: assets, - maxOut: 0n, - }, - }, - ]); - - simulationService = new SimulationService( - new MetaMorphoService( - new BlueService(new ChainService(signer), { - users: [signer.address], + await client.writeContract({ + account: owner, + address: publicAllocator, + abi: publicAllocatorAbi, + functionName: "setFee", + args: [steakUsdc.address, fee], + }); + await client.writeContract({ + account: owner, + address: publicAllocator, + abi: publicAllocatorAbi, + functionName: "setFlowCaps", + args: [ + steakUsdc.address, + [ + { + id: usdc_wstEth.id, + caps: { + maxIn: 0n, + maxOut: assets, + }, + }, + { + id: usdc_idle.id, + caps: { + maxIn: assets, + maxOut: 0n, + }, + }, + ], + ], + }); + + const block = await client.getBlock(); + + const { result, rerender } = await renderHook( + config, + (block: MinimalBlock) => + useSimulationState({ + marketIds: [ + usdc_wstEth.id, + usdc_idle.id, + usdc_wbtc.id, + usdc_wbIB01.id, + ], + users: [client.account.address, steakUsdc.address], + tokens: [NATIVE_ADDRESS, steakUsdc.asset, steakUsdc.address], + vaults: [steakUsdc.address], + block, + accrueInterest: false, }), - { vaults: [steakUsdc.address] }, - ), + { initialProps: block }, ); - const { value: dataBefore } = await simulationService.data; + await waitFor(() => expect(result.current.isFetchingAny).toBeFalsy()); + + const dataBefore = result.current.data!; + + dataBefore.block.number += 1n; + dataBefore.block.timestamp += 1n; const steps = simulateOperations( [ { type: "MetaMorpho_PublicReallocate", - sender: signer.address, + sender: client.account.address, address: steakUsdc.address, args: { - withdrawals: [{ id: MAINNET_MARKETS.usdc_wstEth.id, assets }], - supplyMarketId: MAINNET_MARKETS.usdc_idle.id, + withdrawals: [{ id: usdc_wstEth.id, assets }], + supplyMarketId: usdc_idle.id, }, }, ], dataBefore, ); - expect(steps.length).to.equal(2); + expect(steps.length).toBe(2); - await setNextBlockTimestamp(dataBefore.timestamp); - await publicAllocator - .connect(signer) - .reallocateTo( + await client.setNextBlockTimestamp({ + timestamp: dataBefore.block.timestamp, + }); + await client.writeContractWait({ + address: publicAllocator, + abi: publicAllocatorAbi, + functionName: "reallocateTo", + args: [ steakUsdc.address, - [{ marketParams: MAINNET_MARKETS.usdc_wstEth, amount: assets }], - MAINNET_MARKETS.usdc_idle, - { value: fee }, - ); - await mine(0); + [ + { + marketParams: usdc_wstEth as Pick< + typeof usdc_wstEth, + "collateralToken" | "loanToken" | "oracle" | "irm" | "lltv" + >, + amount: assets, + }, + ], + usdc_idle as Pick< + typeof usdc_idle, + "collateralToken" | "loanToken" | "oracle" | "irm" | "lltv" + >, + ], + value: fee, + }); - const { value: data } = await simulationService.data; + await rerender(await client.getBlock()); + await waitFor(() => expect(result.current.isFetchingAny).toBeFalsy()); - const expected = getLast(steps); - expected.blockNumber += 1n; + // Hotfix: anvil's effective gas price is not zero for some reason. + result.current.data!.holdings[client.account.address]![ + NATIVE_ADDRESS + ]!.balance = expect.any(BigInt); - expect(_omit(data, "cacheId")).to.eql(_omit(expected, "cacheId")); + expect(result.current.data).toStrictEqual(getLast(steps)); }); }); diff --git a/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/reallocate.test.ts b/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/reallocate.test.ts index c0ba151a..4e435670 100644 --- a/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/reallocate.test.ts +++ b/packages/blue-sdk-viem-simulation/test/e2e/handlers/metamorpho/reallocate.test.ts @@ -1,93 +1,108 @@ -import { expect } from "chai"; -import { MaxUint256, parseUnits } from "ethers"; -import { MetaMorpho__factory } from "ethers-types"; -import { ethers } from "hardhat"; -import _omit from "lodash/omit"; - -import type { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { setNextBlockTimestamp } from "@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time"; - -import { BlueService, ChainService, getLast } from "@morpho-org/blue-core-sdk"; -import { MetaMorphoService } from "@morpho-org/blue-metamorpho-sdk"; -import { MAINNET_MARKETS } from "@morpho-org/blue-sdk/lib/tests/mocks/markets"; -import { mine, setUp } from "@morpho-org/morpho-test"; - -import { SimulationService, simulateOperations } from "../../../../src"; -import { steakUsdc } from "../../fixtures"; +import { ChainId } from "@morpho-org/blue-sdk"; +import { metaMorphoAbi } from "@morpho-org/blue-sdk-viem"; +import { markets, vaults } from "@morpho-org/morpho-test"; +import { getLast } from "@morpho-org/morpho-ts"; +import { renderHook, waitFor } from "@morpho-org/test"; +import { maxUint256, parseUnits } from "viem"; +import { describe, expect } from "vitest"; +import { + type MinimalBlock, + simulateOperations, + useSimulationState, +} from "../../../../src/index.js"; +import { test } from "../../setup.js"; + +const { usdc_wstEth, usdc_idle, usdc_wbtc, usdc_wbIB01 } = + markets[ChainId.EthMainnet]; +const { steakUsdc } = vaults[ChainId.EthMainnet]; describe("MetaMorpho_Reallocate", () => { - let signer: SignerWithAddress; - - let simulationService: SimulationService; - - setUp(async () => { - signer = (await ethers.getSigners())[0]!; - }); - - afterEach(async () => { - simulationService?.chainService.close(); - simulationService?.metaMorphoService.blueService.close(); - simulationService?.metaMorphoService.close(); - simulationService?.close(); - }); - - test("should simulate reallocation accurately", async () => { - simulationService = new SimulationService( - new MetaMorphoService( - new BlueService(new ChainService(signer), { - users: [signer.address], + test("should simulate reallocation accurately", async ({ + wagmi: { config, client }, + }) => { + const block = await client.getBlock(); + + const { result, rerender } = await renderHook( + config, + (block: MinimalBlock) => + useSimulationState({ + marketIds: [ + usdc_wstEth.id, + usdc_idle.id, + usdc_wbtc.id, + usdc_wbIB01.id, + ], + users: [client.account.address, steakUsdc.address], + tokens: [steakUsdc.asset, steakUsdc.address], + vaults: [steakUsdc.address], + block, + accrueInterest: false, }), - { vaults: [steakUsdc.address] }, - ), + { initialProps: block }, ); - const { value: dataBefore } = await simulationService.data; + await waitFor(() => expect(result.current.isFetchingAny).toBeFalsy()); + + const dataBefore = result.current.data!; - const vault = MetaMorpho__factory.connect(steakUsdc.address, signer); + dataBefore.block.number += 1n; + dataBefore.block.timestamp += 1n; - const owner = await ethers.getImpersonatedSigner(await vault.owner()); + const owner = await client.readContract({ + address: steakUsdc.address, + abi: metaMorphoAbi, + functionName: "owner", + }); const assets = - dataBefore.getAccrualPosition( - steakUsdc.address, - MAINNET_MARKETS.usdc_wstEth.id, - ).supplyAssets - parseUnits("1000", 6); + dataBefore.getAccrualPosition(steakUsdc.address, usdc_wstEth.id) + .supplyAssets - parseUnits("1000", 6); const steps = simulateOperations( [ { type: "MetaMorpho_Reallocate", - sender: owner.address, + sender: owner, address: steakUsdc.address, args: [ { - id: MAINNET_MARKETS.usdc_wstEth.id, + id: usdc_wstEth.id, assets, }, - { id: MAINNET_MARKETS.usdc_idle.id, assets: MaxUint256 }, + { id: usdc_idle.id, assets: maxUint256 }, ], }, ], dataBefore, ); - expect(steps.length).to.equal(2); - - await setNextBlockTimestamp(dataBefore.timestamp); - await vault.connect(owner).reallocate([ - { - marketParams: MAINNET_MARKETS.usdc_wstEth, - assets, - }, - { marketParams: MAINNET_MARKETS.usdc_idle, assets: MaxUint256 }, - ]); - await mine(0); - - const { value: data } = await simulationService.data; + expect(steps.length).toBe(2); + + await client.setNextBlockTimestamp({ + timestamp: dataBefore.block.timestamp, + }); + await client.writeContractWait({ + account: owner, + address: steakUsdc.address, + abi: metaMorphoAbi, + functionName: "reallocate", + args: [ + [ + { + marketParams: usdc_wstEth as Pick< + typeof usdc_wstEth, + "collateralToken" | "loanToken" | "oracle" | "irm" | "lltv" + >, + assets, + }, + { marketParams: usdc_idle, assets: maxUint256 }, + ], + ], + }); - const expected = getLast(steps); - expected.blockNumber += 1n; + await rerender(await client.getBlock()); + await waitFor(() => expect(result.current.isFetchingAny).toBeFalsy()); - expect(_omit(data, "cacheId")).to.eql(_omit(expected, "cacheId")); + expect(result.current.data).toStrictEqual(getLast(steps)); }); }); diff --git a/packages/blue-sdk-viem-simulation/test/e2e/hooks/useSimulationState.test.ts b/packages/blue-sdk-viem-simulation/test/e2e/hooks/useSimulationState.test.ts index a6315c8b..db53bee7 100644 --- a/packages/blue-sdk-viem-simulation/test/e2e/hooks/useSimulationState.test.ts +++ b/packages/blue-sdk-viem-simulation/test/e2e/hooks/useSimulationState.test.ts @@ -317,7 +317,6 @@ describe("useSimulationState", () => { await client.setNextBlockTimestamp({ timestamp: data1.block.timestamp + 1n, }); - await client.setBalance({ address: morpho, value: BigInt(1e18) }); await client.writeContractWait({ account: morpho, address: usdc, diff --git a/packages/blue-sdk-viem-simulation/test/unit/SimulationState.test.ts b/packages/blue-sdk-viem-simulation/test/unit/SimulationState.test.ts index a14b9903..25955af1 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/SimulationState.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/SimulationState.test.ts @@ -132,7 +132,7 @@ describe("SimulationState", () => { test("should calculate reallocatable liquidity on idle market with target 0%", () => { // We create a state with only a vault that has all the liquidity in the idle market. - const idleMarketTokenA = new Market({ + const idleMarketA = new Market({ config: MarketConfig.idle(tokenA), totalBorrowAssets: 0n, totalBorrowShares: 0n, @@ -143,13 +143,15 @@ describe("SimulationState", () => { price: parseUnits("3", 18), }); - const blueFixture = { + const customFixture = new SimulationState({ + chainId: ChainId.EthMainnet, + block: { number: 1n, timestamp }, global: { feeRecipient: randomAddress(), }, users: {}, markets: { - [idleMarketTokenA.id]: idleMarketTokenA, + [idleMarketA.id]: idleMarketA, [marketA1.id]: marketA1, }, tokens: { @@ -162,9 +164,9 @@ describe("SimulationState", () => { }, positions: { [vaultA.address]: { - [idleMarketTokenA.id]: new Position({ + [idleMarketA.id]: new Position({ user: vaultA.address, - marketId: idleMarketTokenA.id, + marketId: idleMarketA.id, borrowShares: 0n, collateral: 0n, supplyShares: parseUnits("10000", 6 + 6), @@ -178,12 +180,14 @@ describe("SimulationState", () => { }), }, }, - holdings: {}, - }; - const metaMorphoFixture = { + holdings: { + [vaultA.address]: { + [tokenA]: dataFixture.getHolding(vaultA.address, tokenA), + }, + }, vaults: { [vaultA.address]: new Vault({ - config: vaultA, + ...vaultA, curator: randomAddress(), fee: 0n, feeRecipient: randomAddress(), @@ -193,8 +197,8 @@ describe("SimulationState", () => { pendingOwner: randomAddress(), pendingTimelock: { validAt: 0n, value: 0n }, skimRecipient: randomAddress(), - supplyQueue: [idleMarketTokenA.id, marketA1.id], - withdrawQueue: [idleMarketTokenA.id, marketA1.id], + supplyQueue: [idleMarketA.id, marketA1.id], + withdrawQueue: [idleMarketA.id, marketA1.id], timelock: 0n, publicAllocatorConfig: { fee: 0n, @@ -208,16 +212,16 @@ describe("SimulationState", () => { }, vaultMarketConfigs: { [vaultA.address]: { - [idleMarketTokenA.id]: { + [idleMarketA.id]: { vault: vaultA.address, - marketId: idleMarketTokenA.id, + marketId: idleMarketA.id, cap: parseUnits("10000", 6), pendingCap: { validAt: 0n, value: 0n }, removableAt: 0n, enabled: true, publicAllocatorConfig: { vault: vaultA.address, - marketId: idleMarketTokenA.id, + marketId: idleMarketA.id, maxIn: parseUnits("10000", 6), maxOut: parseUnits("10000", 6), }, @@ -239,15 +243,9 @@ describe("SimulationState", () => { }, }, vaultUsers: {}, - }; - - const dataFixture = new SimulationState({ - chainId: ChainId.EthMainnet, - block: { number: 1n, timestamp }, - ...blueFixture, - ...metaMorphoFixture, }); - const { withdrawals, data } = dataFixture.getMarketPublicReallocations( + + const { withdrawals, data } = customFixture.getMarketPublicReallocations( marketA1.id, { defaultMaxWithdrawalUtilization: 0n, @@ -257,17 +255,17 @@ describe("SimulationState", () => { expect(withdrawals).toEqual([ { vault: vaultA.address, - id: idleMarketTokenA.id, + id: idleMarketA.id, assets: parseUnits("10000", 6), }, ]); - expect(data.getMarket(idleMarketTokenA.id).liquidity).toEqual( - blueFixture.markets[idleMarketTokenA.id]!.totalSupplyAssets - + expect(data.getMarket(idleMarketA.id).liquidity).toEqual( + customFixture.markets[idleMarketA.id]!.totalSupplyAssets - parseUnits("10000", 6), ); expect(data.getMarket(marketA1.id).liquidity).toEqual( - dataFixture.getMarket(marketA1.id).liquidity + parseUnits("10000", 6), + customFixture.getMarket(marketA1.id).liquidity + parseUnits("10000", 6), ); }); diff --git a/packages/blue-sdk-viem-simulation/test/unit/fixtures.ts b/packages/blue-sdk-viem-simulation/test/unit/fixtures.ts index 5aad125a..13f6f873 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/fixtures.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/fixtures.ts @@ -17,7 +17,7 @@ import { import { randomMarket, randomVault } from "@morpho-org/morpho-test"; import { randomAddress } from "@morpho-org/test"; -import { SimulationState } from "../../src"; +import { SimulationState } from "../../src/index.js"; export const timestamp = 12345n; @@ -1131,7 +1131,682 @@ export const blueFixture = { }, user: userC, token: vaultC.address, - balance: parseEther("15000"), + balance: parseEther("30000"), + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + }, + [vaultA.address]: { + [NATIVE_ADDRESS]: new Holding({ + erc20Allowances: { + morpho: maxUint256, + permit2: maxUint256, + bundler: maxUint256, + }, + user: vaultA.address, + token: NATIVE_ADDRESS, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [tokenA]: new Holding({ + erc20Allowances: { + morpho: maxUint256, + permit2: maxUint256, + bundler: maxUint256, + }, + user: vaultA.address, + token: tokenA, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [tokenB]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: tokenB, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketA1.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: marketA1.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketA2.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: marketA2.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketB1.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: marketB1.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketB2.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: marketB2.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [vaultA.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: vaultA.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + [vaultB.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: vaultB.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + [vaultC.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultA.address, + token: vaultC.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + }, + [vaultB.address]: { + [NATIVE_ADDRESS]: new Holding({ + erc20Allowances: { + morpho: maxUint256, + permit2: maxUint256, + bundler: maxUint256, + }, + user: vaultB.address, + token: NATIVE_ADDRESS, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [tokenA]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: tokenA, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [tokenB]: new Holding({ + erc20Allowances: { + morpho: maxUint256, + permit2: maxUint256, + bundler: maxUint256, + }, + user: vaultB.address, + token: tokenB, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketA1.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: marketA1.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketA2.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: marketA2.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketB1.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: marketB1.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketB2.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: marketB2.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [vaultA.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: vaultA.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + [vaultB.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: vaultB.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + [vaultC.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultB.address, + token: vaultC.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + }, + [vaultC.address]: { + [NATIVE_ADDRESS]: new Holding({ + erc20Allowances: { + morpho: maxUint256, + permit2: maxUint256, + bundler: maxUint256, + }, + user: vaultC.address, + token: NATIVE_ADDRESS, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [tokenA]: new Holding({ + erc20Allowances: { + morpho: maxUint256, + permit2: maxUint256, + bundler: maxUint256, + }, + user: vaultC.address, + token: tokenA, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [tokenB]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultC.address, + token: tokenB, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketA1.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: maxUint256, + permit2: maxUint256, + bundler: maxUint256, + }, + user: vaultC.address, + token: marketA1.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketA2.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultC.address, + token: marketA2.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketB1.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultC.address, + token: marketB1.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [marketB2.config.collateralToken]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultC.address, + token: marketB2.config.collateralToken, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + }), + [vaultA.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultC.address, + token: vaultA.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + [vaultB.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultC.address, + token: vaultB.address, + balance: 0n, + permit2Allowances: { + morpho: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + bundler: { + amount: 0n, + expiration: 0n, + nonce: 0n, + }, + }, + erc2612Nonce: 0n, + }), + [vaultC.address]: new Holding({ + erc20Allowances: { + morpho: 0n, + permit2: 0n, + bundler: 0n, + }, + user: vaultC.address, + token: vaultC.address, + balance: 0n, permit2Allowances: { morpho: { amount: 0n, @@ -1153,7 +1828,7 @@ export const blueFixture = { export const metaMorphoFixture = { vaults: { [vaultA.address]: new Vault({ - config: vaultA, + ...vaultA, curator: randomAddress(), fee: 0n, feeRecipient: randomAddress(), @@ -1176,7 +1851,7 @@ export const metaMorphoFixture = { lastTotalAssets: parseUnits("1400", 6), }), [vaultB.address]: new Vault({ - config: vaultB, + ...vaultB, curator: randomAddress(), fee: 0n, feeRecipient: randomAddress(), @@ -1194,7 +1869,7 @@ export const metaMorphoFixture = { lastTotalAssets: 0n, }), [vaultC.address]: new Vault({ - config: vaultC, + ...vaultC, curator: randomAddress(), fee: 0n, feeRecipient: randomAddress(), diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/accrueInterest.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/accrueInterest.test.ts index a3b979e9..d4f8278e 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/accrueInterest.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/accrueInterest.test.ts @@ -27,7 +27,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixtureCopy); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id] = marketData.accrueInterest( dataFixtureCopy.block.timestamp, ); diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/borrow.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/borrow.test.ts index cdb4088c..bdcc9769 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/borrow.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/borrow.test.ts @@ -35,7 +35,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.getMarket(marketA1.id).totalBorrowAssets += assets; expected.getMarket(marketA1.id).totalBorrowShares += shares; expected.getPosition(userB, marketA1.id).borrowShares += shares; @@ -60,7 +59,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.getMarket(marketA1.id).totalBorrowAssets += assets; expected.getMarket(marketA1.id).totalBorrowShares += shares; expected.getPosition(userB, marketA1.id).borrowShares += shares; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/repay.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/repay.test.ts index 8e12f653..22ca3e64 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/repay.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/repay.test.ts @@ -44,7 +44,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalBorrowAssets -= assets; expected.markets[marketA1.id]!.totalBorrowShares -= shares; expected.positions[userB]![marketA1.id]!.borrowShares -= shares; @@ -69,7 +68,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalBorrowAssets -= assets; expected.markets[marketA1.id]!.totalBorrowShares -= shares; expected.positions[userB]![marketA1.id]!.borrowShares -= shares; @@ -177,7 +175,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalBorrowAssets -= assets; expected.markets[marketA1.id]!.totalBorrowShares -= shares; expected.positions[userC]![marketA1.id]!.borrowShares -= shares; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/setAuthorization.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/setAuthorization.test.ts index ae15af17..d8364d5d 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/setAuthorization.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/setAuthorization.test.ts @@ -18,7 +18,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.users[userA]!.isBundlerAuthorized = true; expect(result).toEqual(expected); diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supply.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supply.test.ts index 32b05fe9..39cd920e 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supply.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supply.test.ts @@ -42,7 +42,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets += assets; expected.markets[marketA1.id]!.totalSupplyShares += shares; expected.positions[userA]![marketA1.id]!.supplyShares += shares; @@ -67,7 +66,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets += assets; expected.markets[marketA1.id]!.totalSupplyShares += shares; expected.positions[userA]![marketA1.id]!.supplyShares += shares; @@ -156,7 +154,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA2.id]!.totalSupplyAssets -= assets; expected.markets[marketA2.id]!.totalSupplyShares -= shares; expected.positions[userA]![marketA2.id]!.supplyShares -= shares; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supplyCollateral.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supplyCollateral.test.ts index 7d11641e..639de98c 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supplyCollateral.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/supplyCollateral.test.ts @@ -42,7 +42,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.positions[userA]![marketA1.id]!.collateral += assets; expected.holdings[userB]![marketA1.config.collateralToken]!.balance -= assets; @@ -123,7 +122,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA3.id]!.totalBorrowAssets += collateral; expected.markets[marketA3.id]!.totalBorrowShares += borrowShares; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdraw.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdraw.test.ts index 10c05ad5..4124f800 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdraw.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdraw.test.ts @@ -36,7 +36,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets -= assets; expected.markets[marketA1.id]!.totalSupplyShares -= shares; expected.positions[userA]![marketA1.id]!.supplyShares -= shares; @@ -61,7 +60,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets -= assets; expected.markets[marketA1.id]!.totalSupplyShares -= shares; expected.positions[userA]![marketA1.id]!.supplyShares -= shares; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdrawCollateral.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdrawCollateral.test.ts index 898d4122..d9e4f4a5 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdrawCollateral.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/blue/withdrawCollateral.test.ts @@ -32,7 +32,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.positions[userB]![marketA1.id]!.collateral -= assets; expected.holdings[userA]![marketA1.config.collateralToken]!.balance += assets; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/approve.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/approve.test.ts index 7d463084..55b13d1a 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/approve.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/approve.test.ts @@ -36,7 +36,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userB]![tokenA]!.erc20Allowances.morpho = 1n; expect(result).toEqual(expected); @@ -57,7 +56,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenB]!.erc20Allowances.permit2 = 1n; expect(result).toEqual(expected); @@ -78,7 +76,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenB]!.erc20Allowances.bundler = 1n; expect(result).toEqual(expected); @@ -99,7 +96,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.vaultUsers[vaultB.address]![userB]!.allowance = 1n; expect(result).toEqual(expected); diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit.test.ts index 2a5a444a..14a20722 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit.test.ts @@ -30,7 +30,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userB]![tokenA]!.erc20Allowances.morpho = 2n; expected.holdings[userB]![tokenA]!.erc2612Nonce = 1n; @@ -53,7 +52,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.erc20Allowances.bundler = 2n; expected.holdings[userA]![tokenA]!.erc2612Nonce = 1n; @@ -76,7 +74,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.vaultUsers[vaultA.address]![userB]!.allowance = 1n; expected.holdings[userB]![tokenA]!.erc2612Nonce = 1n; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit2.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit2.test.ts index 0935f742..fe9ce75b 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit2.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/permit2.test.ts @@ -28,7 +28,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userB]![tokenA]!.permit2Allowances.morpho.amount = 2n; expected.holdings[userB]![tokenA]!.permit2Allowances.morpho.expiration = 5n; expected.holdings[userB]![tokenA]!.permit2Allowances.morpho.nonce = 2n; @@ -53,7 +52,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.permit2Allowances.bundler.amount = 2n; expected.holdings[userA]![tokenA]!.permit2Allowances.bundler.expiration = 5n; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer.test.ts index 7d5196bd..4f848cc6 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer.test.ts @@ -29,7 +29,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.balance += amount; expected.holdings[userB]![tokenA]!.balance -= amount; @@ -52,7 +51,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.balance += amount; expected.holdings[userB]![tokenA]!.balance -= amount; expected.holdings[userB]![tokenA]!.erc20Allowances.morpho -= amount; @@ -76,7 +74,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.balance += amount; expected.holdings[userB]![tokenA]!.balance -= amount; expected.holdings[userB]![tokenA]!.erc20Allowances.permit2 -= amount; @@ -100,7 +97,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.balance += amount; expected.holdings[userB]![tokenA]!.balance -= amount; expected.holdings[userB]![tokenA]!.erc20Allowances.bundler -= amount; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer2.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer2.test.ts index fb4c0e9e..4c792b93 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer2.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/transfer2.test.ts @@ -33,7 +33,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.balance += amount; expected.holdings[userB]![tokenA]!.balance -= amount; expected.holdings[userB]![tokenA]!.erc20Allowances.permit2 -= amount; @@ -59,7 +58,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.holdings[userA]![tokenA]!.balance += amount; expected.holdings[userB]![tokenA]!.balance -= amount; expected.holdings[userB]![tokenA]!.erc20Allowances.permit2 -= amount; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/unwrap.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/unwrap.test.ts index bd807395..da360e7c 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/unwrap.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/unwrap.test.ts @@ -29,7 +29,6 @@ describe(type, () => { ); const expected = _.cloneDeep(wrapFixtures); - // expected.cacheId = expect.any(String); expected.holdings[userB]![tokenB]!.balance -= amount; expected.holdings[userB]![tokenA]!.balance += parseUnits("1", 6); diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/wrap.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/wrap.test.ts index 32ba6750..b3ed9cfc 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/wrap.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/erc20/wrap.test.ts @@ -29,7 +29,6 @@ describe(type, () => { ); const expected = _.cloneDeep(wrapFixtures); - // expected.cacheId = expect.any(String); expected.holdings[userB]![tokenA]!.balance -= amount; expected.holdings[userB]![tokenB]!.balance += parseUnits("1", 18); diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/deposit.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/deposit.test.ts index 783b5332..eac8e557 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/deposit.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/deposit.test.ts @@ -40,7 +40,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets += assets; expected.markets[marketA1.id]!.totalSupplyShares += supplyShares; expected.positions[vaultA.address]![marketA1.id]!.supplyShares += @@ -48,6 +47,8 @@ describe(type, () => { expected.vaultUsers[vaultA.address]![userB]!.allowance -= assets; expected.holdings[userB]![tokenA]!.balance -= assets; + expected.holdings[vaultA.address]![tokenA]!.erc20Allowances.morpho -= + assets; const vaultData = expected.vaults[vaultA.address]!; vaultData.totalAssets += assets; @@ -78,7 +79,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets += assets; expected.markets[marketA1.id]!.totalSupplyShares += supplyShares; expected.positions[vaultA.address]![marketA1.id]!.supplyShares += @@ -86,6 +86,8 @@ describe(type, () => { expected.vaultUsers[vaultA.address]![userB]!.allowance -= assets; expected.holdings[userB]![tokenA]!.balance -= assets; + expected.holdings[vaultA.address]![tokenA]!.erc20Allowances.morpho -= + assets; const vaultData = expected.vaults[vaultA.address]!; vaultData.totalAssets += assets; @@ -118,7 +120,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets += parseUnits("10", 6); expected.markets[marketA1.id]!.totalSupplyShares += supplyShares1; expected.positions[vaultA.address]![marketA1.id]!.supplyShares += @@ -131,6 +132,8 @@ describe(type, () => { expected.vaultUsers[vaultA.address]![userB]!.allowance -= assets; expected.holdings[userB]![tokenA]!.balance -= assets; + expected.holdings[vaultA.address]![tokenA]!.erc20Allowances.morpho -= + assets; const vaultData = expected.vaults[vaultA.address]!; vaultData.totalAssets += assets; @@ -162,7 +165,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets += parseUnits("10", 6); expected.markets[marketA1.id]!.totalSupplyShares += supplyShares1; expected.positions[vaultA.address]![marketA1.id]!.supplyShares += @@ -175,6 +177,8 @@ describe(type, () => { expected.vaultUsers[vaultA.address]![userB]!.allowance -= assets; expected.holdings[userB]![tokenA]!.balance -= assets; + expected.holdings[vaultA.address]![tokenA]!.erc20Allowances.morpho -= + assets; const vaultData = expected.vaults[vaultA.address]!; vaultData.totalAssets += assets; diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/publicReallocate.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/publicReallocate.test.ts index 16b09e5c..da8cd21b 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/publicReallocate.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/publicReallocate.test.ts @@ -12,6 +12,7 @@ import { dataFixture, marketA1, marketA2, + tokenA, userB, vaultA, } from "../../fixtures.js"; @@ -42,7 +43,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.positions[vaultA.address]![marketA1.id]!.supplyShares = parseUnits( "960", 6 + 6, @@ -62,6 +62,9 @@ describe(type, () => { expected.vaults[vaultA.address]!.publicAllocatorConfig!.accruedFee += parseEther("0.005"); + expected.holdings[vaultA.address]![tokenA]!.erc20Allowances.morpho -= + assets; + expected.vaultMarketConfigs[vaultA.address]![marketA1.id]! .publicAllocatorConfig!.maxIn += assets; expected.vaultMarketConfigs[vaultA.address]![marketA1.id]! diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/reallocate.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/reallocate.test.ts index 556f0589..7322d52f 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/reallocate.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/reallocate.test.ts @@ -12,6 +12,7 @@ import { marketA1, marketA2, marketB1, + tokenA, userB, vaultA, vaultB, @@ -41,7 +42,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.positions[vaultA.address]![marketA1.id]!.supplyShares = parseUnits( "950", 6 + 6, @@ -51,6 +51,9 @@ describe(type, () => { 6 + 6, ); + expected.holdings[vaultA.address]![tokenA]!.erc20Allowances.morpho -= + parseUnits("50", 6); + expected.markets[marketA1.id]!.totalSupplyAssets -= parseUnits("50", 6); expected.markets[marketA1.id]!.totalSupplyShares -= parseUnits("50", 6 + 6); diff --git a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/withdraw.test.ts b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/withdraw.test.ts index 909ad634..d88fff34 100644 --- a/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/withdraw.test.ts +++ b/packages/blue-sdk-viem-simulation/test/unit/handlers/metamorpho/withdraw.test.ts @@ -42,7 +42,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA2.id]!.totalSupplyAssets -= assets; expected.markets[marketA2.id]!.totalSupplyShares -= supplyShares; expected.positions[vaultA.address]![marketA2.id]!.supplyShares -= @@ -80,7 +79,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA2.id]!.totalSupplyAssets -= assets; expected.markets[marketA2.id]!.totalSupplyShares -= supplyShares; expected.positions[vaultA.address]![marketA2.id]!.supplyShares -= @@ -120,7 +118,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets -= parseUnits("30", 6); expected.markets[marketA1.id]!.totalSupplyShares -= supplyShares1; expected.positions[vaultA.address]![marketA1.id]!.supplyShares -= @@ -165,7 +162,6 @@ describe(type, () => { ); const expected = _.cloneDeep(dataFixture); - // expected.cacheId = expect.any(String); expected.markets[marketA1.id]!.totalSupplyAssets -= parseUnits("30", 6); expected.markets[marketA1.id]!.totalSupplyShares -= supplyShares1; expected.positions[vaultA.address]![marketA1.id]!.supplyShares -= diff --git a/packages/blue-sdk-viem/src/fetch/Vault.ts b/packages/blue-sdk-viem/src/fetch/Vault.ts index 55c5f4d6..71916b0e 100644 --- a/packages/blue-sdk-viem/src/fetch/Vault.ts +++ b/packages/blue-sdk-viem/src/fetch/Vault.ts @@ -58,7 +58,7 @@ export async function fetchVault( }); return new Vault({ - config: new VaultConfig({ ...config, address }, parameters.chainId), + ...new VaultConfig({ ...config, address }, parameters.chainId), owner, curator, guardian, @@ -257,7 +257,7 @@ export async function fetchVault( ], ); return new Vault({ - config, + ...config, owner, curator, guardian, diff --git a/packages/blue-sdk-viem/test/Market.test.ts b/packages/blue-sdk-viem/test/Market.test.ts index 024c402d..3eed4f41 100644 --- a/packages/blue-sdk-viem/test/Market.test.ts +++ b/packages/blue-sdk-viem/test/Market.test.ts @@ -61,14 +61,14 @@ describe("augment/Market", () => { irm: randomAddress(), }); - await client.setBalance({ address: owner, value: BigInt(1e18) }); - await client.setCode({ address: config.irm, bytecode: (await client.getCode({ address: adaptiveCurveIrm, }))!, }); + + await client.setBalance({ address: owner, value: BigInt(1e18) }); await client.writeContract({ account: owner, address: morpho, diff --git a/packages/blue-sdk-viem/test/Vault.test.ts b/packages/blue-sdk-viem/test/Vault.test.ts index 490f3d14..d59c0d46 100644 --- a/packages/blue-sdk-viem/test/Vault.test.ts +++ b/packages/blue-sdk-viem/test/Vault.test.ts @@ -19,7 +19,6 @@ describe("augment/Vault", () => { }); await client.setBalance({ address: owner, value: BigInt(1e18) }); - await client.writeContract({ account: owner, address: steakUsdc.address, @@ -27,7 +26,6 @@ describe("augment/Vault", () => { functionName: "setIsAllocator", args: [addresses[ChainId.EthMainnet].publicAllocator, true], }); - await client.writeContract({ account: owner, address: addresses[ChainId.EthMainnet].publicAllocator, @@ -37,7 +35,7 @@ describe("augment/Vault", () => { }); const expectedData = new Vault({ - config: steakUsdc, + ...steakUsdc, curator: zeroAddress, fee: 50000000000000000n, feeRecipient: "0x255c7705e8BB334DfCae438197f7C4297988085a", diff --git a/packages/blue-sdk-viem/test/VaultMarketConfig.test.ts b/packages/blue-sdk-viem/test/VaultMarketConfig.test.ts index 6939af36..d68fc668 100644 --- a/packages/blue-sdk-viem/test/VaultMarketConfig.test.ts +++ b/packages/blue-sdk-viem/test/VaultMarketConfig.test.ts @@ -23,7 +23,6 @@ describe("augment/VaultMarketConfig", () => { }); await client.setBalance({ address: owner, value: BigInt(1e18) }); - await client.writeContract({ account: owner, address: steakUsdc.address, @@ -31,7 +30,6 @@ describe("augment/VaultMarketConfig", () => { functionName: "setIsAllocator", args: [addresses[ChainId.EthMainnet].publicAllocator, true], }); - await client.writeContract({ account: owner, address: addresses[ChainId.EthMainnet].publicAllocator, @@ -39,7 +37,6 @@ describe("augment/VaultMarketConfig", () => { functionName: "setFee", args: [steakUsdc.address, 1n], }); - await client.writeContract({ account: owner, address: addresses[ChainId.EthMainnet].publicAllocator, diff --git a/packages/blue-sdk/src/token/VaultToken.ts b/packages/blue-sdk/src/token/VaultToken.ts index b85a2e53..8b84a734 100644 --- a/packages/blue-sdk/src/token/VaultToken.ts +++ b/packages/blue-sdk/src/token/VaultToken.ts @@ -1,29 +1,46 @@ import type { RoundingDirection } from "../math/index.js"; +import type { Address } from "../types.js"; import type { InputVaultConfig } from "../vault/VaultConfig.js"; import { VaultUtils } from "../vault/VaultUtils.js"; import { WrappedToken } from "./WrappedToken.js"; -export class VaultToken extends WrappedToken { - public decimalsOffset: bigint; - public totalAssets: bigint; +export interface InputVaultToken { + totalAssets: bigint; + totalSupply: bigint; +} + +export class VaultToken extends WrappedToken implements InputVaultToken { + public readonly asset: Address; + public readonly decimalsOffset: bigint; + + /** + * The ERC4626 vault's total supply of shares. + */ public totalSupply: bigint; + /** + * The ERC4626 vault's total assets. + */ + public totalAssets: bigint; + constructor( config: InputVaultConfig, - { totalAssets, totalSupply }: { totalAssets: bigint; totalSupply: bigint }, + { totalAssets, totalSupply }: InputVaultToken, ) { super(config, config.asset); + this.asset = config.asset; + this.totalAssets = totalAssets; this.totalSupply = totalSupply; this.decimalsOffset = BigInt(config.decimalsOffset); } - protected _wrap(amount: bigint, rounding: RoundingDirection) { - return VaultUtils.toShares(amount, this, this, rounding); + protected _wrap(amount: bigint, rounding?: RoundingDirection) { + return VaultUtils.toShares(amount, this, rounding); } - protected _unwrap(amount: bigint, rounding: RoundingDirection) { - return VaultUtils.toAssets(amount, this, this, rounding); + protected _unwrap(amount: bigint, rounding?: RoundingDirection) { + return VaultUtils.toAssets(amount, this, rounding); } } diff --git a/packages/blue-sdk/src/vault/Vault.ts b/packages/blue-sdk/src/vault/Vault.ts index 6889d183..af5096d8 100644 --- a/packages/blue-sdk/src/vault/Vault.ts +++ b/packages/blue-sdk/src/vault/Vault.ts @@ -3,12 +3,11 @@ import { MathLib, type RoundingDirection } from "../math/index.js"; import { VaultToken } from "../token/index.js"; import type { Address, BigIntish, MarketId } from "../types.js"; -import type { VaultConfig } from "./VaultConfig.js"; +import type { InputVaultConfig } from "./VaultConfig.js"; import { type InputVaultMarketAllocation, VaultMarketAllocation, } from "./VaultMarketAllocation.js"; -import { VaultUtils } from "./VaultUtils.js"; export interface Pending { value: T; @@ -30,8 +29,7 @@ export interface VaultPublicAllocatorConfig { accruedFee: bigint; } -export interface InputVault { - config: VaultConfig; +export interface InputVault extends InputVaultConfig { curator: Address; owner: Address; guardian: Address; @@ -51,11 +49,6 @@ export interface InputVault { } export class Vault extends VaultToken implements InputVault { - /** - * The MetaMorpho vault's config. - */ - public readonly config: VaultConfig; - /** * The MetaMorpho vault's owner address. */ @@ -108,14 +101,6 @@ export class Vault extends VaultToken implements InputVault { */ public withdrawQueue: MarketId[]; - /** - * The ERC4626 vault's total supply of shares. - */ - public totalSupply: bigint; - /** - * The ERC4626 vault's total assets. - */ - public totalAssets: bigint; /** * The MetaMorpho vault's last total assets used to calculate performance fees. */ @@ -124,10 +109,9 @@ export class Vault extends VaultToken implements InputVault { /** * The MetaMorpho vault's public allocator configuration. */ - publicAllocatorConfig?: VaultPublicAllocatorConfig; + public publicAllocatorConfig?: VaultPublicAllocatorConfig; constructor({ - config, curator, owner, guardian, @@ -144,10 +128,10 @@ export class Vault extends VaultToken implements InputVault { totalSupply, totalAssets, lastTotalAssets, + ...config }: InputVault) { super(config, { totalAssets, totalSupply }); - this.config = config; this.curator = curator; this.owner = owner; this.guardian = guardian; @@ -163,16 +147,10 @@ export class Vault extends VaultToken implements InputVault { this.timelock = timelock; this.supplyQueue = supplyQueue; this.withdrawQueue = withdrawQueue; - this.totalSupply = totalSupply; - this.totalAssets = totalAssets; this.lastTotalAssets = lastTotalAssets; this.publicAllocatorConfig = publicAllocatorConfig; } - get asset() { - return this.config.asset; - } - /** * The amount of interest in assets accrued since the last interaction with the vault. */ @@ -181,11 +159,11 @@ export class Vault extends VaultToken implements InputVault { } public toAssets(shares: bigint, rounding?: RoundingDirection) { - return VaultUtils.toAssets(shares, this, this.config, rounding); + return this._unwrap(shares, rounding); } public toShares(assets: bigint, rounding?: RoundingDirection) { - return VaultUtils.toShares(assets, this, this.config, rounding); + return this._wrap(assets, rounding); } } @@ -264,10 +242,12 @@ export class AccrualVault extends Vault implements InputAccrualVault { * The vault's liquidity directly available from allocated markets. */ get liquidity() { - return Array.from(this.allocations.values()).reduce( - (total, { position }) => total + position.withdrawCapacityLimit.value, - 0n, - ); + return this.allocations + .values() + .reduce( + (total, { position }) => total + position.withdrawCapacityLimit.value, + 0n, + ); } /** @@ -277,11 +257,13 @@ export class AccrualVault extends Vault implements InputAccrualVault { if (this.totalAssets === 0n) return 0n; return ( - Array.from(this.allocations.values()).reduce( - (total, { position }) => - total + position.market.supplyApy * position.supplyAssets, - 0n, - ) / this.totalAssets + this.allocations + .values() + .reduce( + (total, { position }) => + total + position.market.supplyApy * position.supplyAssets, + 0n, + ) / this.totalAssets ); } @@ -302,17 +284,19 @@ export class AccrualVault extends Vault implements InputAccrualVault { } public getDepositCapacityLimit(assets: bigint): CapacityLimit { - const suppliable = Array.from(this.allocations.values()).reduce( - (total, { config: { cap }, position: { marketId, supplyAssets } }) => - MathLib.min( - total + - (this.supplyQueue.includes(marketId) - ? MathLib.zeroFloorSub(cap, supplyAssets) - : 0n), - MathLib.MAX_UINT_256, - ), - 0n, - ); + const suppliable = this.allocations + .values() + .reduce( + (total, { config: { cap }, position: { marketId, supplyAssets } }) => + MathLib.min( + total + + (this.supplyQueue.includes(marketId) + ? MathLib.zeroFloorSub(cap, supplyAssets) + : 0n), + MathLib.MAX_UINT_256, + ), + 0n, + ); if (assets > suppliable) return { @@ -349,10 +333,13 @@ export class AccrualVault extends Vault implements InputAccrualVault { public accrueInterest(timestamp: BigIntish) { const vault = new AccrualVault( this, - Array.from(this.allocations.values(), ({ config, position }) => ({ - config, - position: position.accrueInterest(timestamp), - })), + this.allocations + .values() + .map(({ config, position }) => ({ + config, + position: position.accrueInterest(timestamp), + })) + .toArray(), ); const feeAssets = MathLib.wMulDown(vault.totalInterest, vault.fee); diff --git a/packages/blue-sdk/src/vault/VaultConfig.ts b/packages/blue-sdk/src/vault/VaultConfig.ts index 0258892a..1f68de60 100644 --- a/packages/blue-sdk/src/vault/VaultConfig.ts +++ b/packages/blue-sdk/src/vault/VaultConfig.ts @@ -6,7 +6,6 @@ export interface InputVaultConfig { address: Address; decimals: BigIntish; decimalsOffset: BigIntish; - // TODO: make this not immutable (move to Vault) symbol: string; name: string; asset: Address; diff --git a/packages/blue-sdk/src/vault/VaultUtils.ts b/packages/blue-sdk/src/vault/VaultUtils.ts index 82b6e0d4..837d05e7 100644 --- a/packages/blue-sdk/src/vault/VaultUtils.ts +++ b/packages/blue-sdk/src/vault/VaultUtils.ts @@ -13,11 +13,12 @@ export namespace VaultUtils { { totalAssets, totalSupply, + decimalsOffset, }: { totalAssets: BigIntish; totalSupply: BigIntish; + decimalsOffset: BigIntish; }, - { decimalsOffset }: { decimalsOffset: BigIntish }, rounding: RoundingDirection = "Down", ) { return MathLib.mulDiv( @@ -33,11 +34,12 @@ export namespace VaultUtils { { totalAssets, totalSupply, + decimalsOffset, }: { totalAssets: BigIntish; totalSupply: BigIntish; + decimalsOffset: BigIntish; }, - { decimalsOffset }: { decimalsOffset: BigIntish }, rounding: RoundingDirection = "Up", ) { return MathLib.mulDiv( diff --git a/packages/test/package.json b/packages/test/package.json index af9f3ebd..b414432c 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -21,10 +21,12 @@ "@tanstack/react-query": "^5.59.0", "@testing-library/dom": "^10.4.0", "@testing-library/react": "^16.0.1", + "@types/lodash.kebabcase": "^4.1.9", "@types/node": "^22.7.4", "@types/react": "^18.3.1", "@types/react-dom": "^18.3.0", "@wagmi/core": "^2.13.8", + "lodash.kebabcase": "^4.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", "typescript": "^5.6.2", diff --git a/packages/test/src/anvil.ts b/packages/test/src/anvil.ts index b70bba96..fc98cd1e 100644 --- a/packages/test/src/anvil.ts +++ b/packages/test/src/anvil.ts @@ -1,4 +1,5 @@ import { spawn } from "node:child_process"; +import _kebabCase from "lodash.kebabcase"; import { http, type Abi, @@ -132,6 +133,10 @@ export interface AnvilArgs { * The gas price. */ gasPrice?: number | bigint | undefined; + /** + * Disable minimum priority fee to set the gas price to zero. + */ + disableMinPriorityFee?: boolean | undefined; /** * The EVM hardfork to use. */ @@ -274,18 +279,18 @@ function toArgs(obj: AnvilArgs) { return Object.entries(obj).flatMap(([key, value]) => { if (value === undefined) return []; - if (Array.isArray(value)) return [toFlagCase(key), value.join(",")]; + if (Array.isArray(value)) return [`--${_kebabCase(key)}`, value.join(",")]; if (typeof value === "object" && value !== null) { return Object.entries(value).flatMap(([subKey, subValue]) => { if (subValue === undefined) return []; - const flag = toFlagCase(`${key}.${subKey}`); + const flag = `--${_kebabCase(`${key}.${subKey}`)}`; return [flag, Array.isArray(subValue) ? subValue.join(",") : subValue]; }); } - const flag = toFlagCase(key); + const flag = `--${_kebabCase(key)}`; if (value === false) return [flag, "false"]; if (value === true) return [flag]; @@ -297,25 +302,6 @@ function toArgs(obj: AnvilArgs) { }); } -/** Converts to a --flag-case string. */ -const toFlagCase = (str: string) => { - const keys = []; - - for (let i = 0; i < str.split(".").length; i++) { - const key = str.split(".")[i]; - if (!key) continue; - - keys.push( - key - .replace(/\s+/g, "-") - .replace(/([a-z])([A-Z])/g, `$1-$2`) - .toLowerCase(), - ); - } - - return `--${keys.join(".")}`; -}; - export const spawnAnvil = async ( args: AnvilArgs, basePort: number, diff --git a/packages/test/src/vitest.ts b/packages/test/src/vitest.ts index d15cafe2..8f9436e1 100644 --- a/packages/test/src/vitest.ts +++ b/packages/test/src/vitest.ts @@ -73,6 +73,7 @@ export const createAnvilWagmiTest = ( parameters.gasPrice ??= 0n; parameters.blockBaseFeePerGas ??= 0n; + parameters.disableMinPriorityFee ??= true; let port = 0; diff --git a/vitest.workspace.ts b/vitest.workspace.ts index fc79eec7..16057f3a 100644 --- a/vitest.workspace.ts +++ b/vitest.workspace.ts @@ -17,6 +17,7 @@ export default defineWorkspace([ test: { name: "blue-sdk-viem", include: ["packages/blue-sdk-viem/**/*.test.ts"], + testTimeout: 30_000, }, }, { diff --git a/yarn.lock b/yarn.lock index eb0a4f89..e09e4de5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3311,10 +3311,12 @@ __metadata: "@tanstack/react-query": "npm:^5.59.0" "@testing-library/dom": "npm:^10.4.0" "@testing-library/react": "npm:^16.0.1" + "@types/lodash.kebabcase": "npm:^4.1.9" "@types/node": "npm:^22.7.4" "@types/react": "npm:^18.3.1" "@types/react-dom": "npm:^18.3.0" "@wagmi/core": "npm:^2.13.8" + lodash.kebabcase: "npm:^4.1.1" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" typescript: "npm:^5.6.2" @@ -5298,6 +5300,15 @@ __metadata: languageName: node linkType: hard +"@types/lodash.kebabcase@npm:^4.1.9": + version: 4.1.9 + resolution: "@types/lodash.kebabcase@npm:4.1.9" + dependencies: + "@types/lodash": "npm:*" + checksum: 10c0/f00fbfb891fd1883e3fab2286fa2b23a013550b3498013c8c8c5e3ed437f52543afe8e8dc899b4f3317bab8db403bb281de863274a6fa12f088667378fd7b475 + languageName: node + linkType: hard + "@types/lodash.merge@npm:^4": version: 4.6.9 resolution: "@types/lodash.merge@npm:4.6.9" @@ -10807,6 +10818,13 @@ __metadata: languageName: node linkType: hard +"lodash.kebabcase@npm:^4.1.1": + version: 4.1.1 + resolution: "lodash.kebabcase@npm:4.1.1" + checksum: 10c0/da5d8f41dbb5bc723d4bf9203d5096ca8da804d6aec3d2b56457156ba6c8d999ff448d347ebd97490da853cb36696ea4da09a431499f1ee8deb17b094ecf4e33 + languageName: node + linkType: hard + "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2"