@defisaver/positions-sdk 2.1.127-dev → 2.1.127-midnight-1-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/cjs/config/contracts.d.ts +249 -0
  2. package/cjs/config/contracts.js +11 -1
  3. package/cjs/contracts.d.ts +1510 -0
  4. package/cjs/contracts.js +3 -2
  5. package/cjs/helpers/index.d.ts +1 -0
  6. package/cjs/helpers/index.js +2 -1
  7. package/cjs/helpers/morphoBlueHelpers/index.js +0 -1
  8. package/cjs/helpers/morphoMidnightHelpers/index.d.ts +50 -0
  9. package/cjs/helpers/morphoMidnightHelpers/index.js +170 -0
  10. package/cjs/index.d.ts +2 -1
  11. package/cjs/index.js +3 -1
  12. package/cjs/markets/index.d.ts +1 -0
  13. package/cjs/markets/index.js +4 -1
  14. package/cjs/markets/morphoMidnight/index.d.ts +16 -0
  15. package/cjs/markets/morphoMidnight/index.js +159 -0
  16. package/cjs/morphoBlue/index.d.ts +6 -8
  17. package/cjs/morphoBlue/index.js +40 -69
  18. package/cjs/morphoMidnight/index.d.ts +14 -0
  19. package/cjs/morphoMidnight/index.js +244 -0
  20. package/cjs/portfolio/discovery.js +4 -0
  21. package/cjs/portfolio/index.js +45 -1
  22. package/cjs/services/viem.d.ts +11 -11
  23. package/cjs/types/index.d.ts +1 -0
  24. package/cjs/types/index.js +1 -0
  25. package/cjs/types/morphoBlue.d.ts +0 -9
  26. package/cjs/types/morphoMidnight.d.ts +94 -0
  27. package/cjs/types/morphoMidnight.js +15 -0
  28. package/cjs/types/portfolio.d.ts +4 -0
  29. package/esm/config/contracts.d.ts +249 -0
  30. package/esm/config/contracts.js +9 -0
  31. package/esm/contracts.d.ts +1510 -0
  32. package/esm/contracts.js +1 -0
  33. package/esm/helpers/index.d.ts +1 -0
  34. package/esm/helpers/index.js +1 -0
  35. package/esm/helpers/morphoBlueHelpers/index.js +0 -1
  36. package/esm/helpers/morphoMidnightHelpers/index.d.ts +50 -0
  37. package/esm/helpers/morphoMidnightHelpers/index.js +159 -0
  38. package/esm/index.d.ts +2 -1
  39. package/esm/index.js +2 -1
  40. package/esm/markets/index.d.ts +1 -0
  41. package/esm/markets/index.js +1 -0
  42. package/esm/markets/morphoMidnight/index.d.ts +16 -0
  43. package/esm/markets/morphoMidnight/index.js +148 -0
  44. package/esm/morphoBlue/index.d.ts +6 -8
  45. package/esm/morphoBlue/index.js +39 -62
  46. package/esm/morphoMidnight/index.d.ts +14 -0
  47. package/esm/morphoMidnight/index.js +231 -0
  48. package/esm/portfolio/discovery.js +5 -1
  49. package/esm/portfolio/index.js +47 -3
  50. package/esm/services/viem.d.ts +11 -11
  51. package/esm/types/index.d.ts +1 -0
  52. package/esm/types/index.js +1 -0
  53. package/esm/types/morphoBlue.d.ts +0 -9
  54. package/esm/types/morphoMidnight.d.ts +94 -0
  55. package/esm/types/morphoMidnight.js +12 -0
  56. package/esm/types/portfolio.d.ts +4 -0
  57. package/package.json +1 -1
  58. package/src/config/contracts.ts +9 -0
  59. package/src/contracts.ts +1 -0
  60. package/src/helpers/index.ts +1 -0
  61. package/src/helpers/morphoBlueHelpers/index.ts +0 -1
  62. package/src/helpers/morphoMidnightHelpers/index.ts +219 -0
  63. package/src/index.ts +2 -0
  64. package/src/markets/index.ts +1 -0
  65. package/src/markets/morphoMidnight/index.ts +161 -0
  66. package/src/morphoBlue/index.ts +44 -101
  67. package/src/morphoMidnight/index.ts +261 -0
  68. package/src/portfolio/discovery.ts +6 -0
  69. package/src/portfolio/index.ts +46 -2
  70. package/src/types/index.ts +1 -0
  71. package/src/types/morphoBlue.ts +0 -11
  72. package/src/types/morphoMidnight.ts +110 -0
  73. package/src/types/portfolio.ts +4 -0
@@ -0,0 +1,94 @@
1
+ import { EthAddress, IncentiveData, LeverageType, MMUsedAssets, NetworkNumber } from './common';
2
+ export declare enum MorphoMidnightVersions {
3
+ MorphoMidnightCbBTCUSDC_860_20260731_Base = "morphomidnightcbbtcusdc_860_20260731_base",
4
+ MorphoMidnightCbBTCUSDC_860_20260828_Base = "morphomidnightcbbtcusdc_860_20260828_base",
5
+ MorphoMidnightCbBTCUSDC_860_20260925_Base = "morphomidnightcbbtcusdc_860_20260925_base",
6
+ MorphoMidnightCbBTCUSDC_860_20261030_Base = "morphomidnightcbbtcusdc_860_20261030_base",
7
+ MorphoMidnightCbBTCUSDC_860_20261127_Base = "morphomidnightcbbtcusdc_860_20261127_base",
8
+ MorphoMidnightCbBTCUSDC_860_20261225_Base = "morphomidnightcbbtcusdc_860_20261225_base"
9
+ }
10
+ export interface MorphoMidnightCollateralParams {
11
+ token: EthAddress;
12
+ lltv: number | string;
13
+ liquidationCursor: number | string;
14
+ oracle: EthAddress;
15
+ }
16
+ export interface MorphoMidnightMarketData {
17
+ chainIds: NetworkNumber[];
18
+ label: string;
19
+ shortLabel: string;
20
+ url: string;
21
+ value: MorphoMidnightVersions;
22
+ midnight: EthAddress;
23
+ loanToken: EthAddress;
24
+ collaterals: MorphoMidnightCollateralParams[];
25
+ maturity: number;
26
+ rcfThreshold: number | string;
27
+ enterGate: EthAddress;
28
+ liquidatorGate: EthAddress;
29
+ marketId: string;
30
+ protocolName: string;
31
+ }
32
+ export interface MorphoMidnightAssetData {
33
+ symbol: string;
34
+ address: string;
35
+ price: string;
36
+ supplyRate: string;
37
+ borrowRate: string;
38
+ supplyIncentives: IncentiveData[];
39
+ borrowIncentives: IncentiveData[];
40
+ totalSupply?: string;
41
+ totalBorrow?: string;
42
+ canBeSupplied?: boolean;
43
+ canBeBorrowed?: boolean;
44
+ lltv?: string;
45
+ }
46
+ export type MorphoMidnightAssetsData = {
47
+ [key: string]: MorphoMidnightAssetData;
48
+ };
49
+ export interface MorphoMidnightMarketInfo {
50
+ id: string;
51
+ loanToken: string;
52
+ collaterals: string[];
53
+ maturity: number;
54
+ isMatured: boolean;
55
+ totalUnits: string;
56
+ withdrawable: string;
57
+ totalDebt: string;
58
+ lossFactor: string;
59
+ tickSpacing: number;
60
+ utillization: string;
61
+ assetsData: MorphoMidnightAssetsData;
62
+ }
63
+ export interface MorphoMidnightAggregatedPositionData {
64
+ suppliedUsd: string;
65
+ suppliedCollateralUsd: string;
66
+ borrowedUsd: string;
67
+ borrowLimitUsd: string;
68
+ liquidationLimitUsd: string;
69
+ leftToBorrowUsd: string;
70
+ leftToBorrow: string;
71
+ netApy: string;
72
+ incentiveUsd: string;
73
+ totalInterestUsd: string;
74
+ ltv: string;
75
+ ratio: string;
76
+ healthRatio: string;
77
+ leveragedType: LeverageType;
78
+ leveragedAsset?: string;
79
+ currentVolatilePairRatio?: string;
80
+ liquidationPrice?: string;
81
+ minCollRatio?: string;
82
+ collLiquidationRatio?: string;
83
+ exposure: string;
84
+ }
85
+ export interface MorphoMidnightPositionData extends MorphoMidnightAggregatedPositionData {
86
+ usedAssets: MMUsedAssets;
87
+ credit: string;
88
+ debt: string;
89
+ borrowRate: string;
90
+ debtBase: string;
91
+ debtInterest: string;
92
+ maturity: number;
93
+ isMatured: boolean;
94
+ }
@@ -0,0 +1,12 @@
1
+ export var MorphoMidnightVersions;
2
+ (function (MorphoMidnightVersions) {
3
+ // BASE
4
+ // Fixed-term markets are disambiguated by maturity (YYYYMMDD), so the same pair recurs across dates.
5
+ // Sourced from the official listing at https://markets.morpho.org/fixed/base (see sitemap.xml).
6
+ MorphoMidnightVersions["MorphoMidnightCbBTCUSDC_860_20260731_Base"] = "morphomidnightcbbtcusdc_860_20260731_base";
7
+ MorphoMidnightVersions["MorphoMidnightCbBTCUSDC_860_20260828_Base"] = "morphomidnightcbbtcusdc_860_20260828_base";
8
+ MorphoMidnightVersions["MorphoMidnightCbBTCUSDC_860_20260925_Base"] = "morphomidnightcbbtcusdc_860_20260925_base";
9
+ MorphoMidnightVersions["MorphoMidnightCbBTCUSDC_860_20261030_Base"] = "morphomidnightcbbtcusdc_860_20261030_base";
10
+ MorphoMidnightVersions["MorphoMidnightCbBTCUSDC_860_20261127_Base"] = "morphomidnightcbbtcusdc_860_20261127_base";
11
+ MorphoMidnightVersions["MorphoMidnightCbBTCUSDC_860_20261225_Base"] = "morphomidnightcbbtcusdc_860_20261225_base";
12
+ })(MorphoMidnightVersions || (MorphoMidnightVersions = {}));
@@ -9,6 +9,7 @@ import { LiquityTroveInfo } from './liquity';
9
9
  import { LlamaLendUserData, LlamaLendVersionsType } from './llamaLend';
10
10
  import { CdpData } from './maker';
11
11
  import { MorphoBluePositionData, MorphoBlueVersions } from './morphoBlue';
12
+ import { MorphoMidnightPositionData, MorphoMidnightVersions } from './morphoMidnight';
12
13
  import { SparkPositionData, SparkVersions } from './spark';
13
14
  export interface PortfolioProtocolData<T> {
14
15
  error: string;
@@ -21,6 +22,9 @@ export interface PortfolioPositionsDataForAddress {
21
22
  morphoBlue: {
22
23
  [key in MorphoBlueVersions]?: PortfolioProtocolData<MorphoBluePositionData>;
23
24
  };
25
+ morphoMidnight: {
26
+ [key in MorphoMidnightVersions]?: PortfolioProtocolData<MorphoMidnightPositionData>;
27
+ };
24
28
  compoundV3: {
25
29
  [key in CompoundVersions]?: PortfolioProtocolData<CompoundV3PositionData>;
26
30
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/positions-sdk",
3
- "version": "2.1.127-dev",
3
+ "version": "2.1.127-midnight-1-dev",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -1113,6 +1113,15 @@ export const MorphoBlueView = {
1113
1113
  }
1114
1114
  },
1115
1115
  } as const;
1116
+ export const MidnightView = {
1117
+ "abi": [{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"getMarketInfo","outputs":[{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint128","name":"totalUnits","type":"uint128"},{"internalType":"uint128","name":"lossFactor","type":"uint128"},{"internalType":"uint128","name":"withdrawable","type":"uint128"},{"internalType":"uint128","name":"continuousFeeCredit","type":"uint128"},{"internalType":"uint16[7]","name":"settlementFees","type":"uint16[7]"},{"internalType":"uint32","name":"continuousFee","type":"uint32"},{"internalType":"uint8","name":"tickSpacing","type":"uint8"},{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"internalType":"struct MidnightView.MarketInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"},{"internalType":"address","name":"_user","type":"address"}],"name":"getPositionInfo","outputs":[{"components":[{"internalType":"uint128","name":"credit","type":"uint128"},{"internalType":"uint128","name":"pendingFee","type":"uint128"},{"internalType":"uint128","name":"debt","type":"uint128"},{"internalType":"uint128","name":"collateralBitmap","type":"uint128"},{"internalType":"uint128[]","name":"collateral","type":"uint128[]"},{"internalType":"uint256","name":"ratio","type":"uint256"}],"internalType":"struct MidnightView.PositionInfo","name":"pos","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"},{"internalType":"address","name":"_user","type":"address"}],"name":"getRatio","outputs":[{"internalType":"uint256","name":"ratio","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"midnight","type":"address"},{"internalType":"address","name":"loanToken","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"},{"internalType":"uint256","name":"liquidationCursor","type":"uint256"},{"internalType":"address","name":"oracle","type":"address"}],"internalType":"struct CollateralParams[]","name":"collateralParams","type":"tuple[]"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"rcfThreshold","type":"uint256"},{"internalType":"address","name":"enterGate","type":"address"},{"internalType":"address","name":"liquidatorGate","type":"address"}],"internalType":"struct Market","name":"_market","type":"tuple"}],"name":"toId","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"toMarket","outputs":[{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"midnight","type":"address"},{"internalType":"address","name":"loanToken","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"},{"internalType":"uint256","name":"liquidationCursor","type":"uint256"},{"internalType":"address","name":"oracle","type":"address"}],"internalType":"struct CollateralParams[]","name":"collateralParams","type":"tuple[]"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"rcfThreshold","type":"uint256"},{"internalType":"address","name":"enterGate","type":"address"},{"internalType":"address","name":"liquidatorGate","type":"address"}],"internalType":"struct Market","name":"market","type":"tuple"}],"stateMutability":"view","type":"function"}],
1118
+ "networks": {
1119
+ "8453": {
1120
+ "address": "0x3aa272f329E8B562A3bA56Bb6979a44D23A28839",
1121
+ "createdBlock": 48932293,
1122
+ }
1123
+ },
1124
+ } as const;
1116
1125
  export const FeedRegistry = {
1117
1126
  "abi": [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"address","name":"aggregator","type":"address"}],"name":"confirmFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"answer","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"getCurrentPhaseId","outputs":[{"internalType":"uint16","name":"currentPhaseId","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"getFeed","outputs":[{"internalType":"contract AggregatorV2V3Interface","name":"aggregator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint80","name":"roundId","type":"uint80"}],"name":"getNextRoundId","outputs":[{"internalType":"uint80","name":"nextRoundId","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint16","name":"phaseId","type":"uint16"}],"name":"getPhase","outputs":[{"components":[{"internalType":"uint16","name":"phaseId","type":"uint16"},{"internalType":"uint80","name":"startingAggregatorRoundId","type":"uint80"},{"internalType":"uint80","name":"endingAggregatorRoundId","type":"uint80"}],"internalType":"struct FeedRegistryInterface.Phase","name":"phase","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint16","name":"phaseId","type":"uint16"}],"name":"getPhaseFeed","outputs":[{"internalType":"contract AggregatorV2V3Interface","name":"aggregator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint16","name":"phaseId","type":"uint16"}],"name":"getPhaseRange","outputs":[{"internalType":"uint80","name":"startingRoundId","type":"uint80"},{"internalType":"uint80","name":"endingRoundId","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint80","name":"roundId","type":"uint80"}],"name":"getPreviousRoundId","outputs":[{"internalType":"uint80","name":"previousRoundId","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"getProposedFeed","outputs":[{"internalType":"contract AggregatorV2V3Interface","name":"proposedAggregator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint80","name":"roundId","type":"uint80"}],"name":"getRoundFeed","outputs":[{"internalType":"contract AggregatorV2V3Interface","name":"aggregator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"getTimestamp","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"}],"name":"isFeedEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"answer","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"latestRound","outputs":[{"internalType":"uint256","name":"roundId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"latestTimestamp","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"address","name":"aggregator","type":"address"}],"name":"proposeFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"},{"internalType":"uint80","name":"roundId","type":"uint80"}],"name":"proposedGetRoundData","outputs":[{"internalType":"uint80","name":"id","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"proposedLatestRoundData","outputs":[{"internalType":"uint80","name":"id","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_accessController","type":"address"}],"name":"setAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"base","type":"address"},{"internalType":"address","name":"quote","type":"address"}],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],
1118
1127
  "networks": {
package/src/contracts.ts CHANGED
@@ -122,6 +122,7 @@ export const getYearnV3VaultContractViem = (client: Client, address: HexString)
122
122
  };
123
123
 
124
124
  export const MorphoBlueViewContractViem = createViemContractFromConfigFunc('MorphoBlueView');
125
+ export const MorphoMidnightViewContractViem = createViemContractFromConfigFunc('MidnightView');
125
126
  export const AaveLoanInfoV2ContractViem = createViemContractFromConfigFunc('AaveLoanInfoV2');
126
127
  export const AaveV3ViewContractViem = createViemContractFromConfigFunc('AaveV3View');
127
128
  export const AaveIncentiveDataProviderV3ContractViem = createViemContractFromConfigFunc('AaveUiIncentiveDataProviderV3');
@@ -4,6 +4,7 @@ export * as sparkHelpers from './sparkHelpers';
4
4
  export * as curveUsdHelpers from './curveUsdHelpers';
5
5
  export * as makerHelpers from './makerHelpers';
6
6
  export * as morphoBlueHelpers from './morphoBlueHelpers';
7
+ export * as morphoMidnightHelpers from './morphoMidnightHelpers';
7
8
  export * as llamaLendHelpers from './llamaLendHelpers';
8
9
  export * as liquityV2Helpers from './liquityV2Helpers';
9
10
  export * as eulerV2Helpers from './eulerHelpers';
@@ -389,7 +389,6 @@ export const getRewardsForMarket = async (marketId: string, network: NetworkNumb
389
389
  query: REWARDS_QUERY,
390
390
  variables: { marketId, chainId: network },
391
391
  }),
392
- signal: AbortSignal.timeout(LONGER_TIMEOUT),
393
392
  });
394
393
 
395
394
  const data = await response.json();
@@ -0,0 +1,219 @@
1
+ import Dec from 'decimal.js';
2
+ import { assetAmountInEth } from '@defisaver/tokens';
3
+ import {
4
+ calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
5
+ } from '../../moneymarket';
6
+ import { calculateNetApy } from '../../staking';
7
+ import {
8
+ LeverageType, MMAssetsData, MMUsedAsset, MMUsedAssets,
9
+ } from '../../types/common';
10
+ import { MorphoMidnightAggregatedPositionData, MorphoMidnightAssetsData, MorphoMidnightMarketInfo } from '../../types';
11
+ import { SECONDS_PER_DAY, WAD } from '../../constants';
12
+ import { LONGER_TIMEOUT } from '../../services/utils';
13
+
14
+ /**
15
+ * Aggregate a Morpho Midnight position. Midnight markets are multi-collateral, so the borrow limit is
16
+ * the sum of each collateral's USD value times its own lltv (Aave-v4 style), rather than a single pair.
17
+ *
18
+ * Note on amounts: `borrowedUsd` is derived from the position's `debt`, which is the face value owed at
19
+ * maturity (principal + fixed interest). Health is therefore measured against the full maturity debt,
20
+ * matching how MidnightView computes `ratio`. Fixed-rate APY is not derived on-chain in MVP, so
21
+ * `netApy` reflects the `'0'` rates in `assetsData` (see the module getter).
22
+ */
23
+ export const getMorphoMidnightAggregatedPositionData = ({
24
+ usedAssets,
25
+ assetsData,
26
+ marketInfo,
27
+ }: {
28
+ usedAssets: MMUsedAssets,
29
+ assetsData: MorphoMidnightAssetsData,
30
+ marketInfo: MorphoMidnightMarketInfo,
31
+ }): MorphoMidnightAggregatedPositionData => {
32
+ const payload = {} as MorphoMidnightAggregatedPositionData;
33
+
34
+ payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
35
+ payload.suppliedCollateralUsd = getAssetsTotal(usedAssets, ({ isSupplied, collateral }: { isSupplied: boolean, collateral: boolean }) => isSupplied && collateral, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
36
+ payload.borrowedUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd);
37
+
38
+ // borrowLimit = Σ collateralUsd_i * lltv_i (per-collateral lltv carried on assetsData)
39
+ payload.borrowLimitUsd = getAssetsTotal(
40
+ usedAssets,
41
+ ({ isSupplied, collateral }: { isSupplied: boolean, collateral: boolean }) => isSupplied && collateral,
42
+ ({ symbol, suppliedUsd }: { symbol: string, suppliedUsd: string }) => new Dec(suppliedUsd).mul(assetsData[symbol]?.lltv || 0),
43
+ );
44
+ payload.liquidationLimitUsd = payload.borrowLimitUsd;
45
+
46
+ const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
47
+ payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
48
+
49
+ const loanTokenPrice = assetsData[marketInfo.loanToken]?.price || '0';
50
+ payload.leftToBorrow = new Dec(loanTokenPrice).eq(0) ? '0' : new Dec(payload.leftToBorrowUsd).div(loanTokenPrice).toString();
51
+
52
+ const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({ usedAssets, assetsData: assetsData as unknown as MMAssetsData });
53
+ payload.netApy = netApy;
54
+ payload.incentiveUsd = incentiveUsd;
55
+ payload.totalInterestUsd = totalInterestUsd;
56
+
57
+ payload.ltv = new Dec(payload.suppliedCollateralUsd).eq(0) ? '0' : new Dec(payload.borrowedUsd).div(payload.suppliedCollateralUsd).toString();
58
+ payload.ratio = new Dec(payload.borrowedUsd).eq(0) ? '0' : new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString();
59
+ payload.healthRatio = new Dec(payload.borrowedUsd).eq(0) ? 'Infinity' : new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
60
+
61
+ const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
62
+ payload.leveragedType = leveragedType;
63
+ payload.liquidationPrice = '';
64
+ if (leveragedType !== '') {
65
+ payload.leveragedAsset = leveragedAsset;
66
+ let assetPrice = assetsData[leveragedAsset].price;
67
+ if (leveragedType === LeverageType.VolatilePair) {
68
+ const borrowedAsset = (Object.values(usedAssets) as MMUsedAsset[]).find(({ borrowedUsd }: { borrowedUsd: string }) => +borrowedUsd > 0);
69
+ const borrowedAssetPrice = assetsData[borrowedAsset!.symbol].price;
70
+ const leveragedAssetPrice = assetsData[leveragedAsset].price;
71
+ const isReverse = new Dec(leveragedAssetPrice).lt(borrowedAssetPrice);
72
+ if (isReverse) {
73
+ payload.leveragedType = LeverageType.VolatilePairReverse;
74
+ payload.currentVolatilePairRatio = new Dec(borrowedAssetPrice).div(leveragedAssetPrice).toDP(18).toString();
75
+ assetPrice = new Dec(borrowedAssetPrice).div(assetPrice).toString();
76
+ } else {
77
+ assetPrice = new Dec(assetPrice).div(borrowedAssetPrice).toString();
78
+ payload.currentVolatilePairRatio = new Dec(leveragedAssetPrice).div(borrowedAssetPrice).toDP(18).toString();
79
+ }
80
+ }
81
+ payload.liquidationPrice = calcLeverageLiqPrice(payload.leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
82
+ }
83
+
84
+ payload.minCollRatio = new Dec(payload.borrowLimitUsd).eq(0) ? '0' : new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
85
+ payload.collLiquidationRatio = new Dec(payload.liquidationLimitUsd).eq(0) ? '0' : new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
86
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
87
+
88
+ return payload;
89
+ };
90
+
91
+ // ── Off-chain order-book rate helpers ──────────────────────────────────────────────────────────────
92
+ // notion: https://app.notion.com/p/defisaver/Estimate-borrow-rate-and-slippage-before-execution-3a70be682adc80c783c8c11fdb761dd2
93
+ // the borrow rate is not exposed on-chain (MidnightView only stores total debt at maturity in `units`).
94
+ // derive the rate + interest from Morpho's public keyless Midnight API
95
+ // Quote prices are WAD-scaled
96
+ // loan-per-unit ratios (< 1 for a discounted fixed-term borrow); annualizing them yields the borrow APY.
97
+
98
+ const MIDNIGHT_API_BASE = 'https://api.morpho.org/v0/midnight';
99
+ const nowInSeconds = () => Math.floor(Date.now() / 1000);
100
+
101
+ interface MidnightTransaction {
102
+ event_type: string,
103
+ market_id: string,
104
+ created_at: number,
105
+ data: { seller_assets?: string, units?: string },
106
+ }
107
+
108
+ export interface MorphoMidnightBorrowInfo {
109
+ borrowRate: string, // weighted-average borrow APY as a percent
110
+ debtBase: string, // base borrowed (Σ seller_assets), loan-token units
111
+ debtInterest: string, // debtTotal − debtBase (interest owed at maturity), loan-token units
112
+ debtTotal: string, // Σ units = on-chain debt at maturity, loan-token units
113
+ }
114
+
115
+ export interface MorphoMidnightBorrowQuote {
116
+ bestPrice: string, // average_best_price, loan-per-unit
117
+ worstPrice: string, // average_worst_price, slippage-adjusted
118
+ estBorrowRate: string, // estimated borrow APY as a percent
119
+ maxRate: string, // estBorrowRate + slippage (display only, not sent on-chain)
120
+ newUnits: string, // debt added at best price, raw loan-token base units
121
+ maxUnits: string, // slippage-capped debt (on-chain cap), raw loan-token base units
122
+ availableAssets: string,
123
+ availableUnits: string,
124
+ takeableOffers: any[], // opaque orderbook offers, forwarded verbatim to on-chain execution
125
+ }
126
+
127
+ // Days remaining until maturity, optionally measured at a past timestamp (for historical fills).
128
+ export const midnightTimeToMaturityDays = (maturity: number, atSeconds: number = nowInSeconds()): number => new Dec(maturity).sub(atSeconds).div(SECONDS_PER_DAY).toNumber();
129
+
130
+ // Annualize a fixed-term discount price into an APY percent: (1 / price)^(365 / ttmDays) − 1.
131
+ // `price` is loan-per-unit (assets received / units owed), so 1/price ≥ 1.
132
+ export const midnightApyFromPrice = (price: Dec.Value, ttmDays: Dec.Value): string => {
133
+ const p = new Dec(price);
134
+ const ttm = new Dec(ttmDays);
135
+ if (p.lte(0) || ttm.lte(0)) return '0';
136
+ return new Dec(1).div(p).pow(new Dec(365).div(ttm)).sub(1)
137
+ .mul(100)
138
+ .toString();
139
+ };
140
+
141
+ /**
142
+ * Current borrower rate + debt breakdown from the Midnight transactions API. On-chain we can only read the
143
+ * total debt at maturity (`units`); the base-vs-interest split and the effective borrow rate require the
144
+ * fill history. Per fill the rate is (units / seller_assets)^(365 / ttmAtFill) − 1, weighted by base amount.
145
+ * The caller swallows errors — a missing rate must never block position rendering.
146
+ */
147
+ export const getMorphoMidnightUserBorrowInfo = async (
148
+ account: string,
149
+ marketId: string,
150
+ maturity: number,
151
+ loanTokenSymbol: string,
152
+ ): Promise<MorphoMidnightBorrowInfo> => {
153
+ const res = await fetch(`${MIDNIGHT_API_BASE}/users/${account}/transactions`, { signal: AbortSignal.timeout(LONGER_TIMEOUT) });
154
+ const json: { data?: MidnightTransaction[] } = await res.json();
155
+ const borrows = (json?.data || []).filter((t) => t.event_type === 'borrow' && t.market_id?.toLowerCase() === marketId.toLowerCase());
156
+
157
+ let sumSeller = new Dec(0); // Σ seller_assets (base), raw
158
+ let sumUnits = new Dec(0); // Σ units (debt at maturity), raw
159
+ let weightedApy = new Dec(0); // Σ seller_assets × APYᵢ
160
+
161
+ borrows.forEach((t) => {
162
+ const sellerAssets = new Dec(t.data?.seller_assets || 0);
163
+ const units = new Dec(t.data?.units || 0);
164
+ if (sellerAssets.lte(0) || units.lte(0)) return;
165
+ const ttmDays = midnightTimeToMaturityDays(maturity, t.created_at);
166
+ const apy = midnightApyFromPrice(sellerAssets.div(units), ttmDays); // price = seller_assets / units
167
+ sumSeller = sumSeller.add(sellerAssets);
168
+ sumUnits = sumUnits.add(units);
169
+ weightedApy = weightedApy.add(sellerAssets.mul(apy));
170
+ });
171
+
172
+ const borrowRate = sumSeller.lte(0) ? '0' : weightedApy.div(sumSeller).toString();
173
+ const debtBase = assetAmountInEth(sumSeller.toFixed(0), loanTokenSymbol);
174
+ const debtTotal = assetAmountInEth(sumUnits.toFixed(0), loanTokenSymbol);
175
+ const debtInterest = Dec.max(new Dec(debtTotal).sub(debtBase), 0).toString();
176
+
177
+ return {
178
+ borrowRate, debtBase, debtInterest, debtTotal,
179
+ };
180
+ };
181
+
182
+ /**
183
+ * Estimate the borrow rate + slippage cap for a prospective borrow by quoting the Midnight order book.
184
+ * `assetsRaw` (and the returned `newUnits`/`maxUnits`) are raw loan-token base units — callers convert to/from
185
+ * human amounts. `maxUnits` (from the slippage-adjusted worst price) is the cap sent on-chain to protect the
186
+ * user if better offers get filled first. Throws if the book can't fill the amount (caller handles).
187
+ */
188
+ export const getMorphoMidnightBorrowQuote = async (
189
+ marketId: string,
190
+ assetsRaw: string,
191
+ slippagePercent: Dec.Value,
192
+ maturity: number,
193
+ ): Promise<MorphoMidnightBorrowQuote> => {
194
+ const url = `${MIDNIGHT_API_BASE}/books/${marketId}/bids/quote?assets=${assetsRaw}&slippage=${slippagePercent}`;
195
+ const res = await fetch(url, { signal: AbortSignal.timeout(LONGER_TIMEOUT) });
196
+ const json: { data?: any } = await res.json();
197
+ const d = json?.data;
198
+ if (!d?.average_best_price) throw new Error('Morpho Midnight quote unavailable');
199
+
200
+ const bestPrice = new Dec(d.average_best_price).div(WAD).toString();
201
+ const worstPrice = new Dec(d.average_worst_price).div(WAD).toString();
202
+ const ttmDays = midnightTimeToMaturityDays(maturity);
203
+ const estBorrowRate = midnightApyFromPrice(bestPrice, ttmDays);
204
+ const maxRate = new Dec(estBorrowRate).add(slippagePercent).toString();
205
+ const newUnits = new Dec(bestPrice).lte(0) ? '0' : new Dec(assetsRaw).div(bestPrice).toFixed(0);
206
+ const maxUnits = new Dec(worstPrice).lte(0) ? '0' : new Dec(assetsRaw).div(worstPrice).toFixed(0);
207
+
208
+ return {
209
+ bestPrice,
210
+ worstPrice,
211
+ estBorrowRate,
212
+ maxRate,
213
+ newUnits,
214
+ maxUnits,
215
+ availableAssets: d.available_assets,
216
+ availableUnits: d.available_units,
217
+ takeableOffers: d.takeable_offers || [],
218
+ };
219
+ };
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ import * as markets from './markets';
17
17
  import * as helpers from './helpers';
18
18
  import * as exchange from './exchange';
19
19
  import * as morphoBlue from './morphoBlue';
20
+ import * as morphoMidnight from './morphoMidnight';
20
21
  import * as llamaLend from './llamaLend';
21
22
  import * as eulerV2 from './eulerV2';
22
23
  import * as portfolio from './portfolio';
@@ -42,6 +43,7 @@ export {
42
43
  markets,
43
44
  helpers,
44
45
  morphoBlue,
46
+ morphoMidnight,
45
47
  llamaLend,
46
48
  eulerV2,
47
49
  fluid,
@@ -17,6 +17,7 @@ export {
17
17
  export { SparkMarkets } from './spark';
18
18
  export { CrvUsdMarkets } from './curveUsd';
19
19
  export { MorphoBlueMarkets, findMorphoBlueMarket } from './morphoBlue';
20
+ export { MorphoMidnightMarkets, findMorphoMidnightMarket } from './morphoMidnight';
20
21
  export { LlamaLendMarkets } from './llamaLend';
21
22
  export { LiquityV2Markets, findLiquityV2MarketByAddress } from './liquityV2';
22
23
  export { EulerV2Markets } from './euler';
@@ -0,0 +1,161 @@
1
+ import { MorphoMidnightMarketData, MorphoMidnightVersions, NetworkNumber } from '../../types';
2
+
3
+ // Morpho Midnight core contract on Base (same for every market).
4
+ const MIDNIGHT_BASE = '0xAdedD8ab6dE832766Fedf0FaC4992E5C4D3EA18A';
5
+ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
6
+
7
+ // Curated Morpho Midnight markets. Each market is fixed-term: it is uniquely identified on-chain by
8
+ // `marketId` (bytes32), derived from the static struct below via MidnightView.toId. Because markets
9
+ // churn as maturities roll, this list is hand-maintained for the pairs/maturities the app supports.
10
+ // Sourced from the official listing at https://markets.morpho.org/fixed/base (see its sitemap.xml) —
11
+ // currently a single USDC/cbBTC pair offered on a monthly maturity ladder; new maturities are added
12
+ // there progressively. Every `marketId` here is verified against MidnightView.toId(marketStruct) in
13
+ // tests/morphoMidnight.ts.
14
+
15
+ // BASE — USDC/cbBTC, 86% LLTV, monthly maturity ladder
16
+
17
+ export const MORPHO_MIDNIGHT_CBBTC_USDC_860_20260731 = (networkId = NetworkNumber.Base): MorphoMidnightMarketData => ({
18
+ chainIds: [NetworkNumber.Base],
19
+ label: 'Morpho Midnight cbBTC/USDC',
20
+ shortLabel: 'cbBTC/USDC',
21
+ url: 'cbbtc-usdc-20260731',
22
+ value: MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20260731_Base,
23
+ midnight: MIDNIGHT_BASE,
24
+ loanToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
25
+ collaterals: [{
26
+ token: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', // cbBTC
27
+ lltv: 0.86,
28
+ liquidationCursor: '300000000000000000',
29
+ oracle: '0x663BECd10daE6C4A3Dcd89F1d76c1174199639B9',
30
+ }],
31
+ maturity: 1785510000, // 2026-07-31T15:00:00Z
32
+ rcfThreshold: '3000000000',
33
+ enterGate: ZERO_ADDRESS,
34
+ liquidatorGate: ZERO_ADDRESS,
35
+ marketId: '0x168e31250e0008b50d2255a5ab85e0265acd6c12e4f9a1336134b36a65a47937',
36
+ protocolName: 'morpho-midnight',
37
+ });
38
+
39
+ export const MORPHO_MIDNIGHT_CBBTC_USDC_860_20260828 = (networkId = NetworkNumber.Base): MorphoMidnightMarketData => ({
40
+ chainIds: [NetworkNumber.Base],
41
+ label: 'Morpho Midnight cbBTC/USDC',
42
+ shortLabel: 'cbBTC/USDC',
43
+ url: 'cbbtc-usdc-20260828',
44
+ value: MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20260828_Base,
45
+ midnight: MIDNIGHT_BASE,
46
+ loanToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
47
+ collaterals: [{
48
+ token: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', // cbBTC
49
+ lltv: 0.86,
50
+ liquidationCursor: '300000000000000000',
51
+ oracle: '0x663BECd10daE6C4A3Dcd89F1d76c1174199639B9',
52
+ }],
53
+ maturity: 1787929200, // 2026-08-28T15:00:00Z
54
+ rcfThreshold: '3000000000',
55
+ enterGate: ZERO_ADDRESS,
56
+ liquidatorGate: ZERO_ADDRESS,
57
+ marketId: '0x05959752fdeff325962b9d263edb421efc6e2186a49360dba6c32e86ebf6c84c',
58
+ protocolName: 'morpho-midnight',
59
+ });
60
+
61
+ export const MORPHO_MIDNIGHT_CBBTC_USDC_860_20260925 = (networkId = NetworkNumber.Base): MorphoMidnightMarketData => ({
62
+ chainIds: [NetworkNumber.Base],
63
+ label: 'Morpho Midnight cbBTC/USDC',
64
+ shortLabel: 'cbBTC/USDC',
65
+ url: 'cbbtc-usdc-20260925',
66
+ value: MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20260925_Base,
67
+ midnight: MIDNIGHT_BASE,
68
+ loanToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
69
+ collaterals: [{
70
+ token: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', // cbBTC
71
+ lltv: 0.86,
72
+ liquidationCursor: '300000000000000000',
73
+ oracle: '0x663BECd10daE6C4A3Dcd89F1d76c1174199639B9',
74
+ }],
75
+ maturity: 1790348400, // 2026-09-25T15:00:00Z
76
+ rcfThreshold: '3000000000',
77
+ enterGate: ZERO_ADDRESS,
78
+ liquidatorGate: ZERO_ADDRESS,
79
+ marketId: '0x549cd072daf99328554f3a6d2d4d6f4a07f1c59369e891e6391946f9cf75f221',
80
+ protocolName: 'morpho-midnight',
81
+ });
82
+
83
+ export const MORPHO_MIDNIGHT_CBBTC_USDC_860_20261030 = (networkId = NetworkNumber.Base): MorphoMidnightMarketData => ({
84
+ chainIds: [NetworkNumber.Base],
85
+ label: 'Morpho Midnight cbBTC/USDC',
86
+ shortLabel: 'cbBTC/USDC',
87
+ url: 'cbbtc-usdc-20261030',
88
+ value: MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20261030_Base,
89
+ midnight: MIDNIGHT_BASE,
90
+ loanToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
91
+ collaterals: [{
92
+ token: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', // cbBTC
93
+ lltv: 0.86,
94
+ liquidationCursor: '300000000000000000',
95
+ oracle: '0x663BECd10daE6C4A3Dcd89F1d76c1174199639B9',
96
+ }],
97
+ maturity: 1793372400, // 2026-10-30T15:00:00Z
98
+ rcfThreshold: '3000000000',
99
+ enterGate: ZERO_ADDRESS,
100
+ liquidatorGate: ZERO_ADDRESS,
101
+ marketId: '0x43d6120738c57b2bc5835901f8250fdf7fc8054efbb006c6ccba61ec898e5ed9',
102
+ protocolName: 'morpho-midnight',
103
+ });
104
+
105
+ export const MORPHO_MIDNIGHT_CBBTC_USDC_860_20261127 = (networkId = NetworkNumber.Base): MorphoMidnightMarketData => ({
106
+ chainIds: [NetworkNumber.Base],
107
+ label: 'Morpho Midnight cbBTC/USDC',
108
+ shortLabel: 'cbBTC/USDC',
109
+ url: 'cbbtc-usdc-20261127',
110
+ value: MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20261127_Base,
111
+ midnight: MIDNIGHT_BASE,
112
+ loanToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
113
+ collaterals: [{
114
+ token: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', // cbBTC
115
+ lltv: 0.86,
116
+ liquidationCursor: '300000000000000000',
117
+ oracle: '0x663BECd10daE6C4A3Dcd89F1d76c1174199639B9',
118
+ }],
119
+ maturity: 1795791600, // 2026-11-27T15:00:00Z
120
+ rcfThreshold: '3000000000',
121
+ enterGate: ZERO_ADDRESS,
122
+ liquidatorGate: ZERO_ADDRESS,
123
+ marketId: '0xe1878eec035b601f301484e63a49a428f8e008e2bf57a2fd88a3fc3a4c1b1acd',
124
+ protocolName: 'morpho-midnight',
125
+ });
126
+
127
+ export const MORPHO_MIDNIGHT_CBBTC_USDC_860_20261225 = (networkId = NetworkNumber.Base): MorphoMidnightMarketData => ({
128
+ chainIds: [NetworkNumber.Base],
129
+ label: 'Morpho Midnight cbBTC/USDC',
130
+ shortLabel: 'cbBTC/USDC',
131
+ url: 'cbbtc-usdc-20261225',
132
+ value: MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20261225_Base,
133
+ midnight: MIDNIGHT_BASE,
134
+ loanToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC
135
+ collaterals: [{
136
+ token: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', // cbBTC
137
+ lltv: 0.86,
138
+ liquidationCursor: '300000000000000000',
139
+ oracle: '0x663BECd10daE6C4A3Dcd89F1d76c1174199639B9',
140
+ }],
141
+ maturity: 1798210800, // 2026-12-25T15:00:00Z
142
+ rcfThreshold: '3000000000',
143
+ enterGate: ZERO_ADDRESS,
144
+ liquidatorGate: ZERO_ADDRESS,
145
+ marketId: '0x9593c3a6dba45b6106af8dc8b45ba8c505d90d3d68a3d33f7c278dd921b637da',
146
+ protocolName: 'morpho-midnight',
147
+ });
148
+
149
+ export const MorphoMidnightMarkets = (networkId: NetworkNumber) => ({
150
+ // BASE
151
+ [MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20260731_Base]: MORPHO_MIDNIGHT_CBBTC_USDC_860_20260731(networkId),
152
+ [MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20260828_Base]: MORPHO_MIDNIGHT_CBBTC_USDC_860_20260828(networkId),
153
+ [MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20260925_Base]: MORPHO_MIDNIGHT_CBBTC_USDC_860_20260925(networkId),
154
+ [MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20261030_Base]: MORPHO_MIDNIGHT_CBBTC_USDC_860_20261030(networkId),
155
+ [MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20261127_Base]: MORPHO_MIDNIGHT_CBBTC_USDC_860_20261127(networkId),
156
+ [MorphoMidnightVersions.MorphoMidnightCbBTCUSDC_860_20261225_Base]: MORPHO_MIDNIGHT_CBBTC_USDC_860_20261225(networkId),
157
+ }) as const;
158
+
159
+ export const findMorphoMidnightMarket = (marketId: string, network: NetworkNumber = NetworkNumber.Base): MorphoMidnightMarketData | undefined => Object.values(MorphoMidnightMarkets(network)).find(
160
+ (market) => market.marketId.toLowerCase() === marketId.toLowerCase(),
161
+ );