From 70647ddc48339e37711b1e85fd5917836f5fcd28 Mon Sep 17 00:00:00 2001 From: Jean-Grimal <83286814+Jean-Grimal@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:43:37 +0100 Subject: [PATCH] fix: apply suggestions --- .../examples/whitelistedMarkets.ts | 4 +- packages/liquidation-sdk-viem/src/index.ts | 2 + .../src/positions/getters.ts | 6 +- .../src/positions/index.ts | 1 + .../src/preLiquidation/helpers.ts | 53 +--------------- .../src/preLiquidation/index.ts | 3 + .../src/preLiquidation/types.ts | 60 +++++++++++++++++-- .../test/examples/preLiquidation.test.ts | 4 +- .../test/preLiquidationSetup.ts | 31 ---------- packages/liquidation-sdk-viem/test/setup.ts | 15 +++++ 10 files changed, 84 insertions(+), 95 deletions(-) create mode 100644 packages/liquidation-sdk-viem/src/positions/index.ts create mode 100644 packages/liquidation-sdk-viem/src/preLiquidation/index.ts delete mode 100644 packages/liquidation-sdk-viem/test/preLiquidationSetup.ts diff --git a/packages/liquidation-sdk-viem/examples/whitelistedMarkets.ts b/packages/liquidation-sdk-viem/examples/whitelistedMarkets.ts index 6270a1ee..9e9111dc 100644 --- a/packages/liquidation-sdk-viem/examples/whitelistedMarkets.ts +++ b/packages/liquidation-sdk-viem/examples/whitelistedMarkets.ts @@ -16,6 +16,8 @@ import { LiquidationEncoder, Pendle, apiSdk, + getPositions, + getRepayDataPreLiquidation, mainnetAddresses, } from "@morpho-org/liquidation-sdk-viem"; import { @@ -37,8 +39,6 @@ import { readContract, sendTransaction, } from "viem/actions"; -import { getPositions } from "../src/positions/getters"; -import { getRepayDataPreLiquidation } from "../src/preLiquidation/helpers"; const converter = new BlueSdkConverter({ parseAddress: safeGetAddress, diff --git a/packages/liquidation-sdk-viem/src/index.ts b/packages/liquidation-sdk-viem/src/index.ts index b644b481..ccf32a44 100644 --- a/packages/liquidation-sdk-viem/src/index.ts +++ b/packages/liquidation-sdk-viem/src/index.ts @@ -4,6 +4,8 @@ export * from "./api/index.js"; export * from "./addresses.js"; export * from "./flashbots.js"; export * from "./LiquidationEncoder.js"; +export * from "./preLiquidation/index.js"; export * from "./swap/index.js"; export * from "./tokens/index.js"; export * from "./abis.js"; +export * from "./positions/index.js"; diff --git a/packages/liquidation-sdk-viem/src/positions/getters.ts b/packages/liquidation-sdk-viem/src/positions/getters.ts index 992b95dc..149c2e4a 100644 --- a/packages/liquidation-sdk-viem/src/positions/getters.ts +++ b/packages/liquidation-sdk-viem/src/positions/getters.ts @@ -1,10 +1,12 @@ import type { ChainId, MarketId } from "@morpho-org/blue-sdk"; import { fetchAccrualPosition } from "@morpho-org/blue-sdk-viem"; +import { + PreLiquidationPosition, + getPreLiquidablePositions, +} from "@morpho-org/liquidation-sdk-viem"; import { Time } from "@morpho-org/morpho-ts"; import type { Account, Chain, Client, Transport } from "viem"; import { apiSdk } from "../api"; -import { getPreLiquidablePositions } from "../preLiquidation/positionGetters"; -import { PreLiquidationPosition } from "../preLiquidation/types"; export async function getPositions( client: Client, diff --git a/packages/liquidation-sdk-viem/src/positions/index.ts b/packages/liquidation-sdk-viem/src/positions/index.ts new file mode 100644 index 00000000..e9636360 --- /dev/null +++ b/packages/liquidation-sdk-viem/src/positions/index.ts @@ -0,0 +1 @@ +export * from "./getters.js"; diff --git a/packages/liquidation-sdk-viem/src/preLiquidation/helpers.ts b/packages/liquidation-sdk-viem/src/preLiquidation/helpers.ts index 88a153ae..8a2d4cfe 100644 --- a/packages/liquidation-sdk-viem/src/preLiquidation/helpers.ts +++ b/packages/liquidation-sdk-viem/src/preLiquidation/helpers.ts @@ -4,59 +4,8 @@ import { ORACLE_PRICE_SCALE, SharesMath, } from "@morpho-org/blue-sdk"; -import { parseEther } from "viem"; -import type { PreLiquidation } from "./types"; -export function getPreSeizableCollateral( - position: AccrualPosition, - preLiquidation: PreLiquidation, -) { - const preLiquidationParams = preLiquidation.preLiquidationParams; - const lltv = position.market.params.lltv; - const preLltv = preLiquidationParams.preLltv; - if ( - position.borrowAssets > MathLib.wMulDown(position.collateralValue!, lltv) || - position.borrowAssets < MathLib.wMulDown(position.collateralValue!, preLltv) - ) - return undefined; - - const ltv = MathLib.wDivUp(position.borrowAssets, position.collateralValue!); - const quotient = MathLib.wDivDown(ltv - preLltv, lltv - preLltv); - const preLIF = - preLiquidationParams.preLIF1 + - MathLib.wMulDown( - quotient, - preLiquidationParams.preLIF2 - preLiquidationParams.preLIF1, - ); - const preLCF = - preLiquidationParams.preLCF1 + - MathLib.wMulDown( - quotient, - preLiquidationParams.preLCF2 - preLiquidationParams.preLCF1, - ); - - const repayableShares = MathLib.mulDivDown( - position.borrowShares, - preLCF, - parseEther("1.01"), // adding a 1% security to not repay too much - ); - - const repayableAssets = MathLib.wMulDown( - SharesMath.toAssets( - repayableShares, - position.market.totalBorrowAssets, - position.market.totalBorrowShares, - "Down", - ), - preLIF, - ); - - return MathLib.mulDivDown( - repayableAssets, - ORACLE_PRICE_SCALE, - position.market.price!, - ); -} +import type { PreLiquidation } from "./types"; export function getRepayDataPreLiquidation( position: AccrualPosition, diff --git a/packages/liquidation-sdk-viem/src/preLiquidation/index.ts b/packages/liquidation-sdk-viem/src/preLiquidation/index.ts new file mode 100644 index 00000000..957cc2c8 --- /dev/null +++ b/packages/liquidation-sdk-viem/src/preLiquidation/index.ts @@ -0,0 +1,3 @@ +export * from "./helpers.js"; +export * from "./types.js"; +export * from "./positionGetters.js"; diff --git a/packages/liquidation-sdk-viem/src/preLiquidation/types.ts b/packages/liquidation-sdk-viem/src/preLiquidation/types.ts index 7c009a31..230af0ff 100644 --- a/packages/liquidation-sdk-viem/src/preLiquidation/types.ts +++ b/packages/liquidation-sdk-viem/src/preLiquidation/types.ts @@ -3,8 +3,11 @@ import { AccrualPosition, type Address, type MarketId, + MathLib, + ORACLE_PRICE_SCALE, + SharesMath, } from "@morpho-org/blue-sdk"; -import { getPreSeizableCollateral } from "./helpers"; +import { parseEther } from "viem"; export class PreLiquidationPosition extends AccrualPosition { public collateralAsset: PartialApiToken; @@ -12,8 +15,6 @@ export class PreLiquidationPosition extends AccrualPosition { public preLiquidation?: PreLiquidation; - public preSeizableCollateral?: bigint; - constructor( position: AccrualPosition, collateralAsset: PartialApiToken, @@ -25,9 +26,56 @@ export class PreLiquidationPosition extends AccrualPosition { this.collateralAsset = collateralAsset; this.loanAsset = loanAsset; this.preLiquidation = preLiquidation; - this.preSeizableCollateral = preLiquidation - ? getPreSeizableCollateral(position, preLiquidation) - : undefined; + } + + get preSeizableCollateral() { + if (this.preLiquidation == null) return undefined; + + const preLiquidationParams = this.preLiquidation.preLiquidationParams; + const lltv = this.market.params.lltv; + const preLltv = preLiquidationParams.preLltv; + if ( + this.borrowAssets > MathLib.wMulDown(this.collateralValue!, lltv) || + this.borrowAssets < MathLib.wMulDown(this.collateralValue!, preLltv) + ) + return undefined; + + const ltv = MathLib.wDivUp(this.borrowAssets, this.collateralValue!); + const quotient = MathLib.wDivDown(ltv - preLltv, lltv - preLltv); + const preLIF = + preLiquidationParams.preLIF1 + + MathLib.wMulDown( + quotient, + preLiquidationParams.preLIF2 - preLiquidationParams.preLIF1, + ); + const preLCF = + preLiquidationParams.preLCF1 + + MathLib.wMulDown( + quotient, + preLiquidationParams.preLCF2 - preLiquidationParams.preLCF1, + ); + + const repayableShares = MathLib.mulDivDown( + this.borrowShares, + preLCF, + parseEther("1.01"), // adding a 1% security to not repay too much + ); + + const repayableAssets = MathLib.wMulDown( + SharesMath.toAssets( + repayableShares, + this.market.totalBorrowAssets, + this.market.totalBorrowShares, + "Down", + ), + preLIF, + ); + + return MathLib.mulDivDown( + repayableAssets, + ORACLE_PRICE_SCALE, + this.market.price!, + ); } } diff --git a/packages/liquidation-sdk-viem/test/examples/preLiquidation.test.ts b/packages/liquidation-sdk-viem/test/examples/preLiquidation.test.ts index edfcd81d..ed574300 100644 --- a/packages/liquidation-sdk-viem/test/examples/preLiquidation.test.ts +++ b/packages/liquidation-sdk-viem/test/examples/preLiquidation.test.ts @@ -32,7 +32,7 @@ import { PreLiquidationPosition } from "../../src/preLiquidation/types.js"; import * as swapMock from "../contracts/SwapMock.js"; import pendleMarketData from "../pendleMockData/pendleMarketData.json"; import pendleTokens from "../pendleMockData/pendleTokens.json"; -import { type LiquidationTestContext, test } from "../preLiquidationSetup.js"; +import { type LiquidationTestContext, preLiquidationTest } from "../setup.js"; interface SwapAmountConfig { srcAmount: bigint; @@ -269,7 +269,7 @@ describe("pre liquidation", () => { }; // Cannot run concurrently because `fetch` is mocked globally. - test.sequential( + preLiquidationTest.sequential( `should pre-liquidate on standard market`, async ({ client, encoder }) => { const collateralPriceUsd = 63_300; diff --git a/packages/liquidation-sdk-viem/test/preLiquidationSetup.ts b/packages/liquidation-sdk-viem/test/preLiquidationSetup.ts deleted file mode 100644 index d3352147..00000000 --- a/packages/liquidation-sdk-viem/test/preLiquidationSetup.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { AnvilTestClient } from "@morpho-org/test"; -import { type ViemTestContext, createViemTest } from "@morpho-org/test/vitest"; -import dotenv from "dotenv"; -import { bytecode, executorAbi } from "executooor-viem"; -import { type Chain, mainnet } from "viem/chains"; -import { LiquidationEncoder } from "../src/index.js"; - -dotenv.config(); - -export interface LiquidationEncoderTestContext { - encoder: LiquidationEncoder>; -} - -export interface LiquidationTestContext - extends ViemTestContext, - LiquidationEncoderTestContext {} - -export const test = createViemTest(mainnet, { - forkUrl: process.env.MAINNET_RPC_URL, - forkBlockNumber: 21_429_913, -}).extend>({ - encoder: async ({ client }, use) => { - const receipt = await client.deployContractWait({ - abi: executorAbi, - bytecode, - args: [client.account.address], - }); - - await use(new LiquidationEncoder(receipt.contractAddress, client)); - }, -}); diff --git a/packages/liquidation-sdk-viem/test/setup.ts b/packages/liquidation-sdk-viem/test/setup.ts index fd5e1108..a34fb8a4 100644 --- a/packages/liquidation-sdk-viem/test/setup.ts +++ b/packages/liquidation-sdk-viem/test/setup.ts @@ -29,3 +29,18 @@ export const test = createViemTest(mainnet, { await use(new LiquidationEncoder(receipt.contractAddress, client)); }, }); + +export const preLiquidationTest = createViemTest(mainnet, { + forkUrl: process.env.MAINNET_RPC_URL, + forkBlockNumber: 21_429_913, +}).extend>({ + encoder: async ({ client }, use) => { + const receipt = await client.deployContractWait({ + abi: executorAbi, + bytecode, + args: [client.account.address], + }); + + await use(new LiquidationEncoder(receipt.contractAddress, client)); + }, +});