Skip to content

Commit

Permalink
feat(metamorpho): add v1.1 lostAssets
Browse files Browse the repository at this point in the history
  • Loading branch information
Rubilmax committed Jan 10, 2025
1 parent ea5e032 commit 51d42e4
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 96 deletions.
4 changes: 2 additions & 2 deletions packages/blue-sdk-ethers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
"@morpho-org/blue-sdk": "workspace:^",
"@morpho-org/morpho-ts": "workspace:^",
"ethers": "^6.0.0",
"ethers-types": "^3.17.0"
"ethers-types": "^3.18.1"
},
"devDependencies": {
"@morpho-org/blue-sdk": "workspace:^",
"@morpho-org/morpho-test": "workspace:^",
"@morpho-org/morpho-ts": "workspace:^",
"@morpho-org/test": "workspace:^",
"ethers": "^6.13.4",
"ethers-types": "^3.17.3",
"ethers-types": "^3.18.1",
"typescript": "^5.7.2",
"viem": "^2.22.2",
"vitest": "^2.1.8"
Expand Down
11 changes: 10 additions & 1 deletion packages/blue-sdk-ethers/src/fetch/Vault.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { type Provider, resolveProperties } from "ethers";
import { MetaMorpho__factory, PublicAllocator__factory } from "ethers-types";
import {
MetaMorphoV1_1__factory,
MetaMorpho__factory,
PublicAllocator__factory,
} from "ethers-types";

import {
AccrualVault,
Expand Down Expand Up @@ -43,6 +47,7 @@ export async function fetchVault(
totalSupply,
totalAssets,
lastTotalAssets,
lostAssets,
supplyQueueSize,
withdrawQueueSize,
hasPublicAllocator,
Expand All @@ -65,6 +70,9 @@ export async function fetchVault(
mm.totalSupply(overrides),
mm.totalAssets(overrides),
mm.lastTotalAssets(overrides),
MetaMorphoV1_1__factory.connect(address, runner)
.lostAssets(overrides)
.catch(() => undefined),
mm.supplyQueueLength(overrides).then((r) => Number(r)),
mm.withdrawQueueLength(overrides).then((r) => Number(r)),
chainAddresses.publicAllocator &&
Expand Down Expand Up @@ -122,6 +130,7 @@ export async function fetchVault(
totalSupply,
totalAssets,
lastTotalAssets,
lostAssets,
});
}

Expand Down
54 changes: 52 additions & 2 deletions packages/blue-sdk-ethers/test/e2e/Vault.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect } from "vitest";
import { test } from "./setup";
import { test, test2 } from "./setup";

import {
ChainId,
Expand All @@ -13,7 +13,7 @@ import { zeroAddress, zeroHash } from "viem";
import { Vault } from "../../src/augment/Vault";
import { metaMorphoAbi, publicAllocatorAbi } from "./abis";

const { steakUsdc } = vaults[ChainId.EthMainnet];
const { steakUsdc, steakPaxg } = vaults[ChainId.EthMainnet];

describe("augment/Vault", () => {
test("should fetch vault data", async ({ client, wallet }) => {
Expand Down Expand Up @@ -91,4 +91,54 @@ describe("augment/Vault", () => {

expect(value).toEqual(expectedData);
});

test2("should fetch vault v1.1 data", async ({ wallet }) => {
const expectedData = new Vault({
...steakPaxg,
curator: zeroAddress,
fee: 50000000000000000n,
feeRecipient: "0x255c7705e8BB334DfCae438197f7C4297988085a",
guardian: "0x5148Db8942C69A431167C1B7FA7590c15DF934f1",
owner: "0x0A0e559bc3b0950a7e448F0d4894db195b9cf8DD",
pendingGuardian: {
validAt: 0n,
value: zeroAddress,
},
pendingOwner: zeroAddress,
pendingTimelock: {
validAt: 0n,
value: 0n,
},
skimRecipient: zeroAddress,
publicAllocatorConfig: {
admin: "0xfeed46c11F57B7126a773EeC6ae9cA7aE1C03C9a",
fee: 0n,
accruedFee: 0n,
},
supplyQueue: [
"0xb1963517b52c4315a4ed5f6811aee279ab7adc90d9dfbd8f187e05f2758f4d1a" as MarketId,
],
timelock: 604800n,
withdrawQueue: [
"0xb1963517b52c4315a4ed5f6811aee279ab7adc90d9dfbd8f187e05f2758f4d1a" as MarketId,
],
lastTotalAssets: 206000400000000000000n,
lostAssets: 0n,
totalAssets: 206000400000000000000n,
totalSupply: 206000400000000000000n,
eip5267Domain: new Eip5267Domain({
fields: "0x0f",
name: "",
version: "1",
chainId: 1n,
verifyingContract: steakPaxg.address,
salt: zeroHash,
extensions: [],
}),
});

const value = await Vault.fetch(steakPaxg.address, wallet);

expect(value).toEqual(expectedData);
});
});
5 changes: 5 additions & 0 deletions packages/blue-sdk-ethers/test/e2e/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ export const test = createEthersTest(mainnet, {
forkUrl: process.env.MAINNET_RPC_URL,
forkBlockNumber: 19_530_000,
});

export const test2 = createEthersTest(mainnet, {
forkUrl: process.env.MAINNET_RPC_URL,
forkBlockNumber: 21_595_000,
});
13 changes: 13 additions & 0 deletions packages/blue-sdk-viem/src/abis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3684,6 +3684,19 @@ export const metaMorphoAbi = [
],
stateMutability: "view",
},
{
type: "function",
name: "lostAssets", // Only defined for MetaMorpho V1.1 vaults.
inputs: [],
outputs: [
{
name: "",
type: "uint256",
internalType: "uint256",
},
],
stateMutability: "view",
},
{
type: "function",
name: "maxDeposit",
Expand Down
8 changes: 8 additions & 0 deletions packages/blue-sdk-viem/src/fetch/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export async function fetchVault(
totalSupply,
totalAssets,
lastTotalAssets,
lostAssets,
supplyQueueSize,
withdrawQueueSize,
hasPublicAllocator,
Expand Down Expand Up @@ -187,6 +188,12 @@ export async function fetchVault(
abi: metaMorphoAbi,
functionName: "lastTotalAssets",
}),
readContract(client, {
...parameters,
address,
abi: metaMorphoAbi,
functionName: "lostAssets",
}).catch(() => undefined),
readContract(client, {
...parameters,
address,
Expand Down Expand Up @@ -285,6 +292,7 @@ export async function fetchVault(
totalSupply,
totalAssets,
lastTotalAssets,
lostAssets,
});
}
export async function fetchAccrualVault(
Expand Down
54 changes: 52 additions & 2 deletions packages/blue-sdk-viem/test/Vault.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect } from "vitest";
import { test } from "./setup";
import { test, test2 } from "./setup";

import {
ChainId,
Expand All @@ -13,7 +13,7 @@ import { zeroAddress, zeroHash } from "viem";
import { metaMorphoAbi, publicAllocatorAbi } from "../src";
import { Vault } from "../src/augment/Vault";

const { steakUsdc } = vaults[ChainId.EthMainnet];
const { steakUsdc, steakPaxg } = vaults[ChainId.EthMainnet];

describe("augment/Vault", () => {
test("should fetch vault data", async ({ client }) => {
Expand Down Expand Up @@ -91,4 +91,54 @@ describe("augment/Vault", () => {

expect(value).toStrictEqual(expectedData);
});

test2("should fetch vault v1.1 data", async ({ client }) => {
const expectedData = new Vault({
...steakPaxg,
curator: zeroAddress,
fee: 50000000000000000n,
feeRecipient: "0x255c7705e8BB334DfCae438197f7C4297988085a",
guardian: "0x5148Db8942C69A431167C1B7FA7590c15DF934f1",
owner: "0x0A0e559bc3b0950a7e448F0d4894db195b9cf8DD",
pendingGuardian: {
validAt: 0n,
value: zeroAddress,
},
pendingOwner: zeroAddress,
pendingTimelock: {
validAt: 0n,
value: 0n,
},
skimRecipient: zeroAddress,
publicAllocatorConfig: {
admin: "0xfeed46c11F57B7126a773EeC6ae9cA7aE1C03C9a",
fee: 0n,
accruedFee: 0n,
},
supplyQueue: [
"0xb1963517b52c4315a4ed5f6811aee279ab7adc90d9dfbd8f187e05f2758f4d1a" as MarketId,
],
timelock: 604800n,
withdrawQueue: [
"0xb1963517b52c4315a4ed5f6811aee279ab7adc90d9dfbd8f187e05f2758f4d1a" as MarketId,
],
lastTotalAssets: 206000400000000000000n,
lostAssets: 0n,
totalAssets: 206000400000000000000n,
totalSupply: 206000400000000000000n,
eip5267Domain: new Eip5267Domain({
fields: "0x0f",
name: "",
version: "1",
chainId: 1n,
verifyingContract: steakPaxg.address,
salt: zeroHash,
extensions: [],
}),
});

const value = await Vault.fetch(steakPaxg.address, client);

expect(value).toEqual(expectedData);
});
});
5 changes: 5 additions & 0 deletions packages/blue-sdk-viem/test/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ export const test = createViemTest(mainnet, {
forkUrl: process.env.MAINNET_RPC_URL,
forkBlockNumber: 19_530_000,
});

export const test2 = createViemTest(mainnet, {
forkUrl: process.env.MAINNET_RPC_URL,
forkBlockNumber: 21_595_000,
});
50 changes: 34 additions & 16 deletions packages/blue-sdk/src/position/Position.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { BlueErrors } from "../errors.js";
import {
CapacityLimitReason,
Market,
type MaxBorrowOptions,
type MaxPositionCapacities,
type MaxWithdrawCollateralOptions,
} from "../market/index.js";
import { MathLib } from "../math/MathLib.js";
import type { Address, BigIntish, MarketId } from "../types.js";

export interface IPosition {
Expand Down Expand Up @@ -96,7 +99,10 @@ export class AccrualPosition extends Position implements IAccrualPosition {
* `undefined` iff the market's oracle is undefined or reverts.
*/
get maxBorrowableAssets() {
return this.market.getMaxBorrowableAssets(this);
const { maxBorrowAssets } = this;
if (maxBorrowAssets == null) return;

return MathLib.zeroFloorSub(maxBorrowAssets, this.borrowAssets);
}

/**
Expand Down Expand Up @@ -166,18 +172,10 @@ export class AccrualPosition extends Position implements IAccrualPosition {
return this.market.getBorrowCapacityUsage(this);
}

get borrowCapacityLimit() {
return this.market.getBorrowCapacityLimit(this);
}

get withdrawCapacityLimit() {
return this.market.getWithdrawCapacityLimit(this);
}

get withdrawCollateralCapacityLimit() {
return this.market.getWithdrawCollateralCapacityLimit(this);
}

/**
* Returns a new position derived from this position, whose interest has been accrued up to the given timestamp.
* @param timestamp The timestamp at which to accrue interest. Must be greater than or equal to the market's `lastUpdate`.
Expand Down Expand Up @@ -277,6 +275,16 @@ export class AccrualPosition extends Position implements IAccrualPosition {
return { position, assets, shares };
}

public getBorrowCapacityLimit(options?: MaxBorrowOptions) {
return this.market.getBorrowCapacityLimit(this, options);
}

public getWithdrawCollateralCapacityLimit(
options?: MaxWithdrawCollateralOptions,
) {
return this.market.getWithdrawCollateralCapacityLimit(this, options);
}

public getRepayCapacityLimit(loanTokenBalance: bigint) {
return this.market.getRepayCapacityLimit(
this.borrowShares,
Expand All @@ -291,12 +299,22 @@ export class AccrualPosition extends Position implements IAccrualPosition {
borrow?: MaxBorrowOptions;
withdrawCollateral?: MaxWithdrawCollateralOptions;
},
) {
return this.market.getMaxCapacities(
this,
loanTokenBalance,
collateralTokenBalance,
options,
);
): MaxPositionCapacities {
return {
supply: {
value: loanTokenBalance,
limiter: CapacityLimitReason.balance,
},
withdraw: this.withdrawCapacityLimit,
borrow: this.getBorrowCapacityLimit(options?.borrow),
repay: this.getRepayCapacityLimit(loanTokenBalance),
supplyCollateral: {
value: collateralTokenBalance,
limiter: CapacityLimitReason.balance,
},
withdrawCollateral: this.getWithdrawCollateralCapacityLimit(
options?.withdrawCollateral,
),
};
}
}
Loading

0 comments on commit 51d42e4

Please sign in to comment.