@panoptic-eng/sdk 1.0.17 → 1.0.19

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.
@@ -1 +1 @@
1
- {"version":3,"file":"irm-BYUt1x9h.js","names":["client: Client","results: readonly MulticallBlockResult[]","index: number","label: string","amount: bigint","sqrtPriceX96: bigint","params: IsLiquidatableParams","collateralToken0: Address","collateralToken1: Address","calls: MulticallBlockCall[]","denominatedInToken: bigint","pool: {\n collateralTracker0: { address: Address }\n collateralTracker1: { address: Address }\n}","params: GetAccountCollateralParams","collateralToken0: Address","collateralToken1: Address","token0: TokenCollateral","token1: TokenCollateral","params: GetAccountSummaryBasicParams","params: GetAccountSummaryRiskParams","params: GetNetLiquidationValueParams","params: GetNetLiquidationValuesParams","params: GetLiquidationPricesParams","SECONDS_PER_YEAR","erc20Abi","params: GetCollateralDataParams","_meta","poolData","totalShares","interestRate","depositedAssets","insideAMM","creditedShares","utilization","totalAssets","borrowRate","supplyRate","params: GetCurrentRatesParams","collateralToken0: Address","collateralToken1: Address","params: GetInterestStateParams","amount: bigint","decimals: bigint","precision: bigint","amount: string","flow: TokenFlow","decimals0: bigint","decimals1: bigint","precision0: bigint","precision1: bigint","wad: bigint","precision: bigint","rateWad: bigint","value: string","SECONDS_PER_YEAR","ratePerSecondWad: bigint","precision: bigint","utilizationBps: bigint","bits: bigint","value: bigint","fieldName: string","inputs: IrmMarketStateInputs","utilizationPct: number","ratePerSecWad: bigint","borrowRatePerSecWad: bigint","utilizationWad: bigint","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n blockNumber?: bigint\n}","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n points?: number\n blockNumber?: bigint\n}","curvePoints: IrmPoint[]"],"sources":["../src/abis/multicall3.ts","../src/panoptic/v2/abis/panopticQuery.ts","../src/panoptic/v2/reads/multicallBlock.ts","../src/panoptic/v2/reads/checks.ts","../src/panoptic/v2/reads/account.ts","../src/panoptic/v2/reads/collateral.ts","../src/panoptic/v2/formatters/amount.ts","../src/panoptic/v2/formatters/wad.ts","../src/panoptic/v2/formatters/rates.ts","../src/panoptic/v2/reads/irm.ts"],"sourcesContent":["export const Multicall3Abi = [\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes[]',\n name: 'returnData',\n type: 'bytes[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bool',\n name: 'allowFailure',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call3[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate3',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bool',\n name: 'allowFailure',\n type: 'bool',\n },\n {\n internalType: 'uint256',\n name: 'value',\n type: 'uint256',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call3Value[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate3Value',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'blockAndAggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getBasefee',\n outputs: [\n {\n internalType: 'uint256',\n name: 'basefee',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n ],\n name: 'getBlockHash',\n outputs: [\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getBlockNumber',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getChainId',\n outputs: [\n {\n internalType: 'uint256',\n name: 'chainid',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockCoinbase',\n outputs: [\n {\n internalType: 'address',\n name: 'coinbase',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockDifficulty',\n outputs: [\n {\n internalType: 'uint256',\n name: 'difficulty',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockGasLimit',\n outputs: [\n {\n internalType: 'uint256',\n name: 'gaslimit',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockTimestamp',\n outputs: [\n {\n internalType: 'uint256',\n name: 'timestamp',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'addr',\n type: 'address',\n },\n ],\n name: 'getEthBalance',\n outputs: [\n {\n internalType: 'uint256',\n name: 'balance',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getLastBlockHash',\n outputs: [\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'bool',\n name: 'requireSuccess',\n type: 'bool',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'tryAggregate',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'bool',\n name: 'requireSuccess',\n type: 'bool',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'tryBlockAndAggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n] as const\n","/**\n * PanopticQuery contract ABI\n * Auto-generated from PanopticQuery.json\n * @module abis/panopticQuery\n */\n\nexport const panopticQueryAbi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: 'SFPM_',\n type: 'address',\n internalType: 'contract ISemiFungiblePositionManager',\n },\n ],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n name: 'checkCollateral',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'collateralBalances0', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'requiredCollaterals0', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'collateralBalances1', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'requiredCollaterals1', type: 'uint256[4]', internalType: 'uint256[4]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'checkCollateral',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: 'balancesAndRequired', type: 'uint256[4]', internalType: 'uint256[4]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'checkCollateralListOutput',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: '', type: 'uint256[2][]', internalType: 'uint256[2][]' },\n { name: '', type: 'int256[]', internalType: 'int256[]' },\n { name: '', type: 'int24[]', internalType: 'int24[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'computeMedianObservedPrice',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'cardinality', type: 'uint256', internalType: 'uint256' },\n { name: 'period', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [{ name: 'medianTick', type: 'int24', internalType: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getChunkData',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [{ name: '', type: 'uint256[2][4][]', internalType: 'uint256[2][4][]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'scanChunks',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'tickLower', type: 'int24', internalType: 'int24' },\n { name: 'tickUpper', type: 'int24', internalType: 'int24' },\n { name: 'width', type: 'int24', internalType: 'int24' },\n ],\n outputs: [\n { name: 'strikes', type: 'int24[]', internalType: 'int24[]' },\n { name: 'netLiquidities', type: 'uint128[2][]', internalType: 'uint128[2][]' },\n { name: 'removedLiquidities', type: 'uint128[2][]', internalType: 'uint128[2][]' },\n { name: 'settledTokens', type: 'uint256[2][]', internalType: 'LeftRightUnsigned[2][]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getLiquidationPrices',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'liquidationPriceDown', type: 'int24', internalType: 'int24' },\n { name: 'liquidationPriceUp', type: 'int24', internalType: 'int24' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getMaxPositionSizeBounds',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'existingPositionIds', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n ],\n outputs: [\n { name: 'maxSizeAtMinUtil', type: 'uint128', internalType: 'uint128' },\n { name: 'maxSizeAtMaxUtil', type: 'uint128', internalType: 'uint128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getNetLiquidationValue',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'includePendingPremium', type: 'bool', internalType: 'bool' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTicks', type: 'int24[]', internalType: 'int24[]' },\n ],\n outputs: [\n { name: 'value0', type: 'int256[]', internalType: 'int256[]' },\n { name: 'value1', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getPortfolioValue',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'value0', type: 'int256', internalType: 'int256' },\n { name: 'value1', type: 'int256', internalType: 'int256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getRequiredBase',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNets',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNetsV3',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNetsV4',\n inputs: [\n { name: 'manager', type: 'address', internalType: 'contract IPoolManager' },\n { name: 'poolId', type: 'bytes32', internalType: 'PoolId' },\n { name: 'tickSpacing', type: 'int24', internalType: 'int24' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isAccountSolvent',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: '', type: 'bool', internalType: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'optimizeRiskPartners',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n ],\n outputs: [{ name: '', type: 'uint256', internalType: 'TokenId' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'twapFilter',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'twapWindow', type: 'uint32', internalType: 'uint32' },\n ],\n outputs: [{ name: '', type: 'int24', internalType: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'validateTokenId',\n inputs: [{ name: 'self', type: 'uint256', internalType: 'TokenId' }],\n outputs: [],\n stateMutability: 'pure',\n },\n {\n type: 'error',\n name: 'CastingError',\n inputs: [],\n },\n {\n type: 'error',\n name: 'InvalidTick',\n inputs: [],\n },\n {\n type: 'error',\n name: 'InvalidTokenIdParameter',\n inputs: [{ name: 'parameterType', type: 'uint256', internalType: 'uint256' }],\n },\n {\n type: 'error',\n name: 'LiquidityTooHigh',\n inputs: [],\n },\n {\n type: 'error',\n name: 'UnderOverFlow',\n inputs: [],\n },\n] as const\n","import type { Address, Client, Hex } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\nimport { call } from 'viem/actions'\n\nimport { Multicall3Abi } from '../../../abis/multicall3'\nimport {\n MulticallNoDataError,\n MulticallResultFailedError,\n MulticallResultMissingError,\n} from '../errors'\nimport type { BlockMeta } from '../types'\n\nexport const MULTICALL3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11' as const\n\nexport interface MulticallBlockCall {\n target: Address\n callData: Hex\n}\n\nexport interface MulticallBlockResult {\n success: boolean\n returnData: Hex\n}\n\ninterface ClientWithCall extends Client {\n call: (parameters: { to: Address; data: Hex; blockNumber?: bigint }) => Promise<{ data?: Hex }>\n}\n\nfunction hasCall(client: Client): client is ClientWithCall {\n return 'call' in client && typeof (client as Record<'call', unknown>).call === 'function'\n}\n\nfunction requireResult(\n results: readonly MulticallBlockResult[],\n index: number,\n label: string,\n): MulticallBlockResult {\n const result = results[index]\n if (result === undefined) {\n throw new MulticallResultMissingError(label, index)\n }\n if (!result.success) {\n throw new MulticallResultFailedError(label, index)\n }\n return result\n}\n\nexport function requireReturnData(\n results: readonly MulticallBlockResult[],\n index: number,\n label: string,\n): Hex {\n return requireResult(results, index, label).returnData\n}\n\nexport async function readBlockAndAggregate({\n client,\n calls,\n blockNumber,\n}: {\n client: Client\n calls: readonly MulticallBlockCall[]\n blockNumber?: bigint\n}): Promise<{ _meta: BlockMeta; results: readonly MulticallBlockResult[] }> {\n const aggregateCalls = [\n ...calls,\n {\n target: MULTICALL3_ADDRESS,\n callData: encodeFunctionData({\n abi: Multicall3Abi,\n functionName: 'getCurrentBlockTimestamp',\n }),\n },\n ]\n\n const data = encodeFunctionData({\n abi: Multicall3Abi,\n functionName: 'blockAndAggregate',\n args: [aggregateCalls],\n })\n const parameters = { to: MULTICALL3_ADDRESS, data, blockNumber }\n const response = hasCall(client) ? await client.call(parameters) : await call(client, parameters)\n\n if (response.data === undefined) {\n throw new MulticallNoDataError('blockAndAggregate')\n }\n const aggregateResult = decodeFunctionResult({\n abi: Multicall3Abi,\n functionName: 'blockAndAggregate',\n data: response.data,\n })\n const [aggregateBlockNumber, blockHash, rawResults] = aggregateResult as readonly [\n bigint,\n Hex,\n readonly MulticallBlockResult[],\n ]\n const timestampResult = requireReturnData(\n rawResults,\n calls.length,\n 'Multicall3.getCurrentBlockTimestamp',\n )\n const blockTimestamp = decodeFunctionResult({\n abi: Multicall3Abi,\n functionName: 'getCurrentBlockTimestamp',\n data: timestampResult,\n })\n\n return {\n _meta: {\n blockNumber: aggregateBlockNumber,\n blockHash,\n blockTimestamp,\n },\n results: rawResults.slice(0, calls.length),\n }\n}\n","/**\n * Position and account check functions for the Panoptic v2 SDK.\n *\n * These functions check account liquidatability.\n *\n * @module v2/reads/checks\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { tickToSqrtPriceX96 } from '../formatters/tick'\nimport type { BlockMeta } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { type MulticallBlockCall, readBlockAndAggregate, requireReturnData } from './multicallBlock'\n\nconst FP96 = 1n << 96n\nconst Q128 = 1n << 128n\n\nfunction convert0to1(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n return (amount * sqrtPriceX96 * sqrtPriceX96) >> 192n\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * sp2Hi) >> 128n\n}\n\nfunction convert1to0(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n const denom = sqrtPriceX96 * sqrtPriceX96\n return (amount * (1n << 192n)) / denom\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * (1n << 128n)) / sp2Hi\n}\n\n/**\n * Liquidation check result with detailed margin breakdown.\n *\n * **Denomination**: both per-token pairs hold the gross account total\n * cross-converted to that single token denomination at `atTick`.\n * - `currentMargin0` / `requiredMargin0` are in token0 units\n * - `currentMargin1` / `requiredMargin1` are in token1 units\n *\n * `denominatedInToken` indicates which pair is \"preferred\": 0n when\n * `atTick < 0` (token0), 1n otherwise.\n */\nexport interface LiquidationCheck {\n /** Whether the account is liquidatable */\n isLiquidatable: boolean\n /** Margin shortfall for slot 0 (positive = shortfall, negative = excess) */\n marginShortfall0: bigint\n /** Margin shortfall for slot 1 (positive = shortfall, negative = excess) */\n marginShortfall1: bigint\n /** Current (gross) margin (collateral balance), denominated in token0 */\n currentMargin0: bigint\n /** Current (gross) margin, denominated in token1 */\n currentMargin1: bigint\n /** Required margin (sum of per-position requirements), denominated in token0 */\n requiredMargin0: bigint\n /** Required margin, denominated in token1 */\n requiredMargin1: bigint\n /**\n * Which token the \"preferred\" margin pair is denominated in.\n * 0n = token0 (when atTick < 0), 1n = token1 (when atTick >= 0).\n */\n denominatedInToken: bigint\n /** Tick at which liquidation was checked */\n atTick: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for isLiquidatable.\n */\nexport interface IsLiquidatableParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account to check */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /**\n * Optional: Tick to check liquidation at (defaults to current tick).\n * Note: collateral requirements are evaluated by the contract at the\n * pool's current tick — `atTick` here governs only the cross-token\n * sqrtPrice used to express the totals in a single denomination.\n */\n atTick?: bigint\n /** PanopticQuery address (kept for backwards compatibility; unused). */\n queryAddress?: Address\n /**\n * Optional pre-fetched collateral tracker addresses (saves an RPC).\n * If omitted, they are fetched from the pool.\n */\n collateralAddresses?: { collateralToken0: Address; collateralToken1: Address }\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Check if an account is liquidatable with detailed margin breakdown.\n *\n * Sources gross collateral from `CollateralTracker.assetsOf` and per-position\n * required margin from `PanopticPool.getFullPositionsData.collateralRequirements[]`,\n * cross-converted to each token denomination at `atTick`. Loan tokenIds\n * (width=0 shorts) contribute correctly to required margin.\n *\n * @param params - The parameters\n * @returns Liquidation check result with detailed margin breakdown\n *\n * @example\n * ```typescript\n * const result = await isLiquidatable({\n * client,\n * poolAddress,\n * account,\n * tokenIds: [position1, position2],\n * })\n *\n * if (result.isLiquidatable) {\n * console.log('Account is liquidatable!')\n * }\n * ```\n */\nexport async function isLiquidatable(params: IsLiquidatableParams): Promise<LiquidationCheck> {\n const { client, poolAddress, account, tokenIds, atTick, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Resolve collateral tracker addresses (immutable; cache-friendly).\n let collateralToken0: Address\n let collateralToken1: Address\n if (params.collateralAddresses) {\n collateralToken0 = params.collateralAddresses.collateralToken0\n collateralToken1 = params.collateralAddresses.collateralToken1\n } else {\n const addrs = await client.multicall({\n contracts: [\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken0' },\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken1' },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n })\n collateralToken0 = addrs[0]\n collateralToken1 = addrs[1]\n }\n\n const calls: MulticallBlockCall[] = []\n const currentTickIndex = atTick === undefined ? calls.length : null\n if (currentTickIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n }),\n })\n }\n\n const assets0Index = calls.length\n calls.push({\n target: collateralToken0,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n })\n\n const assets1Index = calls.length\n calls.push({\n target: collateralToken1,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n })\n\n const positionDataIndex = tokenIds.length > 0 ? calls.length : null\n if (positionDataIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, true, tokenIds],\n }),\n })\n }\n\n const { _meta, results } = await readBlockAndAggregate({\n client,\n calls,\n blockNumber: targetBlockNumber,\n })\n\n let effectiveTick = atTick\n if (effectiveTick === undefined) {\n if (currentTickIndex === null) {\n throw new Error('Missing current tick Multicall3 result index')\n }\n effectiveTick = BigInt(\n decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n data: requireReturnData(results, currentTickIndex, 'PanopticPool.getCurrentTick'),\n }),\n )\n }\n const assets0 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, assets0Index, 'CollateralTracker.assetsOf token0'),\n })\n const assets1 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, assets1Index, 'CollateralTracker.assetsOf token1'),\n })\n const positionDataResult =\n positionDataIndex === null\n ? null\n : (decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data: requireReturnData(results, positionDataIndex, 'PanopticPool.getFullPositionsData'),\n }) as readonly [bigint, bigint, readonly bigint[], readonly bigint[], readonly bigint[]])\n\n let required0Native = 0n\n let required1Native = 0n\n if (positionDataResult) {\n const collateralRequirements = positionDataResult[3]\n for (const packed of collateralRequirements) {\n const decoded = decodeLeftRightUnsigned(packed)\n required0Native += decoded.right\n required1Native += decoded.left\n }\n }\n\n const sqrtPriceX96 = tickToSqrtPriceX96(effectiveTick)\n const currentMargin0 = assets0 + convert1to0(assets1, sqrtPriceX96)\n const requiredMargin0 = required0Native + convert1to0(required1Native, sqrtPriceX96)\n const currentMargin1 = assets1 + convert0to1(assets0, sqrtPriceX96)\n const requiredMargin1 = required1Native + convert0to1(required0Native, sqrtPriceX96)\n\n const marginShortfall0 = requiredMargin0 - currentMargin0\n const marginShortfall1 = requiredMargin1 - currentMargin1\n const denominatedInToken: bigint = sqrtPriceX96 < FP96 ? 0n : 1n\n const isLiquidatableResult =\n denominatedInToken === 0n ? marginShortfall0 > 0n : marginShortfall1 > 0n\n\n return {\n isLiquidatable: isLiquidatableResult,\n marginShortfall0,\n marginShortfall1,\n currentMargin0,\n currentMargin1,\n requiredMargin0,\n requiredMargin1,\n denominatedInToken,\n atTick: effectiveTick,\n _meta,\n }\n}\n","/**\n * Account read functions for the Panoptic v2 SDK.\n *\n * ## Same-Block Guarantee\n *\n * All dynamic data is fetched in a SINGLE multicall to ensure block consistency.\n * Per PLAN.md §6, immutable \"static prefetch\" data (addresses) can be fetched\n * separately and cached - it's not subject to same-block consistency.\n *\n * @module v2/reads/account\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type {\n AccountCollateral,\n AccountSummaryBasic,\n AccountSummaryRisk,\n BlockMeta,\n LiquidationPrices,\n NetLiquidationValue,\n NetLiquidationValues,\n TokenCollateral,\n} from '../types'\nimport { isLiquidatable } from './checks'\nimport { type PoolMetadata, getPool } from './pool'\nimport { getPositions } from './position'\n\n/**\n * Collateral tracker addresses (immutable, can be cached).\n */\nexport interface CollateralAddresses {\n /** Collateral tracker 0 address */\n collateralToken0: Address\n /** Collateral tracker 1 address */\n collateralToken1: Address\n}\n\n/**\n * Extract collateral tracker addresses from a Pool object.\n *\n * Convenience helper that avoids re-fetching immutable addresses\n * when you already have a Pool from a prior `getPool()` call.\n *\n * @param pool - Pool object from getPool()\n * @returns Collateral tracker addresses\n */\nexport function getCollateralAddresses(pool: {\n collateralTracker0: { address: Address }\n collateralTracker1: { address: Address }\n}): CollateralAddresses {\n return {\n collateralToken0: pool.collateralTracker0.address,\n collateralToken1: pool.collateralTracker1.address,\n }\n}\n\n/**\n * Parameters for getAccountCollateral.\n */\nexport interface GetAccountCollateralParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral addresses (for caching/optimization) */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get collateral data for an account.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Collateral tracker addresses are either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Account collateral data with block metadata\n */\nexport async function getAccountCollateral(\n params: GetAccountCollateralParams,\n): Promise<AccountCollateral> {\n const { client, poolAddress, account, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get collateral tracker addresses (static prefetch if not provided)\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n // Static prefetch - addresses are immutable\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [dynamicResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n // Token 0 collateral data\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n // Token 1 collateral data\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n // Leg count from pool\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'numberOfLegs',\n args: [account],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [shares0, assets0, maxWithdraw0, shares1, assets1, maxWithdraw1, legCount] = dynamicResults\n\n // Calculate locked assets as total - available (maxWithdraw)\n const locked0 = assets0 > maxWithdraw0 ? assets0 - maxWithdraw0 : 0n\n const locked1 = assets1 > maxWithdraw1 ? assets1 - maxWithdraw1 : 0n\n\n const token0: TokenCollateral = {\n assets: assets0,\n shares: shares0,\n availableAssets: maxWithdraw0,\n lockedAssets: locked0,\n }\n\n const token1: TokenCollateral = {\n assets: assets1,\n shares: shares1,\n availableAssets: maxWithdraw1,\n lockedAssets: locked1,\n }\n\n return {\n account,\n poolAddress,\n token0,\n token1,\n legCount,\n _meta,\n }\n}\n\n/**\n * Parameters for getAccountSummaryBasic.\n */\nexport interface GetAccountSummaryBasicParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Chain ID */\n chainId: bigint\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched pool metadata (for caching/optimization) */\n poolMetadata?: PoolMetadata\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Parameters for getAccountSummaryRisk.\n */\nexport interface GetAccountSummaryRiskParams extends GetAccountSummaryBasicParams {\n /** PanopticQuery address (required for risk fields) */\n queryAddress: Address\n /** Optional: Tick to calculate risk metrics at (defaults to current tick) */\n atTick?: bigint\n /** Optional: Whether to include pending premium in NLV */\n includePendingPremium?: boolean\n}\n\ninterface AccountSummaryCoreData {\n pool: Awaited<ReturnType<typeof getPool>>\n collateral: AccountCollateral\n positions: Awaited<ReturnType<typeof getPositions>>['positions']\n _meta: BlockMeta\n}\n\nasync function getAccountSummaryCore(\n params: GetAccountSummaryBasicParams,\n): Promise<AccountSummaryCoreData> {\n const { client, poolAddress, account, chainId, tokenIds, blockNumber, poolMetadata } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const sharedMeta =\n params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n\n const collateralAddresses = poolMetadata\n ? {\n collateralToken0: poolMetadata.collateralToken0Address,\n collateralToken1: poolMetadata.collateralToken1Address,\n }\n : undefined\n\n const [pool, collateral, { positions }] = await Promise.all([\n getPool({\n client,\n poolAddress,\n chainId,\n blockNumber: targetBlockNumber,\n poolMetadata,\n _meta: sharedMeta,\n }),\n getAccountCollateral({\n client,\n poolAddress,\n account,\n blockNumber: targetBlockNumber,\n collateralAddresses,\n _meta: sharedMeta,\n }),\n getPositions({\n client,\n poolAddress,\n owner: account,\n tokenIds,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n ])\n\n return {\n pool,\n collateral,\n positions,\n _meta: sharedMeta,\n }\n}\n\n/**\n * Get base account summary data for UI dashboards.\n *\n * ## Same-Block Guarantee\n * Uses the same blockNumber for pool, collateral, and position reads.\n *\n * @param params - The parameters\n * @returns Base account summary with block metadata\n */\nexport async function getAccountSummaryBasic(\n params: GetAccountSummaryBasicParams,\n): Promise<AccountSummaryBasic> {\n const { account } = params\n const { pool, collateral, positions, _meta } = await getAccountSummaryCore(params)\n\n return {\n account,\n pool,\n collateral,\n positions,\n healthStatus: pool.healthStatus,\n networkMismatch: false, // Requires wallet context, not available in read functions\n _meta,\n }\n}\n\n/**\n * Get risk-focused account summary including helper-dependent fields.\n *\n * ## Same-Block Guarantee\n * Uses one block target for all pool/collateral/position/risk reads.\n *\n * @param params - The parameters\n * @returns Risk-focused account summary with block metadata\n */\nexport async function getAccountSummaryRisk(\n params: GetAccountSummaryRiskParams,\n): Promise<AccountSummaryRisk> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n queryAddress,\n atTick,\n includePendingPremium = true,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const sharedMeta =\n params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n\n const [{ pool, collateral, positions }, nlv, liquidationCheck, liquidationPrices] =\n await Promise.all([\n getAccountSummaryCore({\n ...params,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n getNetLiquidationValue({\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n includePendingPremium,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n isLiquidatable({\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n getLiquidationPrices({\n client,\n poolAddress,\n account,\n tokenIds,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n ])\n\n const totalGreeks = {\n value: 0n,\n delta: 0n,\n gamma: 0n,\n }\n\n const maintenanceMargin0 = liquidationCheck.requiredMargin0\n const maintenanceMargin1 = liquidationCheck.requiredMargin1\n const marginExcess0 = liquidationCheck.currentMargin0 - liquidationCheck.requiredMargin0\n const marginExcess1 = liquidationCheck.currentMargin1 - liquidationCheck.requiredMargin1\n\n return {\n account,\n pool,\n collateral,\n positions,\n totalGreeks,\n netLiquidationValue0: nlv.value0,\n netLiquidationValue1: nlv.value1,\n maintenanceMargin0,\n maintenanceMargin1,\n marginExcess0,\n marginExcess1,\n marginShortfall0: liquidationCheck.marginShortfall0,\n marginShortfall1: liquidationCheck.marginShortfall1,\n currentMargin0: liquidationCheck.currentMargin0,\n currentMargin1: liquidationCheck.currentMargin1,\n isLiquidatable: liquidationCheck.isLiquidatable,\n liquidationPrices,\n healthStatus: pool.healthStatus,\n networkMismatch: false, // Requires wallet context, not available in read functions\n _meta: sharedMeta,\n }\n}\n\n/**\n * Parameters for getNetLiquidationValue.\n */\nexport interface GetNetLiquidationValueParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Optional: Tick to calculate NLV at (defaults to current tick) */\n atTick?: bigint\n /** Optional: Whether to include pending premium */\n includePendingPremium?: boolean\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get net liquidation value for an account.\n *\n * ## Same-Block Guarantee\n * Tick and NLV are queried at the same target block.\n *\n * Requires PanopticQuery for accurate value and premium accounting.\n *\n * @param params - The parameters\n * @returns Net liquidation value with block metadata\n */\nexport async function getNetLiquidationValue(\n params: GetNetLiquidationValueParams,\n): Promise<NetLiquidationValue> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n includePendingPremium = true,\n queryAddress,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Skip getCurrentTick RPC call when atTick is provided\n const [currentTickResult, _meta] = await Promise.all([\n atTick != null\n ? Promise.resolve(atTick)\n : client\n .readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n .then((r) => BigInt(r)),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const effectiveTick = currentTickResult\n\n // PanopticQuery only exposes the int24[] overload; query a single tick and unwrap.\n const result = await client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getNetLiquidationValue',\n args: [poolAddress, account, includePendingPremium, tokenIds, [Number(effectiveTick)]],\n blockNumber: targetBlockNumber,\n })\n\n const [values0, values1] = result\n const value0 = values0[0]\n const value1 = values1[0]\n\n return {\n value0,\n value1,\n atTick: effectiveTick,\n includedPendingPremium: includePendingPremium,\n _meta,\n }\n}\n\n/**\n * Parameters for getNetLiquidationValues (batch/multi-tick).\n */\nexport interface GetNetLiquidationValuesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Ticks to calculate NLV at */\n atTicks: bigint[]\n /** Optional: Whether to include pending premium */\n includePendingPremium?: boolean\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get net liquidation values at multiple ticks in a single contract call.\n *\n * Uses the `int24[]` overload of `getNetLiquidationValue` on PanopticQuery.\n *\n * @param params - The parameters\n * @returns Net liquidation values with block metadata\n */\nexport async function getNetLiquidationValues(\n params: GetNetLiquidationValuesParams,\n): Promise<NetLiquidationValues> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n atTicks,\n includePendingPremium = true,\n queryAddress,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Use an isolated ABI with only the int24[] overload to avoid viem overload ambiguity\n const batchNlvAbi = [\n {\n type: 'function' as const,\n name: 'getNetLiquidationValue' as const,\n inputs: [\n { name: 'pool', type: 'address' as const },\n { name: 'account', type: 'address' as const },\n { name: 'includePendingPremium', type: 'bool' as const },\n { name: 'positionIdList', type: 'uint256[]' as const },\n { name: 'atTicks', type: 'int24[]' as const },\n ],\n outputs: [\n { name: 'value0', type: 'int256[]' as const },\n { name: 'value1', type: 'int256[]' as const },\n ],\n stateMutability: 'view' as const,\n },\n ] as const\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: batchNlvAbi,\n functionName: 'getNetLiquidationValue',\n args: [poolAddress, account, includePendingPremium, tokenIds, atTicks.map((t) => Number(t))],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [values0, values1] = result\n\n return {\n values0: [...values0],\n values1: [...values1],\n atTicks,\n _meta,\n }\n}\n\n/**\n * Parameters for getLiquidationPrices.\n */\nexport interface GetLiquidationPricesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get liquidation prices for an account.\n *\n * ## Same-Block Guarantee\n * Liquidation price query is made at a single block.\n *\n * @param params - The parameters\n * @returns Liquidation prices with block metadata\n */\nexport async function getLiquidationPrices(\n params: GetLiquidationPricesParams,\n): Promise<LiquidationPrices> {\n const { client, poolAddress, account, tokenIds, queryAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // MIN_TICK and MAX_TICK indicate no liquidation at that boundary\n const MIN_TICK = -887272n\n const MAX_TICK = 887272n\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getLiquidationPrices',\n args: [poolAddress, account, tokenIds],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // Convert from number (abitype default for int24) to bigint (viem runtime type)\n const liqPriceDown = BigInt(result[0])\n const liqPriceUp = BigInt(result[1])\n\n return {\n lowerTick: liqPriceDown === MIN_TICK ? null : liqPriceDown,\n upperTick: liqPriceUp === MAX_TICK ? null : liqPriceUp,\n isLiquidatable: liqPriceDown !== MIN_TICK || liqPriceUp !== MAX_TICK,\n _meta,\n }\n}\n","/**\n * Collateral read functions for the Panoptic v2 SDK.\n *\n * ## Same-Block Guarantee\n *\n * All dynamic data is fetched in a SINGLE multicall to ensure block consistency.\n * Per PLAN.md §6, immutable \"static prefetch\" data (addresses, symbols, decimals)\n * can be fetched separately and cached - it's not subject to same-block consistency.\n *\n * @module v2/reads/collateral\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta, CollateralTracker, CurrentRates } from '../types'\n\nconst SECONDS_PER_YEAR = 31_536_000n\n\n// ERC20 minimal ABI for token metadata\nconst erc20Abi = [\n {\n type: 'function',\n name: 'symbol',\n inputs: [],\n outputs: [{ type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'decimals',\n inputs: [],\n outputs: [{ type: 'uint8' }],\n stateMutability: 'view',\n },\n] as const\n\n/**\n * Pre-fetched collateral tracker metadata (immutable, can be cached).\n */\nexport interface CollateralTrackerMetadata {\n /** Collateral tracker address */\n address: Address\n /** Underlying asset address */\n assetAddress: Address\n /** Token symbol */\n symbol: string\n /** Token decimals */\n decimals: bigint\n}\n\n/**\n * Parameters for getCollateralData.\n */\nexport interface GetCollateralDataParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Which token's collateral tracker to query (0 or 1) */\n tokenIndex: 0 | 1\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker metadata (for caching/optimization) */\n trackerMetadata?: CollateralTrackerMetadata\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get collateral tracker data for a specific token.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Static metadata (address, symbol, decimals) is either provided or fetched separately.\n *\n * @param params - The parameters\n * @returns Collateral tracker data with block metadata\n */\nexport async function getCollateralData(\n params: GetCollateralDataParams,\n): Promise<CollateralTracker & { _meta: BlockMeta }> {\n const { client, poolAddress, tokenIndex, blockNumber, trackerMetadata } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // If metadata is provided, we only need ONE multicall for dynamic data\n if (trackerMetadata) {\n const [dynamicResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [poolData, totalShares, interestRate] = dynamicResults\n const [depositedAssets, insideAMM, creditedShares, utilization] = poolData\n const totalAssets = depositedAssets + insideAMM\n\n const borrowRate = BigInt(interestRate) * SECONDS_PER_YEAR\n const supplyRate = (borrowRate * utilization) / 10000n\n\n return {\n address: trackerMetadata.address,\n token: trackerMetadata.assetAddress,\n symbol: trackerMetadata.symbol,\n decimals: trackerMetadata.decimals,\n totalAssets,\n insideAMM,\n creditedShares,\n totalShares,\n utilization,\n borrowRate,\n supplyRate,\n _meta,\n }\n }\n\n // Without metadata, fetch everything (original structure for backwards compatibility)\n // 1. Get tracker address (static)\n const collateralTrackerAddress = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: tokenIndex === 0 ? 'collateralToken0' : 'collateralToken1',\n })\n\n // 2. Get asset + dynamic data in one multicall (same-block guarantee for dynamic data)\n const [trackerData, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [assetAddress, poolData, totalShares, interestRate] = trackerData\n\n // 3. Get token metadata (static - can be cached)\n const [symbol, decimals] = await client.multicall({\n contracts: [\n {\n address: assetAddress,\n abi: erc20Abi,\n functionName: 'symbol',\n },\n {\n address: assetAddress,\n abi: erc20Abi,\n functionName: 'decimals',\n },\n ],\n allowFailure: false,\n })\n\n // poolData returns: (depositedAssets, insideAMM, creditedShares, currentPoolUtilization)\n const [depositedAssets, insideAMM, creditedShares, utilization] = poolData\n const totalAssets = depositedAssets + insideAMM\n\n // Annualize rates: interestRate() returns WAD/s\n const borrowRate = BigInt(interestRate) * SECONDS_PER_YEAR\n const supplyRate = (borrowRate * utilization) / 10000n\n\n return {\n address: collateralTrackerAddress,\n token: assetAddress,\n symbol,\n decimals: BigInt(decimals),\n totalAssets,\n insideAMM,\n creditedShares,\n totalShares,\n utilization,\n borrowRate,\n supplyRate,\n _meta,\n }\n}\n\n/**\n * Collateral tracker addresses (immutable, can be cached).\n */\nexport interface CollateralAddresses {\n /** Collateral tracker 0 address */\n collateralToken0: Address\n /** Collateral tracker 1 address */\n collateralToken1: Address\n}\n\n/**\n * Parameters for getCurrentRates.\n */\nexport interface GetCurrentRatesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker addresses (for caching/optimization) */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get current interest rates for both tokens.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Collateral tracker addresses are either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Current rates with block metadata\n */\nexport async function getCurrentRates(params: GetCurrentRatesParams): Promise<CurrentRates> {\n const { client, poolAddress, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get collateral tracker addresses (static prefetch if not provided)\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n // Static prefetch - addresses are immutable\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [rateData, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [interestRate0, poolData0, interestRate1, poolData1] = rateData\n\n // Extract utilization from pool data\n const utilization0 = poolData0[3]\n const utilization1 = poolData1[3]\n\n // Annualize rates: interestRate() returns WAD/s\n const borrowRate0 = BigInt(interestRate0) * SECONDS_PER_YEAR\n const borrowRate1 = BigInt(interestRate1) * SECONDS_PER_YEAR\n\n // Supply rate = borrow rate * utilization (utilization is in bps, so /10000)\n const supplyRate0 = (borrowRate0 * utilization0) / 10000n\n const supplyRate1 = (borrowRate1 * utilization1) / 10000n\n\n return {\n borrowRate0,\n supplyRate0,\n borrowRate1,\n supplyRate1,\n _meta,\n }\n}\n\n// ─── Interest State (per-user borrows) ───────────────────────────────────────\n\n/**\n * Per-user interest state for a single collateral tracker.\n */\nexport interface TokenInterestState {\n /** User's borrow index snapshot (int128) */\n userBorrowIndex: bigint\n /** User's net borrows: positive = borrowing, negative = net supplying (int128) */\n netBorrows: bigint\n}\n\n/**\n * Interest state for both tokens in a Panoptic pool.\n */\nexport interface InterestState {\n /** Token 0 interest state */\n token0: TokenInterestState\n /** Token 1 interest state */\n token1: TokenInterestState\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getInterestState.\n */\nexport interface GetInterestStateParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address to query */\n account: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker addresses */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata */\n _meta?: BlockMeta\n}\n\n/**\n * Get per-user interest state (borrow index + net borrows) for both tokens.\n *\n * Calls `collateralTracker.interestState(user)` on both trackers in a single multicall.\n *\n * @param params - The parameters\n * @returns Interest state for both tokens with block metadata\n */\nexport async function getInterestState(params: GetInterestStateParams): Promise<InterestState> {\n const { client, poolAddress, account, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n const [results, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'interestState',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'interestState',\n args: [account],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [state0, state1] = results\n\n return {\n token0: { userBorrowIndex: state0[0], netBorrows: state0[1] },\n token1: { userBorrowIndex: state1[0], netBorrows: state1[1] },\n _meta,\n }\n}\n","/**\n * Token amount formatters and parsers.\n *\n * All formatters require explicit precision - no hidden defaults.\n *\n * @module v2/formatters/amount\n */\n\nimport type { TokenFlow } from '../types'\n\n/**\n * Format a raw token amount to a human-readable string.\n *\n * @param amount - The amount in smallest units (e.g., wei)\n * @param decimals - Token decimals (e.g., 18n for WETH, 6n for USDC)\n * @param precision - Number of decimal places to display\n * @returns Formatted string\n *\n * @example\n * ```typescript\n * formatTokenAmount(1500000000000000000n, 18n, 4n) // \"1.5000\"\n * formatTokenAmount(1500000000000000000n, 18n, 2n) // \"1.50\"\n * formatTokenAmount(1500000n, 6n, 2n) // \"1.50\" (USDC)\n * formatTokenAmount(-500000000000000000n, 18n, 4n) // \"-0.5000\"\n * ```\n */\nexport function formatTokenAmount(amount: bigint, decimals: bigint, precision: bigint): string {\n const isNegative = amount < 0n\n const absAmount = isNegative ? -amount : amount\n const divisor = 10n ** decimals\n const integerPart = absAmount / divisor\n const fractionalPart = absAmount % divisor\n\n // Build fractional string with proper padding\n const fullFractionalStr = fractionalPart.toString().padStart(Number(decimals), '0')\n const truncatedFractionalStr = fullFractionalStr.slice(0, Number(precision))\n const paddedFractionalStr = truncatedFractionalStr.padEnd(Number(precision), '0')\n\n const sign = isNegative ? '-' : ''\n return precision > 0n ? `${sign}${integerPart}.${paddedFractionalStr}` : `${sign}${integerPart}`\n}\n\n/**\n * Format a token amount with a sign prefix (+/-) for non-zero values.\n * Useful for displaying PnL, deltas, or changes.\n *\n * @param amount - The amount in smallest units\n * @param decimals - Token decimals\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n *\n * @example\n * ```typescript\n * formatTokenAmountSigned(1500000000000000000n, 18n, 4n) // \"+1.5000\"\n * formatTokenAmountSigned(-500000000000000000n, 18n, 4n) // \"-0.5000\"\n * formatTokenAmountSigned(0n, 18n, 4n) // \"0.0000\"\n * ```\n */\nexport function formatTokenAmountSigned(\n amount: bigint,\n decimals: bigint,\n precision: bigint,\n): string {\n const formatted = formatTokenAmount(amount, decimals, precision)\n if (amount > 0n) {\n return `+${formatted}`\n }\n return formatted\n}\n\n/**\n * Parse a human-readable token amount string to raw units.\n *\n * @param amount - Human-readable amount string (e.g., \"1.5\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n *\n * @example\n * ```typescript\n * parseTokenAmount(\"1.5\", 18n) // 1500000000000000000n\n * parseTokenAmount(\"1.5\", 6n) // 1500000n (USDC)\n * parseTokenAmount(\"100\", 18n) // 100000000000000000000n\n * parseTokenAmount(\"-0.5\", 18n) // -500000000000000000n\n * ```\n */\nexport function parseTokenAmount(amount: string, decimals: bigint): bigint {\n const trimmed = amount.trim()\n const isNegative = trimmed.startsWith('-')\n const cleanAmount = isNegative ? trimmed.slice(1) : trimmed\n\n const [integerStr, fractionalStr = ''] = cleanAmount.split('.')\n const paddedFractional = fractionalStr.padEnd(Number(decimals), '0').slice(0, Number(decimals))\n\n const integerPart = BigInt(integerStr || '0') * 10n ** decimals\n const fractionalPart = BigInt(paddedFractional || '0')\n\n const result = integerPart + fractionalPart\n return isNegative ? -result : result\n}\n\n/**\n * Format a token delta amount with a sign prefix (+/-) for non-zero values.\n * Alias for formatTokenAmountSigned, useful for clarity at call sites.\n *\n * @param amount - The delta amount in smallest units\n * @param decimals - Token decimals\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n */\nexport function formatTokenDelta(amount: bigint, decimals: bigint, precision: bigint): string {\n return formatTokenAmountSigned(amount, decimals, precision)\n}\n\n/**\n * Format token flow deltas and balances from simulation results.\n *\n * @param flow - Token flow data\n * @param decimals0 - Token0 decimals\n * @param decimals1 - Token1 decimals\n * @param precision0 - Precision for token0 formatting\n * @param precision1 - Precision for token1 formatting\n * @returns Formatted token flow strings\n */\nexport function formatTokenFlow(\n flow: TokenFlow,\n decimals0: bigint,\n decimals1: bigint,\n precision0: bigint,\n precision1: bigint,\n): {\n delta0: string\n delta1: string\n balanceBefore0: string\n balanceBefore1: string\n balanceAfter0: string\n balanceAfter1: string\n} {\n return {\n delta0: formatTokenAmountSigned(flow.delta0, decimals0, precision0),\n delta1: formatTokenAmountSigned(flow.delta1, decimals1, precision1),\n balanceBefore0: formatTokenAmount(flow.balanceBefore0, decimals0, precision0),\n balanceBefore1: formatTokenAmount(flow.balanceBefore1, decimals1, precision1),\n balanceAfter0: formatTokenAmount(flow.balanceAfter0, decimals0, precision0),\n balanceAfter1: formatTokenAmount(flow.balanceAfter1, decimals1, precision1),\n }\n}\n","/**\n * WAD-scaled value formatters.\n *\n * WAD is a fixed-point representation where 1e18 = 1.0.\n * Used extensively in DeFi for representing ratios, prices, and multipliers.\n *\n * @module v2/formatters/wad\n */\n\nimport { formatTokenAmount } from './amount'\n\n/**\n * Format a WAD-scaled value (1e18 = 1.0).\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted string\n *\n * @example\n * ```typescript\n * formatWad(1220000000000000000n, 2n) // \"1.22\"\n * formatWad(1220000000000000000n, 4n) // \"1.2200\"\n * formatWad(1000000000000000000n, 2n) // \"1.00\"\n * formatWad(500000000000000000n, 2n) // \"0.50\"\n * ```\n */\nexport function formatWad(wad: bigint, precision: bigint): string {\n return formatTokenAmount(wad, 18n, precision)\n}\n\n/**\n * Format a WAD-scaled value with sign prefix (+/-) for non-zero values.\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n *\n * @example\n * ```typescript\n * formatWadSigned(1220000000000000000n, 2n) // \"+1.22\"\n * formatWadSigned(-500000000000000000n, 2n) // \"-0.50\"\n * formatWadSigned(0n, 2n) // \"0.00\"\n * ```\n */\nexport function formatWadSigned(wad: bigint, precision: bigint): string {\n const formatted = formatWad(wad, precision)\n if (wad > 0n) {\n return `+${formatted}`\n }\n return formatted\n}\n\n/**\n * Format a WAD-scaled value as a percentage string.\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n *\n * @example\n * ```typescript\n * formatWadPercent(50000000000000000n, 2n) // \"5.00%\"\n * formatWadPercent(1000000000000000000n, 1n) // \"100.0%\"\n * ```\n */\nexport function formatWadPercent(wad: bigint, precision: bigint): string {\n return `${formatTokenAmount(wad * 100n, 18n, precision)}%`\n}\n\n/**\n * Format an annualized rate stored as a WAD-scaled value.\n * Alias for formatWadPercent.\n *\n * @param rateWad - Rate in WAD (1e18 = 1.0)\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n */\nexport function formatRateWad(rateWad: bigint, precision: bigint): string {\n return formatWadPercent(rateWad, precision)\n}\n\n/**\n * Parse a decimal string to a WAD-scaled value.\n *\n * @param value - Decimal string (e.g., \"1.5\")\n * @returns WAD-scaled bigint\n *\n * @example\n * ```typescript\n * parseWad(\"1.5\") // 1500000000000000000n\n * parseWad(\"0.5\") // 500000000000000000n\n * parseWad(\"100\") // 100000000000000000000n\n * parseWad(\"-1.22\") // -1220000000000000000n\n * ```\n */\nexport function parseWad(value: string): bigint {\n const trimmed = value.trim()\n const isNegative = trimmed.startsWith('-')\n const cleanValue = isNegative ? trimmed.slice(1) : trimmed\n\n const [integerStr, fractionalStr = ''] = cleanValue.split('.')\n const paddedFractional = fractionalStr.padEnd(18, '0').slice(0, 18)\n\n const integerPart = BigInt(integerStr || '0') * 10n ** 18n\n const fractionalPart = BigInt(paddedFractional || '0')\n\n const result = integerPart + fractionalPart\n return isNegative ? -result : result\n}\n","/**\n * Per-second rate helpers.\n *\n * Collateral tracker rates are returned as WAD-scaled per-second rates.\n * These helpers annualize them for display.\n *\n * @module v2/formatters/rates\n */\n\nimport { formatWadPercent } from './wad'\n\nconst SECONDS_PER_DAY = 86_400n\nconst DAYS_PER_YEAR = 365n\nconst SECONDS_PER_YEAR = SECONDS_PER_DAY * DAYS_PER_YEAR\n\n/**\n * Annualize a per-second WAD-scaled rate to annual WAD.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @returns Annualized rate in WAD\n */\nexport function annualizePerSecondRateWad(ratePerSecondWad: bigint): bigint {\n return ratePerSecondWad * SECONDS_PER_YEAR\n}\n\n/**\n * Format a per-second WAD rate as APY percentage text.\n * Uses linear annualization, then formats as WAD percent.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @param precision - Decimal places\n * @returns Percentage string, e.g. \"2.41%\"\n */\nexport function formatPerSecondRateWadAsApyPct(\n ratePerSecondWad: bigint,\n precision: bigint,\n): string {\n return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision)\n}\n\n/**\n * Format a per-second WAD rate as APR percentage text.\n * For this rate model, APR presentation uses the same annualized output.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @param precision - Decimal places\n * @returns Percentage string, e.g. \"2.41%\"\n */\nexport function formatPerSecondRateWadAsAprPct(\n ratePerSecondWad: bigint,\n precision: bigint,\n): string {\n return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision)\n}\n","/**\n * Interest rate model (IRM) reads for Panoptic v2.\n * @module v2/reads/irm\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, riskEngineAbi } from '../../../generated'\nimport { PanopticValidationError } from '../errors/sdk'\nimport type { IrmCurrent, IrmMarketStateInputs, IrmPoint } from '../types/irm'\nexport type { IrmCurrent, IrmMarketStateInputs, IrmPoint } from '../types/irm'\n\nexport const WAD = 10n ** 18n\nexport const BPS_SCALE = 10_000n\nexport const SECONDS_PER_YEAR = 31_536_000n\nexport const MARKET_EPOCH_SHIFT = 2n\nexport const BORROW_INDEX_BITS = 80n\nexport const MARKET_EPOCH_BITS = 32n\nexport const RATE_AT_TARGET_BITS = 38n\nexport const UNREALIZED_INTEREST_BITS = 106n\n\nconst BORROW_INDEX_SHIFT = 0n\nconst MARKET_EPOCH_FIELD_SHIFT = BORROW_INDEX_BITS\nconst RATE_AT_TARGET_FIELD_SHIFT = BORROW_INDEX_BITS + MARKET_EPOCH_BITS\nconst UNREALIZED_INTEREST_FIELD_SHIFT = RATE_AT_TARGET_FIELD_SHIFT + RATE_AT_TARGET_BITS\nconst MAX_IRM_CURVE_POINTS = 500\n\nconst clampUtilizationBps = (utilizationBps: bigint): bigint => {\n if (utilizationBps < 0n) {\n return 0n\n }\n if (utilizationBps > BPS_SCALE) {\n return BPS_SCALE\n }\n return utilizationBps\n}\n\nconst getMaxValue = (bits: bigint): bigint => (1n << bits) - 1n\n\nconst assertFitsBits = (value: bigint, bits: bigint, fieldName: string): void => {\n if (value < 0n) {\n throw new PanopticValidationError(`${fieldName} must be >= 0`)\n }\n if (value > getMaxValue(bits)) {\n throw new PanopticValidationError(`${fieldName} exceeds ${bits.toString()} bits`)\n }\n}\n\nexport function packMarketState(inputs: IrmMarketStateInputs): bigint {\n const { borrowIndex, lastInteractionTimestamp, rateAtTarget, unrealizedGlobalInterest } = inputs\n const marketEpoch = lastInteractionTimestamp >> MARKET_EPOCH_SHIFT\n\n assertFitsBits(borrowIndex, BORROW_INDEX_BITS, 'borrowIndex')\n assertFitsBits(marketEpoch, MARKET_EPOCH_BITS, 'marketEpoch')\n assertFitsBits(rateAtTarget, RATE_AT_TARGET_BITS, 'rateAtTarget')\n assertFitsBits(unrealizedGlobalInterest, UNREALIZED_INTEREST_BITS, 'unrealizedGlobalInterest')\n\n return (\n (borrowIndex << BORROW_INDEX_SHIFT) +\n (marketEpoch << MARKET_EPOCH_FIELD_SHIFT) +\n (rateAtTarget << RATE_AT_TARGET_FIELD_SHIFT) +\n (unrealizedGlobalInterest << UNREALIZED_INTEREST_FIELD_SHIFT)\n )\n}\n\nexport function utilizationPctToWad(utilizationPct: number): bigint {\n if (!Number.isFinite(utilizationPct)) {\n throw new PanopticValidationError('utilizationPct must be finite')\n }\n if (utilizationPct < 0 || utilizationPct > 100) {\n throw new PanopticValidationError('utilizationPct must be between 0 and 100')\n }\n\n const scaledPct = Math.round(utilizationPct * 1_000_000)\n return (BigInt(scaledPct) * WAD) / 100_000_000n\n}\n\nexport function utilizationBpsToWad(utilizationBps: bigint): bigint {\n return (clampUtilizationBps(utilizationBps) * WAD) / BPS_SCALE\n}\n\nexport function ratePerSecWadToAprPct(ratePerSecWad: bigint): number {\n return (Number(ratePerSecWad) * Number(SECONDS_PER_YEAR) * 100) / Number(WAD)\n}\n\nexport function deriveSupplyRatePerSecWad(\n borrowRatePerSecWad: bigint,\n utilizationWad: bigint,\n): bigint {\n return (borrowRatePerSecWad * utilizationWad) / WAD\n}\n\nexport async function getIrmCurrent(params: {\n client: PublicClient\n collateralTrackerAddress: Address\n blockNumber?: bigint\n}): Promise<IrmCurrent> {\n const { client, collateralTrackerAddress, blockNumber } = params\n const [\n borrowIndex,\n lastInteractionTimestamp,\n rateAtTarget,\n unrealizedGlobalInterest,\n poolData,\n riskEngineAddress,\n ] = await client.multicall({\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'borrowIndex',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'lastInteractionTimestamp',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'rateAtTarget',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'unrealizedGlobalInterest',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'riskEngine',\n },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n const currentUtilizationBps = clampUtilizationBps(poolData[3])\n const currentUtilizationWad = utilizationBpsToWad(currentUtilizationBps)\n const currentUtilizationPct = Number(currentUtilizationBps) / 100\n\n const marketStatePacked = packMarketState({\n borrowIndex,\n lastInteractionTimestamp,\n rateAtTarget,\n unrealizedGlobalInterest,\n })\n\n const borrowRatePerSecWad = await client.readContract({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'interestRate',\n args: [currentUtilizationWad, marketStatePacked],\n blockNumber,\n })\n\n const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, currentUtilizationWad)\n\n return {\n collateralTrackerAddress,\n riskEngineAddress,\n currentUtilizationBps,\n currentUtilizationWad,\n currentUtilizationPct,\n borrowRatePerSecWad,\n supplyRatePerSecWad,\n borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),\n supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad),\n marketStatePacked,\n }\n}\n\nexport async function getIrmCurve(params: {\n client: PublicClient\n collateralTrackerAddress: Address\n points?: number\n blockNumber?: bigint\n}): Promise<{\n current: IrmCurrent\n points: IrmPoint[]\n}> {\n const { client, collateralTrackerAddress, points = 201, blockNumber } = params\n\n if (!Number.isInteger(points) || points < 2) {\n throw new PanopticValidationError('points must be an integer >= 2')\n }\n if (points > MAX_IRM_CURVE_POINTS) {\n throw new PanopticValidationError(`points must be <= ${MAX_IRM_CURVE_POINTS}`)\n }\n\n const current = await getIrmCurrent({\n client,\n collateralTrackerAddress,\n blockNumber,\n })\n\n const denominator = BigInt(points - 1)\n const contracts = Array.from({ length: points }, (_, idx) => {\n const i = BigInt(idx)\n const utilizationWad = (i * WAD) / denominator\n\n return {\n address: current.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'interestRate' as const,\n args: [utilizationWad, current.marketStatePacked] as const,\n }\n })\n\n const borrowRatesPerSecWad = await client.multicall({\n contracts,\n blockNumber,\n allowFailure: false,\n })\n\n const curvePoints: IrmPoint[] = borrowRatesPerSecWad.map((borrowRatePerSecWad, idx) => {\n const i = BigInt(idx)\n const utilizationWad = (i * WAD) / denominator\n const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, utilizationWad)\n\n return {\n utilizationWad,\n utilizationPct: (idx * 100) / (points - 1),\n borrowRatePerSecWad,\n supplyRatePerSecWad,\n borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),\n supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad),\n }\n })\n\n return {\n current,\n points: curvePoints,\n }\n}\n"],"mappings":";;;;;AAAA,MAAa,gBAAgB;CAC3B;EACE,QAAQ,CACN;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY;IACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;GACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY;IACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;GACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS;GACP;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,YAAY,CACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,GACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,CACF;IACD,cAAc;IACd,MAAM;IACN,MAAM;GACP;EACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS;GACP;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,YAAY,CACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,GACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,CACF;IACD,cAAc;IACd,MAAM;IACN,MAAM;GACP;EACF;EACD,iBAAiB;EACjB,MAAM;CACP;AACF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"}
1
+ {"version":3,"file":"irm-y3T4tvfM.js","names":["client: Client","results: readonly MulticallBlockResult[]","index: number","label: string","amount: bigint","sqrtPriceX96: bigint","params: IsLiquidatableParams","collateralToken0: Address","collateralToken1: Address","calls: MulticallBlockCall[]","denominatedInToken: bigint","pool: {\n collateralTracker0: { address: Address }\n collateralTracker1: { address: Address }\n}","params: GetAccountCollateralParams","collateralToken0: Address","collateralToken1: Address","token0: TokenCollateral","token1: TokenCollateral","params: GetAccountSummaryBasicParams","params: GetAccountSummaryRiskParams","params: GetNetLiquidationValueParams","params: GetNetLiquidationValuesParams","params: GetLiquidationPricesParams","SECONDS_PER_YEAR","erc20Abi","params: GetCollateralDataParams","_meta","poolData","totalShares","interestRate","depositedAssets","insideAMM","creditedShares","utilization","totalAssets","borrowRate","supplyRate","params: GetCurrentRatesParams","collateralToken0: Address","collateralToken1: Address","params: GetInterestStateParams","amount: bigint","decimals: bigint","precision: bigint","amount: string","flow: TokenFlow","decimals0: bigint","decimals1: bigint","precision0: bigint","precision1: bigint","wad: bigint","precision: bigint","rateWad: bigint","value: string","SECONDS_PER_YEAR","ratePerSecondWad: bigint","precision: bigint","utilizationBps: bigint","bits: bigint","value: bigint","fieldName: string","inputs: IrmMarketStateInputs","utilizationPct: number","ratePerSecWad: bigint","borrowRatePerSecWad: bigint","utilizationWad: bigint","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n blockNumber?: bigint\n}","params: {\n client: PublicClient\n collateralTrackerAddress: Address\n points?: number\n blockNumber?: bigint\n}","curvePoints: IrmPoint[]"],"sources":["../src/abis/multicall3.ts","../src/panoptic/v2/abis/panopticQuery.ts","../src/panoptic/v2/reads/multicallBlock.ts","../src/panoptic/v2/reads/checks.ts","../src/panoptic/v2/reads/account.ts","../src/panoptic/v2/reads/collateral.ts","../src/panoptic/v2/formatters/amount.ts","../src/panoptic/v2/formatters/wad.ts","../src/panoptic/v2/formatters/rates.ts","../src/panoptic/v2/reads/irm.ts"],"sourcesContent":["export const Multicall3Abi = [\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes[]',\n name: 'returnData',\n type: 'bytes[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bool',\n name: 'allowFailure',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call3[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate3',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bool',\n name: 'allowFailure',\n type: 'bool',\n },\n {\n internalType: 'uint256',\n name: 'value',\n type: 'uint256',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call3Value[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'aggregate3Value',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'blockAndAggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getBasefee',\n outputs: [\n {\n internalType: 'uint256',\n name: 'basefee',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n ],\n name: 'getBlockHash',\n outputs: [\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getBlockNumber',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getChainId',\n outputs: [\n {\n internalType: 'uint256',\n name: 'chainid',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockCoinbase',\n outputs: [\n {\n internalType: 'address',\n name: 'coinbase',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockDifficulty',\n outputs: [\n {\n internalType: 'uint256',\n name: 'difficulty',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockGasLimit',\n outputs: [\n {\n internalType: 'uint256',\n name: 'gaslimit',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getCurrentBlockTimestamp',\n outputs: [\n {\n internalType: 'uint256',\n name: 'timestamp',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'addr',\n type: 'address',\n },\n ],\n name: 'getEthBalance',\n outputs: [\n {\n internalType: 'uint256',\n name: 'balance',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'getLastBlockHash',\n outputs: [\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'bool',\n name: 'requireSuccess',\n type: 'bool',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'tryAggregate',\n outputs: [\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'bool',\n name: 'requireSuccess',\n type: 'bool',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'target',\n type: 'address',\n },\n {\n internalType: 'bytes',\n name: 'callData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Call[]',\n name: 'calls',\n type: 'tuple[]',\n },\n ],\n name: 'tryBlockAndAggregate',\n outputs: [\n {\n internalType: 'uint256',\n name: 'blockNumber',\n type: 'uint256',\n },\n {\n internalType: 'bytes32',\n name: 'blockHash',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'bool',\n name: 'success',\n type: 'bool',\n },\n {\n internalType: 'bytes',\n name: 'returnData',\n type: 'bytes',\n },\n ],\n internalType: 'struct Multicall3.Result[]',\n name: 'returnData',\n type: 'tuple[]',\n },\n ],\n stateMutability: 'payable',\n type: 'function',\n },\n] as const\n","/**\n * PanopticQuery contract ABI\n * Auto-generated from PanopticQuery.json\n * @module abis/panopticQuery\n */\n\nexport const panopticQueryAbi = [\n {\n type: 'constructor',\n inputs: [\n {\n name: 'SFPM_',\n type: 'address',\n internalType: 'contract ISemiFungiblePositionManager',\n },\n ],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n name: 'checkCollateral',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'collateralBalances0', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'requiredCollaterals0', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'collateralBalances1', type: 'uint256[4]', internalType: 'uint256[4]' },\n { name: 'requiredCollaterals1', type: 'uint256[4]', internalType: 'uint256[4]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'checkCollateral',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: 'balancesAndRequired', type: 'uint256[4]', internalType: 'uint256[4]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'checkCollateralListOutput',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: '', type: 'uint256[2][]', internalType: 'uint256[2][]' },\n { name: '', type: 'int256[]', internalType: 'int256[]' },\n { name: '', type: 'int24[]', internalType: 'int24[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'computeMedianObservedPrice',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'cardinality', type: 'uint256', internalType: 'uint256' },\n { name: 'period', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [{ name: 'medianTick', type: 'int24', internalType: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getChunkData',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [{ name: '', type: 'uint256[2][4][]', internalType: 'uint256[2][4][]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'scanChunks',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'tickLower', type: 'int24', internalType: 'int24' },\n { name: 'tickUpper', type: 'int24', internalType: 'int24' },\n { name: 'width', type: 'int24', internalType: 'int24' },\n ],\n outputs: [\n { name: 'strikes', type: 'int24[]', internalType: 'int24[]' },\n { name: 'netLiquidities', type: 'uint128[2][]', internalType: 'uint128[2][]' },\n { name: 'removedLiquidities', type: 'uint128[2][]', internalType: 'uint128[2][]' },\n { name: 'settledTokens', type: 'uint256[2][]', internalType: 'LeftRightUnsigned[2][]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getLiquidationPrices',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'liquidationPriceDown', type: 'int24', internalType: 'int24' },\n { name: 'liquidationPriceUp', type: 'int24', internalType: 'int24' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getMaxPositionSizeBounds',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'existingPositionIds', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n ],\n outputs: [\n { name: 'maxSizeAtMinUtil', type: 'uint128', internalType: 'uint128' },\n { name: 'maxSizeAtMaxUtil', type: 'uint128', internalType: 'uint128' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getNetLiquidationValue',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'includePendingPremium', type: 'bool', internalType: 'bool' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTicks', type: 'int24[]', internalType: 'int24[]' },\n ],\n outputs: [\n { name: 'value0', type: 'int256[]', internalType: 'int256[]' },\n { name: 'value1', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getPortfolioValue',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n ],\n outputs: [\n { name: 'value0', type: 'int256', internalType: 'int256' },\n { name: 'value1', type: 'int256', internalType: 'int256' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getRequiredBase',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNets',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNetsV3',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getTickNetsV4',\n inputs: [\n { name: 'manager', type: 'address', internalType: 'contract IPoolManager' },\n { name: 'poolId', type: 'bytes32', internalType: 'PoolId' },\n { name: 'tickSpacing', type: 'int24', internalType: 'int24' },\n { name: 'startTick', type: 'int24', internalType: 'int24' },\n { name: 'nTicks', type: 'uint256', internalType: 'uint256' },\n ],\n outputs: [\n { name: 'tickData', type: 'int256[]', internalType: 'int256[]' },\n { name: 'liquidityNets', type: 'int256[]', internalType: 'int256[]' },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isAccountSolvent',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'account', type: 'address', internalType: 'address' },\n { name: 'positionIdList', type: 'uint256[]', internalType: 'TokenId[]' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n ],\n outputs: [{ name: '', type: 'bool', internalType: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'optimizeRiskPartners',\n inputs: [\n { name: 'pool', type: 'address', internalType: 'contract PanopticPool' },\n { name: 'atTick', type: 'int24', internalType: 'int24' },\n { name: 'tokenId', type: 'uint256', internalType: 'TokenId' },\n ],\n outputs: [{ name: '', type: 'uint256', internalType: 'TokenId' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'twapFilter',\n inputs: [\n { name: 'univ3pool', type: 'address', internalType: 'contract IUniswapV3Pool' },\n { name: 'twapWindow', type: 'uint32', internalType: 'uint32' },\n ],\n outputs: [{ name: '', type: 'int24', internalType: 'int24' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'validateTokenId',\n inputs: [{ name: 'self', type: 'uint256', internalType: 'TokenId' }],\n outputs: [],\n stateMutability: 'pure',\n },\n {\n type: 'error',\n name: 'CastingError',\n inputs: [],\n },\n {\n type: 'error',\n name: 'InvalidTick',\n inputs: [],\n },\n {\n type: 'error',\n name: 'InvalidTokenIdParameter',\n inputs: [{ name: 'parameterType', type: 'uint256', internalType: 'uint256' }],\n },\n {\n type: 'error',\n name: 'LiquidityTooHigh',\n inputs: [],\n },\n {\n type: 'error',\n name: 'UnderOverFlow',\n inputs: [],\n },\n] as const\n","import type { Address, Client, Hex } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\nimport { call } from 'viem/actions'\n\nimport { Multicall3Abi } from '../../../abis/multicall3'\nimport {\n MulticallNoDataError,\n MulticallResultFailedError,\n MulticallResultMissingError,\n} from '../errors'\nimport type { BlockMeta } from '../types'\n\nexport const MULTICALL3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11' as const\n\nexport interface MulticallBlockCall {\n target: Address\n callData: Hex\n}\n\nexport interface MulticallBlockResult {\n success: boolean\n returnData: Hex\n}\n\ninterface ClientWithCall extends Client {\n call: (parameters: { to: Address; data: Hex; blockNumber?: bigint }) => Promise<{ data?: Hex }>\n}\n\nfunction hasCall(client: Client): client is ClientWithCall {\n return 'call' in client && typeof (client as Record<'call', unknown>).call === 'function'\n}\n\nfunction requireResult(\n results: readonly MulticallBlockResult[],\n index: number,\n label: string,\n): MulticallBlockResult {\n const result = results[index]\n if (result === undefined) {\n throw new MulticallResultMissingError(label, index)\n }\n if (!result.success) {\n throw new MulticallResultFailedError(label, index)\n }\n return result\n}\n\nexport function requireReturnData(\n results: readonly MulticallBlockResult[],\n index: number,\n label: string,\n): Hex {\n return requireResult(results, index, label).returnData\n}\n\nexport async function readBlockAndAggregate({\n client,\n calls,\n blockNumber,\n}: {\n client: Client\n calls: readonly MulticallBlockCall[]\n blockNumber?: bigint\n}): Promise<{ _meta: BlockMeta; results: readonly MulticallBlockResult[] }> {\n const aggregateCalls = [\n ...calls,\n {\n target: MULTICALL3_ADDRESS,\n callData: encodeFunctionData({\n abi: Multicall3Abi,\n functionName: 'getCurrentBlockTimestamp',\n }),\n },\n ]\n\n const data = encodeFunctionData({\n abi: Multicall3Abi,\n functionName: 'blockAndAggregate',\n args: [aggregateCalls],\n })\n const parameters = { to: MULTICALL3_ADDRESS, data, blockNumber }\n const response = hasCall(client) ? await client.call(parameters) : await call(client, parameters)\n\n if (response.data === undefined) {\n throw new MulticallNoDataError('blockAndAggregate')\n }\n const aggregateResult = decodeFunctionResult({\n abi: Multicall3Abi,\n functionName: 'blockAndAggregate',\n data: response.data,\n })\n const [aggregateBlockNumber, blockHash, rawResults] = aggregateResult as readonly [\n bigint,\n Hex,\n readonly MulticallBlockResult[],\n ]\n const timestampResult = requireReturnData(\n rawResults,\n calls.length,\n 'Multicall3.getCurrentBlockTimestamp',\n )\n const blockTimestamp = decodeFunctionResult({\n abi: Multicall3Abi,\n functionName: 'getCurrentBlockTimestamp',\n data: timestampResult,\n })\n\n return {\n _meta: {\n blockNumber: aggregateBlockNumber,\n blockHash,\n blockTimestamp,\n },\n results: rawResults.slice(0, calls.length),\n }\n}\n","/**\n * Position and account check functions for the Panoptic v2 SDK.\n *\n * These functions check account liquidatability.\n *\n * @module v2/reads/checks\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport { decodeFunctionResult, encodeFunctionData } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { tickToSqrtPriceX96 } from '../formatters/tick'\nimport type { BlockMeta } from '../types'\nimport { decodeLeftRightUnsigned } from '../writes/utils'\nimport { type MulticallBlockCall, readBlockAndAggregate, requireReturnData } from './multicallBlock'\n\nconst FP96 = 1n << 96n\nconst Q128 = 1n << 128n\n\nfunction convert0to1(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n return (amount * sqrtPriceX96 * sqrtPriceX96) >> 192n\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * sp2Hi) >> 128n\n}\n\nfunction convert1to0(amount: bigint, sqrtPriceX96: bigint): bigint {\n if (sqrtPriceX96 < Q128) {\n const denom = sqrtPriceX96 * sqrtPriceX96\n return (amount * (1n << 192n)) / denom\n }\n const sp2Hi = (sqrtPriceX96 * sqrtPriceX96) >> 64n\n return (amount * (1n << 128n)) / sp2Hi\n}\n\n/**\n * Liquidation check result with detailed margin breakdown.\n *\n * **Denomination**: both per-token pairs hold the gross account total\n * cross-converted to that single token denomination at `atTick`.\n * - `currentMargin0` / `requiredMargin0` are in token0 units\n * - `currentMargin1` / `requiredMargin1` are in token1 units\n *\n * `denominatedInToken` indicates which pair is \"preferred\": 0n when\n * `atTick < 0` (token0), 1n otherwise.\n */\nexport interface LiquidationCheck {\n /** Whether the account is liquidatable */\n isLiquidatable: boolean\n /** Margin shortfall for slot 0 (positive = shortfall, negative = excess) */\n marginShortfall0: bigint\n /** Margin shortfall for slot 1 (positive = shortfall, negative = excess) */\n marginShortfall1: bigint\n /** Current (gross) margin (collateral balance), denominated in token0 */\n currentMargin0: bigint\n /** Current (gross) margin, denominated in token1 */\n currentMargin1: bigint\n /** Required margin (sum of per-position requirements), denominated in token0 */\n requiredMargin0: bigint\n /** Required margin, denominated in token1 */\n requiredMargin1: bigint\n /**\n * Which token the \"preferred\" margin pair is denominated in.\n * 0n = token0 (when atTick < 0), 1n = token1 (when atTick >= 0).\n */\n denominatedInToken: bigint\n /** Tick at which liquidation was checked */\n atTick: bigint\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for isLiquidatable.\n */\nexport interface IsLiquidatableParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account to check */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /**\n * Optional: Tick to check liquidation at (defaults to current tick).\n * Note: collateral requirements are evaluated by the contract at the\n * pool's current tick — `atTick` here governs only the cross-token\n * sqrtPrice used to express the totals in a single denomination.\n */\n atTick?: bigint\n /** PanopticQuery address (kept for backwards compatibility; unused). */\n queryAddress?: Address\n /**\n * Optional pre-fetched collateral tracker addresses (saves an RPC).\n * If omitted, they are fetched from the pool.\n */\n collateralAddresses?: { collateralToken0: Address; collateralToken1: Address }\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Check if an account is liquidatable with detailed margin breakdown.\n *\n * Sources gross collateral from `CollateralTracker.assetsOf` and per-position\n * required margin from `PanopticPool.getFullPositionsData.collateralRequirements[]`,\n * cross-converted to each token denomination at `atTick`. Loan tokenIds\n * (width=0 shorts) contribute correctly to required margin.\n *\n * @param params - The parameters\n * @returns Liquidation check result with detailed margin breakdown\n *\n * @example\n * ```typescript\n * const result = await isLiquidatable({\n * client,\n * poolAddress,\n * account,\n * tokenIds: [position1, position2],\n * })\n *\n * if (result.isLiquidatable) {\n * console.log('Account is liquidatable!')\n * }\n * ```\n */\nexport async function isLiquidatable(params: IsLiquidatableParams): Promise<LiquidationCheck> {\n const { client, poolAddress, account, tokenIds, atTick, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Resolve collateral tracker addresses (immutable; cache-friendly).\n let collateralToken0: Address\n let collateralToken1: Address\n if (params.collateralAddresses) {\n collateralToken0 = params.collateralAddresses.collateralToken0\n collateralToken1 = params.collateralAddresses.collateralToken1\n } else {\n const addrs = await client.multicall({\n contracts: [\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken0' },\n { address: poolAddress, abi: panopticPoolV2Abi, functionName: 'collateralToken1' },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n })\n collateralToken0 = addrs[0]\n collateralToken1 = addrs[1]\n }\n\n const calls: MulticallBlockCall[] = []\n const currentTickIndex = atTick === undefined ? calls.length : null\n if (currentTickIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n }),\n })\n }\n\n const assets0Index = calls.length\n calls.push({\n target: collateralToken0,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n })\n\n const assets1Index = calls.length\n calls.push({\n target: collateralToken1,\n callData: encodeFunctionData({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n }),\n })\n\n const positionDataIndex = tokenIds.length > 0 ? calls.length : null\n if (positionDataIndex !== null) {\n calls.push({\n target: poolAddress,\n callData: encodeFunctionData({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n args: [account, true, tokenIds],\n }),\n })\n }\n\n const { _meta, results } = await readBlockAndAggregate({\n client,\n calls,\n blockNumber: targetBlockNumber,\n })\n\n let effectiveTick = atTick\n if (effectiveTick === undefined) {\n if (currentTickIndex === null) {\n throw new Error('Missing current tick Multicall3 result index')\n }\n effectiveTick = BigInt(\n decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n data: requireReturnData(results, currentTickIndex, 'PanopticPool.getCurrentTick'),\n }),\n )\n }\n const assets0 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, assets0Index, 'CollateralTracker.assetsOf token0'),\n })\n const assets1 = decodeFunctionResult({\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n data: requireReturnData(results, assets1Index, 'CollateralTracker.assetsOf token1'),\n })\n const positionDataResult =\n positionDataIndex === null\n ? null\n : (decodeFunctionResult({\n abi: panopticPoolV2Abi,\n functionName: 'getFullPositionsData',\n data: requireReturnData(results, positionDataIndex, 'PanopticPool.getFullPositionsData'),\n }) as readonly [bigint, bigint, readonly bigint[], readonly bigint[], readonly bigint[]])\n\n let required0Native = 0n\n let required1Native = 0n\n if (positionDataResult) {\n const collateralRequirements = positionDataResult[3]\n for (const packed of collateralRequirements) {\n const decoded = decodeLeftRightUnsigned(packed)\n required0Native += decoded.right\n required1Native += decoded.left\n }\n }\n\n const sqrtPriceX96 = tickToSqrtPriceX96(effectiveTick)\n const currentMargin0 = assets0 + convert1to0(assets1, sqrtPriceX96)\n const requiredMargin0 = required0Native + convert1to0(required1Native, sqrtPriceX96)\n const currentMargin1 = assets1 + convert0to1(assets0, sqrtPriceX96)\n const requiredMargin1 = required1Native + convert0to1(required0Native, sqrtPriceX96)\n\n const marginShortfall0 = requiredMargin0 - currentMargin0\n const marginShortfall1 = requiredMargin1 - currentMargin1\n const denominatedInToken: bigint = sqrtPriceX96 < FP96 ? 0n : 1n\n const isLiquidatableResult =\n denominatedInToken === 0n ? marginShortfall0 > 0n : marginShortfall1 > 0n\n\n return {\n isLiquidatable: isLiquidatableResult,\n marginShortfall0,\n marginShortfall1,\n currentMargin0,\n currentMargin1,\n requiredMargin0,\n requiredMargin1,\n denominatedInToken,\n atTick: effectiveTick,\n _meta,\n }\n}\n","/**\n * Account read functions for the Panoptic v2 SDK.\n *\n * ## Same-Block Guarantee\n *\n * All dynamic data is fetched in a SINGLE multicall to ensure block consistency.\n * Per PLAN.md §6, immutable \"static prefetch\" data (addresses) can be fetched\n * separately and cached - it's not subject to same-block consistency.\n *\n * @module v2/reads/account\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { panopticQueryAbi } from '../abis/panopticQuery'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type {\n AccountCollateral,\n AccountSummaryBasic,\n AccountSummaryRisk,\n BlockMeta,\n LiquidationPrices,\n NetLiquidationValue,\n NetLiquidationValues,\n TokenCollateral,\n} from '../types'\nimport { isLiquidatable } from './checks'\nimport { type PoolMetadata, getPool } from './pool'\nimport { getPositions } from './position'\n\n/**\n * Collateral tracker addresses (immutable, can be cached).\n */\nexport interface CollateralAddresses {\n /** Collateral tracker 0 address */\n collateralToken0: Address\n /** Collateral tracker 1 address */\n collateralToken1: Address\n}\n\n/**\n * Extract collateral tracker addresses from a Pool object.\n *\n * Convenience helper that avoids re-fetching immutable addresses\n * when you already have a Pool from a prior `getPool()` call.\n *\n * @param pool - Pool object from getPool()\n * @returns Collateral tracker addresses\n */\nexport function getCollateralAddresses(pool: {\n collateralTracker0: { address: Address }\n collateralTracker1: { address: Address }\n}): CollateralAddresses {\n return {\n collateralToken0: pool.collateralTracker0.address,\n collateralToken1: pool.collateralTracker1.address,\n }\n}\n\n/**\n * Parameters for getAccountCollateral.\n */\nexport interface GetAccountCollateralParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral addresses (for caching/optimization) */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get collateral data for an account.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Collateral tracker addresses are either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Account collateral data with block metadata\n */\nexport async function getAccountCollateral(\n params: GetAccountCollateralParams,\n): Promise<AccountCollateral> {\n const { client, poolAddress, account, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get collateral tracker addresses (static prefetch if not provided)\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n // Static prefetch - addresses are immutable\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [dynamicResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n // Token 0 collateral data\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n // Token 1 collateral data\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'balanceOf',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'assetsOf',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'maxWithdraw',\n args: [account],\n },\n // Leg count from pool\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'numberOfLegs',\n args: [account],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [shares0, assets0, maxWithdraw0, shares1, assets1, maxWithdraw1, legCount] = dynamicResults\n\n // Calculate locked assets as total - available (maxWithdraw)\n const locked0 = assets0 > maxWithdraw0 ? assets0 - maxWithdraw0 : 0n\n const locked1 = assets1 > maxWithdraw1 ? assets1 - maxWithdraw1 : 0n\n\n const token0: TokenCollateral = {\n assets: assets0,\n shares: shares0,\n availableAssets: maxWithdraw0,\n lockedAssets: locked0,\n }\n\n const token1: TokenCollateral = {\n assets: assets1,\n shares: shares1,\n availableAssets: maxWithdraw1,\n lockedAssets: locked1,\n }\n\n return {\n account,\n poolAddress,\n token0,\n token1,\n legCount,\n _meta,\n }\n}\n\n/**\n * Parameters for getAccountSummaryBasic.\n */\nexport interface GetAccountSummaryBasicParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** Chain ID */\n chainId: bigint\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched pool metadata (for caching/optimization) */\n poolMetadata?: PoolMetadata\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Parameters for getAccountSummaryRisk.\n */\nexport interface GetAccountSummaryRiskParams extends GetAccountSummaryBasicParams {\n /** PanopticQuery address (required for risk fields) */\n queryAddress: Address\n /** Optional: Tick to calculate risk metrics at (defaults to current tick) */\n atTick?: bigint\n /** Optional: Whether to include pending premium in NLV */\n includePendingPremium?: boolean\n}\n\ninterface AccountSummaryCoreData {\n pool: Awaited<ReturnType<typeof getPool>>\n collateral: AccountCollateral\n positions: Awaited<ReturnType<typeof getPositions>>['positions']\n _meta: BlockMeta\n}\n\nasync function getAccountSummaryCore(\n params: GetAccountSummaryBasicParams,\n): Promise<AccountSummaryCoreData> {\n const { client, poolAddress, account, chainId, tokenIds, blockNumber, poolMetadata } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const sharedMeta =\n params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n\n const collateralAddresses = poolMetadata\n ? {\n collateralToken0: poolMetadata.collateralToken0Address,\n collateralToken1: poolMetadata.collateralToken1Address,\n }\n : undefined\n\n const [pool, collateral, { positions }] = await Promise.all([\n getPool({\n client,\n poolAddress,\n chainId,\n blockNumber: targetBlockNumber,\n poolMetadata,\n _meta: sharedMeta,\n }),\n getAccountCollateral({\n client,\n poolAddress,\n account,\n blockNumber: targetBlockNumber,\n collateralAddresses,\n _meta: sharedMeta,\n }),\n getPositions({\n client,\n poolAddress,\n owner: account,\n tokenIds,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n ])\n\n return {\n pool,\n collateral,\n positions,\n _meta: sharedMeta,\n }\n}\n\n/**\n * Get base account summary data for UI dashboards.\n *\n * ## Same-Block Guarantee\n * Uses the same blockNumber for pool, collateral, and position reads.\n *\n * @param params - The parameters\n * @returns Base account summary with block metadata\n */\nexport async function getAccountSummaryBasic(\n params: GetAccountSummaryBasicParams,\n): Promise<AccountSummaryBasic> {\n const { account } = params\n const { pool, collateral, positions, _meta } = await getAccountSummaryCore(params)\n\n return {\n account,\n pool,\n collateral,\n positions,\n healthStatus: pool.healthStatus,\n networkMismatch: false, // Requires wallet context, not available in read functions\n _meta,\n }\n}\n\n/**\n * Get risk-focused account summary including helper-dependent fields.\n *\n * ## Same-Block Guarantee\n * Uses one block target for all pool/collateral/position/risk reads.\n *\n * @param params - The parameters\n * @returns Risk-focused account summary with block metadata\n */\nexport async function getAccountSummaryRisk(\n params: GetAccountSummaryRiskParams,\n): Promise<AccountSummaryRisk> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n queryAddress,\n atTick,\n includePendingPremium = true,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n const sharedMeta =\n params._meta ?? (await getBlockMeta({ client, blockNumber: targetBlockNumber }))\n\n const [{ pool, collateral, positions }, nlv, liquidationCheck, liquidationPrices] =\n await Promise.all([\n getAccountSummaryCore({\n ...params,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n getNetLiquidationValue({\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n includePendingPremium,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n isLiquidatable({\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n getLiquidationPrices({\n client,\n poolAddress,\n account,\n tokenIds,\n queryAddress,\n blockNumber: targetBlockNumber,\n _meta: sharedMeta,\n }),\n ])\n\n const totalGreeks = {\n value: 0n,\n delta: 0n,\n gamma: 0n,\n }\n\n const maintenanceMargin0 = liquidationCheck.requiredMargin0\n const maintenanceMargin1 = liquidationCheck.requiredMargin1\n const marginExcess0 = liquidationCheck.currentMargin0 - liquidationCheck.requiredMargin0\n const marginExcess1 = liquidationCheck.currentMargin1 - liquidationCheck.requiredMargin1\n\n return {\n account,\n pool,\n collateral,\n positions,\n totalGreeks,\n netLiquidationValue0: nlv.value0,\n netLiquidationValue1: nlv.value1,\n maintenanceMargin0,\n maintenanceMargin1,\n marginExcess0,\n marginExcess1,\n marginShortfall0: liquidationCheck.marginShortfall0,\n marginShortfall1: liquidationCheck.marginShortfall1,\n currentMargin0: liquidationCheck.currentMargin0,\n currentMargin1: liquidationCheck.currentMargin1,\n isLiquidatable: liquidationCheck.isLiquidatable,\n liquidationPrices,\n healthStatus: pool.healthStatus,\n networkMismatch: false, // Requires wallet context, not available in read functions\n _meta: sharedMeta,\n }\n}\n\n/**\n * Parameters for getNetLiquidationValue.\n */\nexport interface GetNetLiquidationValueParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Optional: Tick to calculate NLV at (defaults to current tick) */\n atTick?: bigint\n /** Optional: Whether to include pending premium */\n includePendingPremium?: boolean\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get net liquidation value for an account.\n *\n * ## Same-Block Guarantee\n * Tick and NLV are queried at the same target block.\n *\n * Requires PanopticQuery for accurate value and premium accounting.\n *\n * @param params - The parameters\n * @returns Net liquidation value with block metadata\n */\nexport async function getNetLiquidationValue(\n params: GetNetLiquidationValueParams,\n): Promise<NetLiquidationValue> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n atTick,\n includePendingPremium = true,\n queryAddress,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Skip getCurrentTick RPC call when atTick is provided\n const [currentTickResult, _meta] = await Promise.all([\n atTick != null\n ? Promise.resolve(atTick)\n : client\n .readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'getCurrentTick',\n blockNumber: targetBlockNumber,\n })\n .then((r) => BigInt(r)),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const effectiveTick = currentTickResult\n\n // PanopticQuery only exposes the int24[] overload; query a single tick and unwrap.\n const result = await client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getNetLiquidationValue',\n args: [poolAddress, account, includePendingPremium, tokenIds, [Number(effectiveTick)]],\n blockNumber: targetBlockNumber,\n })\n\n const [values0, values1] = result\n const value0 = values0[0]\n const value1 = values1[0]\n\n return {\n value0,\n value1,\n atTick: effectiveTick,\n includedPendingPremium: includePendingPremium,\n _meta,\n }\n}\n\n/**\n * Parameters for getNetLiquidationValues (batch/multi-tick).\n */\nexport interface GetNetLiquidationValuesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** Ticks to calculate NLV at */\n atTicks: bigint[]\n /** Optional: Whether to include pending premium */\n includePendingPremium?: boolean\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get net liquidation values at multiple ticks in a single contract call.\n *\n * Uses the `int24[]` overload of `getNetLiquidationValue` on PanopticQuery.\n *\n * @param params - The parameters\n * @returns Net liquidation values with block metadata\n */\nexport async function getNetLiquidationValues(\n params: GetNetLiquidationValuesParams,\n): Promise<NetLiquidationValues> {\n const {\n client,\n poolAddress,\n account,\n tokenIds,\n atTicks,\n includePendingPremium = true,\n queryAddress,\n blockNumber,\n } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Use an isolated ABI with only the int24[] overload to avoid viem overload ambiguity\n const batchNlvAbi = [\n {\n type: 'function' as const,\n name: 'getNetLiquidationValue' as const,\n inputs: [\n { name: 'pool', type: 'address' as const },\n { name: 'account', type: 'address' as const },\n { name: 'includePendingPremium', type: 'bool' as const },\n { name: 'positionIdList', type: 'uint256[]' as const },\n { name: 'atTicks', type: 'int24[]' as const },\n ],\n outputs: [\n { name: 'value0', type: 'int256[]' as const },\n { name: 'value1', type: 'int256[]' as const },\n ],\n stateMutability: 'view' as const,\n },\n ] as const\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: batchNlvAbi,\n functionName: 'getNetLiquidationValue',\n args: [poolAddress, account, includePendingPremium, tokenIds, atTicks.map((t) => Number(t))],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [values0, values1] = result\n\n return {\n values0: [...values0],\n values1: [...values1],\n atTicks,\n _meta,\n }\n}\n\n/**\n * Parameters for getLiquidationPrices.\n */\nexport interface GetLiquidationPricesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address */\n account: Address\n /** TokenIds of open positions */\n tokenIds: bigint[]\n /** PanopticQuery address (required) */\n queryAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get liquidation prices for an account.\n *\n * ## Same-Block Guarantee\n * Liquidation price query is made at a single block.\n *\n * @param params - The parameters\n * @returns Liquidation prices with block metadata\n */\nexport async function getLiquidationPrices(\n params: GetLiquidationPricesParams,\n): Promise<LiquidationPrices> {\n const { client, poolAddress, account, tokenIds, queryAddress, blockNumber } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // MIN_TICK and MAX_TICK indicate no liquidation at that boundary\n const MIN_TICK = -887272n\n const MAX_TICK = 887272n\n\n const [result, _meta] = await Promise.all([\n client.readContract({\n address: queryAddress,\n abi: panopticQueryAbi,\n functionName: 'getLiquidationPrices',\n args: [poolAddress, account, tokenIds],\n blockNumber: targetBlockNumber,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n // Convert from number (abitype default for int24) to bigint (viem runtime type)\n const liqPriceDown = BigInt(result[0])\n const liqPriceUp = BigInt(result[1])\n\n return {\n lowerTick: liqPriceDown === MIN_TICK ? null : liqPriceDown,\n upperTick: liqPriceUp === MAX_TICK ? null : liqPriceUp,\n isLiquidatable: liqPriceDown !== MIN_TICK || liqPriceUp !== MAX_TICK,\n _meta,\n }\n}\n","/**\n * Collateral read functions for the Panoptic v2 SDK.\n *\n * ## Same-Block Guarantee\n *\n * All dynamic data is fetched in a SINGLE multicall to ensure block consistency.\n * Per PLAN.md §6, immutable \"static prefetch\" data (addresses, symbols, decimals)\n * can be fetched separately and cached - it's not subject to same-block consistency.\n *\n * @module v2/reads/collateral\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, panopticPoolV2Abi } from '../../../generated'\nimport { getBlockMeta } from '../clients/blockMeta'\nimport type { BlockMeta, CollateralTracker, CurrentRates } from '../types'\n\nconst SECONDS_PER_YEAR = 31_536_000n\n\n// ERC20 minimal ABI for token metadata\nconst erc20Abi = [\n {\n type: 'function',\n name: 'symbol',\n inputs: [],\n outputs: [{ type: 'string' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'decimals',\n inputs: [],\n outputs: [{ type: 'uint8' }],\n stateMutability: 'view',\n },\n] as const\n\n/**\n * Pre-fetched collateral tracker metadata (immutable, can be cached).\n */\nexport interface CollateralTrackerMetadata {\n /** Collateral tracker address */\n address: Address\n /** Underlying asset address */\n assetAddress: Address\n /** Token symbol */\n symbol: string\n /** Token decimals */\n decimals: bigint\n}\n\n/**\n * Parameters for getCollateralData.\n */\nexport interface GetCollateralDataParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Which token's collateral tracker to query (0 or 1) */\n tokenIndex: 0 | 1\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker metadata (for caching/optimization) */\n trackerMetadata?: CollateralTrackerMetadata\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get collateral tracker data for a specific token.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Static metadata (address, symbol, decimals) is either provided or fetched separately.\n *\n * @param params - The parameters\n * @returns Collateral tracker data with block metadata\n */\nexport async function getCollateralData(\n params: GetCollateralDataParams,\n): Promise<CollateralTracker & { _meta: BlockMeta }> {\n const { client, poolAddress, tokenIndex, blockNumber, trackerMetadata } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // If metadata is provided, we only need ONE multicall for dynamic data\n if (trackerMetadata) {\n const [dynamicResults, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: trackerMetadata.address,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [poolData, totalShares, interestRate] = dynamicResults\n const [depositedAssets, insideAMM, creditedShares, utilization] = poolData\n const totalAssets = depositedAssets + insideAMM\n\n const borrowRate = BigInt(interestRate) * SECONDS_PER_YEAR\n const supplyRate = (borrowRate * utilization) / 10000n\n\n return {\n address: trackerMetadata.address,\n token: trackerMetadata.assetAddress,\n symbol: trackerMetadata.symbol,\n decimals: trackerMetadata.decimals,\n totalAssets,\n insideAMM,\n creditedShares,\n totalShares,\n utilization,\n borrowRate,\n supplyRate,\n _meta,\n }\n }\n\n // Without metadata, fetch everything (original structure for backwards compatibility)\n // 1. Get tracker address (static)\n const collateralTrackerAddress = await client.readContract({\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: tokenIndex === 0 ? 'collateralToken0' : 'collateralToken1',\n })\n\n // 2. Get asset + dynamic data in one multicall (same-block guarantee for dynamic data)\n const [trackerData, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'asset',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'totalSupply',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [assetAddress, poolData, totalShares, interestRate] = trackerData\n\n // 3. Get token metadata (static - can be cached)\n const [symbol, decimals] = await client.multicall({\n contracts: [\n {\n address: assetAddress,\n abi: erc20Abi,\n functionName: 'symbol',\n },\n {\n address: assetAddress,\n abi: erc20Abi,\n functionName: 'decimals',\n },\n ],\n allowFailure: false,\n })\n\n // poolData returns: (depositedAssets, insideAMM, creditedShares, currentPoolUtilization)\n const [depositedAssets, insideAMM, creditedShares, utilization] = poolData\n const totalAssets = depositedAssets + insideAMM\n\n // Annualize rates: interestRate() returns WAD/s\n const borrowRate = BigInt(interestRate) * SECONDS_PER_YEAR\n const supplyRate = (borrowRate * utilization) / 10000n\n\n return {\n address: collateralTrackerAddress,\n token: assetAddress,\n symbol,\n decimals: BigInt(decimals),\n totalAssets,\n insideAMM,\n creditedShares,\n totalShares,\n utilization,\n borrowRate,\n supplyRate,\n _meta,\n }\n}\n\n/**\n * Collateral tracker addresses (immutable, can be cached).\n */\nexport interface CollateralAddresses {\n /** Collateral tracker 0 address */\n collateralToken0: Address\n /** Collateral tracker 1 address */\n collateralToken1: Address\n}\n\n/**\n * Parameters for getCurrentRates.\n */\nexport interface GetCurrentRatesParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker addresses (for caching/optimization) */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata (skips getBlockMeta RPC call) */\n _meta?: BlockMeta\n}\n\n/**\n * Get current interest rates for both tokens.\n *\n * ## Same-Block Guarantee\n * All dynamic data is fetched in ONE multicall at the target block.\n * Collateral tracker addresses are either provided or fetched separately (static prefetch).\n *\n * @param params - The parameters\n * @returns Current rates with block metadata\n */\nexport async function getCurrentRates(params: GetCurrentRatesParams): Promise<CurrentRates> {\n const { client, poolAddress, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n // Get collateral tracker addresses (static prefetch if not provided)\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n // Static prefetch - addresses are immutable\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n // SINGLE multicall for ALL dynamic data - ensures same-block consistency\n const [rateData, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'interestRate',\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [interestRate0, poolData0, interestRate1, poolData1] = rateData\n\n // Extract utilization from pool data\n const utilization0 = poolData0[3]\n const utilization1 = poolData1[3]\n\n // Annualize rates: interestRate() returns WAD/s\n const borrowRate0 = BigInt(interestRate0) * SECONDS_PER_YEAR\n const borrowRate1 = BigInt(interestRate1) * SECONDS_PER_YEAR\n\n // Supply rate = borrow rate * utilization (utilization is in bps, so /10000)\n const supplyRate0 = (borrowRate0 * utilization0) / 10000n\n const supplyRate1 = (borrowRate1 * utilization1) / 10000n\n\n return {\n borrowRate0,\n supplyRate0,\n borrowRate1,\n supplyRate1,\n _meta,\n }\n}\n\n// ─── Interest State (per-user borrows) ───────────────────────────────────────\n\n/**\n * Per-user interest state for a single collateral tracker.\n */\nexport interface TokenInterestState {\n /** User's borrow index snapshot (int128) */\n userBorrowIndex: bigint\n /** User's net borrows: positive = borrowing, negative = net supplying (int128) */\n netBorrows: bigint\n}\n\n/**\n * Interest state for both tokens in a Panoptic pool.\n */\nexport interface InterestState {\n /** Token 0 interest state */\n token0: TokenInterestState\n /** Token 1 interest state */\n token1: TokenInterestState\n /** Block metadata */\n _meta: BlockMeta\n}\n\n/**\n * Parameters for getInterestState.\n */\nexport interface GetInterestStateParams {\n /** viem PublicClient */\n client: PublicClient\n /** PanopticPool address */\n poolAddress: Address\n /** Account address to query */\n account: Address\n /** Optional block number for historical queries */\n blockNumber?: bigint\n /** Optional pre-fetched collateral tracker addresses */\n collateralAddresses?: CollateralAddresses\n /** Optional pre-fetched block metadata */\n _meta?: BlockMeta\n}\n\n/**\n * Get per-user interest state (borrow index + net borrows) for both tokens.\n *\n * Calls `collateralTracker.interestState(user)` on both trackers in a single multicall.\n *\n * @param params - The parameters\n * @returns Interest state for both tokens with block metadata\n */\nexport async function getInterestState(params: GetInterestStateParams): Promise<InterestState> {\n const { client, poolAddress, account, blockNumber, collateralAddresses } = params\n\n const targetBlockNumber =\n blockNumber ?? params._meta?.blockNumber ?? (await client.getBlockNumber())\n\n let collateralToken0: Address\n let collateralToken1: Address\n\n if (collateralAddresses) {\n collateralToken0 = collateralAddresses.collateralToken0\n collateralToken1 = collateralAddresses.collateralToken1\n } else {\n const addressResults = await client.multicall({\n contracts: [\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken0',\n },\n {\n address: poolAddress,\n abi: panopticPoolV2Abi,\n functionName: 'collateralToken1',\n },\n ],\n allowFailure: false,\n })\n collateralToken0 = addressResults[0]\n collateralToken1 = addressResults[1]\n }\n\n const [results, _meta] = await Promise.all([\n client.multicall({\n contracts: [\n {\n address: collateralToken0,\n abi: collateralTrackerV2Abi,\n functionName: 'interestState',\n args: [account],\n },\n {\n address: collateralToken1,\n abi: collateralTrackerV2Abi,\n functionName: 'interestState',\n args: [account],\n },\n ],\n blockNumber: targetBlockNumber,\n allowFailure: false,\n }),\n params._meta ?? getBlockMeta({ client, blockNumber: targetBlockNumber }),\n ])\n\n const [state0, state1] = results\n\n return {\n token0: { userBorrowIndex: state0[0], netBorrows: state0[1] },\n token1: { userBorrowIndex: state1[0], netBorrows: state1[1] },\n _meta,\n }\n}\n","/**\n * Token amount formatters and parsers.\n *\n * All formatters require explicit precision - no hidden defaults.\n *\n * @module v2/formatters/amount\n */\n\nimport type { TokenFlow } from '../types'\n\n/**\n * Format a raw token amount to a human-readable string.\n *\n * @param amount - The amount in smallest units (e.g., wei)\n * @param decimals - Token decimals (e.g., 18n for WETH, 6n for USDC)\n * @param precision - Number of decimal places to display\n * @returns Formatted string\n *\n * @example\n * ```typescript\n * formatTokenAmount(1500000000000000000n, 18n, 4n) // \"1.5000\"\n * formatTokenAmount(1500000000000000000n, 18n, 2n) // \"1.50\"\n * formatTokenAmount(1500000n, 6n, 2n) // \"1.50\" (USDC)\n * formatTokenAmount(-500000000000000000n, 18n, 4n) // \"-0.5000\"\n * ```\n */\nexport function formatTokenAmount(amount: bigint, decimals: bigint, precision: bigint): string {\n const isNegative = amount < 0n\n const absAmount = isNegative ? -amount : amount\n const divisor = 10n ** decimals\n const integerPart = absAmount / divisor\n const fractionalPart = absAmount % divisor\n\n // Build fractional string with proper padding\n const fullFractionalStr = fractionalPart.toString().padStart(Number(decimals), '0')\n const truncatedFractionalStr = fullFractionalStr.slice(0, Number(precision))\n const paddedFractionalStr = truncatedFractionalStr.padEnd(Number(precision), '0')\n\n const sign = isNegative ? '-' : ''\n return precision > 0n ? `${sign}${integerPart}.${paddedFractionalStr}` : `${sign}${integerPart}`\n}\n\n/**\n * Format a token amount with a sign prefix (+/-) for non-zero values.\n * Useful for displaying PnL, deltas, or changes.\n *\n * @param amount - The amount in smallest units\n * @param decimals - Token decimals\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n *\n * @example\n * ```typescript\n * formatTokenAmountSigned(1500000000000000000n, 18n, 4n) // \"+1.5000\"\n * formatTokenAmountSigned(-500000000000000000n, 18n, 4n) // \"-0.5000\"\n * formatTokenAmountSigned(0n, 18n, 4n) // \"0.0000\"\n * ```\n */\nexport function formatTokenAmountSigned(\n amount: bigint,\n decimals: bigint,\n precision: bigint,\n): string {\n const formatted = formatTokenAmount(amount, decimals, precision)\n if (amount > 0n) {\n return `+${formatted}`\n }\n return formatted\n}\n\n/**\n * Parse a human-readable token amount string to raw units.\n *\n * @param amount - Human-readable amount string (e.g., \"1.5\")\n * @param decimals - Token decimals\n * @returns Amount in smallest units\n *\n * @example\n * ```typescript\n * parseTokenAmount(\"1.5\", 18n) // 1500000000000000000n\n * parseTokenAmount(\"1.5\", 6n) // 1500000n (USDC)\n * parseTokenAmount(\"100\", 18n) // 100000000000000000000n\n * parseTokenAmount(\"-0.5\", 18n) // -500000000000000000n\n * ```\n */\nexport function parseTokenAmount(amount: string, decimals: bigint): bigint {\n const trimmed = amount.trim()\n const isNegative = trimmed.startsWith('-')\n const cleanAmount = isNegative ? trimmed.slice(1) : trimmed\n\n const [integerStr, fractionalStr = ''] = cleanAmount.split('.')\n const paddedFractional = fractionalStr.padEnd(Number(decimals), '0').slice(0, Number(decimals))\n\n const integerPart = BigInt(integerStr || '0') * 10n ** decimals\n const fractionalPart = BigInt(paddedFractional || '0')\n\n const result = integerPart + fractionalPart\n return isNegative ? -result : result\n}\n\n/**\n * Format a token delta amount with a sign prefix (+/-) for non-zero values.\n * Alias for formatTokenAmountSigned, useful for clarity at call sites.\n *\n * @param amount - The delta amount in smallest units\n * @param decimals - Token decimals\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n */\nexport function formatTokenDelta(amount: bigint, decimals: bigint, precision: bigint): string {\n return formatTokenAmountSigned(amount, decimals, precision)\n}\n\n/**\n * Format token flow deltas and balances from simulation results.\n *\n * @param flow - Token flow data\n * @param decimals0 - Token0 decimals\n * @param decimals1 - Token1 decimals\n * @param precision0 - Precision for token0 formatting\n * @param precision1 - Precision for token1 formatting\n * @returns Formatted token flow strings\n */\nexport function formatTokenFlow(\n flow: TokenFlow,\n decimals0: bigint,\n decimals1: bigint,\n precision0: bigint,\n precision1: bigint,\n): {\n delta0: string\n delta1: string\n balanceBefore0: string\n balanceBefore1: string\n balanceAfter0: string\n balanceAfter1: string\n} {\n return {\n delta0: formatTokenAmountSigned(flow.delta0, decimals0, precision0),\n delta1: formatTokenAmountSigned(flow.delta1, decimals1, precision1),\n balanceBefore0: formatTokenAmount(flow.balanceBefore0, decimals0, precision0),\n balanceBefore1: formatTokenAmount(flow.balanceBefore1, decimals1, precision1),\n balanceAfter0: formatTokenAmount(flow.balanceAfter0, decimals0, precision0),\n balanceAfter1: formatTokenAmount(flow.balanceAfter1, decimals1, precision1),\n }\n}\n","/**\n * WAD-scaled value formatters.\n *\n * WAD is a fixed-point representation where 1e18 = 1.0.\n * Used extensively in DeFi for representing ratios, prices, and multipliers.\n *\n * @module v2/formatters/wad\n */\n\nimport { formatTokenAmount } from './amount'\n\n/**\n * Format a WAD-scaled value (1e18 = 1.0).\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted string\n *\n * @example\n * ```typescript\n * formatWad(1220000000000000000n, 2n) // \"1.22\"\n * formatWad(1220000000000000000n, 4n) // \"1.2200\"\n * formatWad(1000000000000000000n, 2n) // \"1.00\"\n * formatWad(500000000000000000n, 2n) // \"0.50\"\n * ```\n */\nexport function formatWad(wad: bigint, precision: bigint): string {\n return formatTokenAmount(wad, 18n, precision)\n}\n\n/**\n * Format a WAD-scaled value with sign prefix (+/-) for non-zero values.\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted string with sign prefix\n *\n * @example\n * ```typescript\n * formatWadSigned(1220000000000000000n, 2n) // \"+1.22\"\n * formatWadSigned(-500000000000000000n, 2n) // \"-0.50\"\n * formatWadSigned(0n, 2n) // \"0.00\"\n * ```\n */\nexport function formatWadSigned(wad: bigint, precision: bigint): string {\n const formatted = formatWad(wad, precision)\n if (wad > 0n) {\n return `+${formatted}`\n }\n return formatted\n}\n\n/**\n * Format a WAD-scaled value as a percentage string.\n *\n * @param wad - WAD-scaled value\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n *\n * @example\n * ```typescript\n * formatWadPercent(50000000000000000n, 2n) // \"5.00%\"\n * formatWadPercent(1000000000000000000n, 1n) // \"100.0%\"\n * ```\n */\nexport function formatWadPercent(wad: bigint, precision: bigint): string {\n return `${formatTokenAmount(wad * 100n, 18n, precision)}%`\n}\n\n/**\n * Format an annualized rate stored as a WAD-scaled value.\n * Alias for formatWadPercent.\n *\n * @param rateWad - Rate in WAD (1e18 = 1.0)\n * @param precision - Number of decimal places to display\n * @returns Formatted percentage string\n */\nexport function formatRateWad(rateWad: bigint, precision: bigint): string {\n return formatWadPercent(rateWad, precision)\n}\n\n/**\n * Parse a decimal string to a WAD-scaled value.\n *\n * @param value - Decimal string (e.g., \"1.5\")\n * @returns WAD-scaled bigint\n *\n * @example\n * ```typescript\n * parseWad(\"1.5\") // 1500000000000000000n\n * parseWad(\"0.5\") // 500000000000000000n\n * parseWad(\"100\") // 100000000000000000000n\n * parseWad(\"-1.22\") // -1220000000000000000n\n * ```\n */\nexport function parseWad(value: string): bigint {\n const trimmed = value.trim()\n const isNegative = trimmed.startsWith('-')\n const cleanValue = isNegative ? trimmed.slice(1) : trimmed\n\n const [integerStr, fractionalStr = ''] = cleanValue.split('.')\n const paddedFractional = fractionalStr.padEnd(18, '0').slice(0, 18)\n\n const integerPart = BigInt(integerStr || '0') * 10n ** 18n\n const fractionalPart = BigInt(paddedFractional || '0')\n\n const result = integerPart + fractionalPart\n return isNegative ? -result : result\n}\n","/**\n * Per-second rate helpers.\n *\n * Collateral tracker rates are returned as WAD-scaled per-second rates.\n * These helpers annualize them for display.\n *\n * @module v2/formatters/rates\n */\n\nimport { formatWadPercent } from './wad'\n\nconst SECONDS_PER_DAY = 86_400n\nconst DAYS_PER_YEAR = 365n\nconst SECONDS_PER_YEAR = SECONDS_PER_DAY * DAYS_PER_YEAR\n\n/**\n * Annualize a per-second WAD-scaled rate to annual WAD.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @returns Annualized rate in WAD\n */\nexport function annualizePerSecondRateWad(ratePerSecondWad: bigint): bigint {\n return ratePerSecondWad * SECONDS_PER_YEAR\n}\n\n/**\n * Format a per-second WAD rate as APY percentage text.\n * Uses linear annualization, then formats as WAD percent.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @param precision - Decimal places\n * @returns Percentage string, e.g. \"2.41%\"\n */\nexport function formatPerSecondRateWadAsApyPct(\n ratePerSecondWad: bigint,\n precision: bigint,\n): string {\n return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision)\n}\n\n/**\n * Format a per-second WAD rate as APR percentage text.\n * For this rate model, APR presentation uses the same annualized output.\n *\n * @param ratePerSecondWad - Rate in WAD per second\n * @param precision - Decimal places\n * @returns Percentage string, e.g. \"2.41%\"\n */\nexport function formatPerSecondRateWadAsAprPct(\n ratePerSecondWad: bigint,\n precision: bigint,\n): string {\n return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision)\n}\n","/**\n * Interest rate model (IRM) reads for Panoptic v2.\n * @module v2/reads/irm\n */\n\nimport type { Address, PublicClient } from 'viem'\n\nimport { collateralTrackerV2Abi, riskEngineAbi } from '../../../generated'\nimport { PanopticValidationError } from '../errors/sdk'\nimport type { IrmCurrent, IrmMarketStateInputs, IrmPoint } from '../types/irm'\nexport type { IrmCurrent, IrmMarketStateInputs, IrmPoint } from '../types/irm'\n\nexport const WAD = 10n ** 18n\nexport const BPS_SCALE = 10_000n\nexport const SECONDS_PER_YEAR = 31_536_000n\nexport const MARKET_EPOCH_SHIFT = 2n\nexport const BORROW_INDEX_BITS = 80n\nexport const MARKET_EPOCH_BITS = 32n\nexport const RATE_AT_TARGET_BITS = 38n\nexport const UNREALIZED_INTEREST_BITS = 106n\n\nconst BORROW_INDEX_SHIFT = 0n\nconst MARKET_EPOCH_FIELD_SHIFT = BORROW_INDEX_BITS\nconst RATE_AT_TARGET_FIELD_SHIFT = BORROW_INDEX_BITS + MARKET_EPOCH_BITS\nconst UNREALIZED_INTEREST_FIELD_SHIFT = RATE_AT_TARGET_FIELD_SHIFT + RATE_AT_TARGET_BITS\nconst MAX_IRM_CURVE_POINTS = 500\n\nconst clampUtilizationBps = (utilizationBps: bigint): bigint => {\n if (utilizationBps < 0n) {\n return 0n\n }\n if (utilizationBps > BPS_SCALE) {\n return BPS_SCALE\n }\n return utilizationBps\n}\n\nconst getMaxValue = (bits: bigint): bigint => (1n << bits) - 1n\n\nconst assertFitsBits = (value: bigint, bits: bigint, fieldName: string): void => {\n if (value < 0n) {\n throw new PanopticValidationError(`${fieldName} must be >= 0`)\n }\n if (value > getMaxValue(bits)) {\n throw new PanopticValidationError(`${fieldName} exceeds ${bits.toString()} bits`)\n }\n}\n\nexport function packMarketState(inputs: IrmMarketStateInputs): bigint {\n const { borrowIndex, lastInteractionTimestamp, rateAtTarget, unrealizedGlobalInterest } = inputs\n const marketEpoch = lastInteractionTimestamp >> MARKET_EPOCH_SHIFT\n\n assertFitsBits(borrowIndex, BORROW_INDEX_BITS, 'borrowIndex')\n assertFitsBits(marketEpoch, MARKET_EPOCH_BITS, 'marketEpoch')\n assertFitsBits(rateAtTarget, RATE_AT_TARGET_BITS, 'rateAtTarget')\n assertFitsBits(unrealizedGlobalInterest, UNREALIZED_INTEREST_BITS, 'unrealizedGlobalInterest')\n\n return (\n (borrowIndex << BORROW_INDEX_SHIFT) +\n (marketEpoch << MARKET_EPOCH_FIELD_SHIFT) +\n (rateAtTarget << RATE_AT_TARGET_FIELD_SHIFT) +\n (unrealizedGlobalInterest << UNREALIZED_INTEREST_FIELD_SHIFT)\n )\n}\n\nexport function utilizationPctToWad(utilizationPct: number): bigint {\n if (!Number.isFinite(utilizationPct)) {\n throw new PanopticValidationError('utilizationPct must be finite')\n }\n if (utilizationPct < 0 || utilizationPct > 100) {\n throw new PanopticValidationError('utilizationPct must be between 0 and 100')\n }\n\n const scaledPct = Math.round(utilizationPct * 1_000_000)\n return (BigInt(scaledPct) * WAD) / 100_000_000n\n}\n\nexport function utilizationBpsToWad(utilizationBps: bigint): bigint {\n return (clampUtilizationBps(utilizationBps) * WAD) / BPS_SCALE\n}\n\nexport function ratePerSecWadToAprPct(ratePerSecWad: bigint): number {\n return (Number(ratePerSecWad) * Number(SECONDS_PER_YEAR) * 100) / Number(WAD)\n}\n\nexport function deriveSupplyRatePerSecWad(\n borrowRatePerSecWad: bigint,\n utilizationWad: bigint,\n): bigint {\n return (borrowRatePerSecWad * utilizationWad) / WAD\n}\n\nexport async function getIrmCurrent(params: {\n client: PublicClient\n collateralTrackerAddress: Address\n blockNumber?: bigint\n}): Promise<IrmCurrent> {\n const { client, collateralTrackerAddress, blockNumber } = params\n const [\n borrowIndex,\n lastInteractionTimestamp,\n rateAtTarget,\n unrealizedGlobalInterest,\n poolData,\n riskEngineAddress,\n ] = await client.multicall({\n contracts: [\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'borrowIndex',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'lastInteractionTimestamp',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'rateAtTarget',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'unrealizedGlobalInterest',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'getPoolData',\n },\n {\n address: collateralTrackerAddress,\n abi: collateralTrackerV2Abi,\n functionName: 'riskEngine',\n },\n ],\n blockNumber,\n allowFailure: false,\n })\n\n const currentUtilizationBps = clampUtilizationBps(poolData[3])\n const currentUtilizationWad = utilizationBpsToWad(currentUtilizationBps)\n const currentUtilizationPct = Number(currentUtilizationBps) / 100\n\n const marketStatePacked = packMarketState({\n borrowIndex,\n lastInteractionTimestamp,\n rateAtTarget,\n unrealizedGlobalInterest,\n })\n\n const borrowRatePerSecWad = await client.readContract({\n address: riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'interestRate',\n args: [currentUtilizationWad, marketStatePacked],\n blockNumber,\n })\n\n const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, currentUtilizationWad)\n\n return {\n collateralTrackerAddress,\n riskEngineAddress,\n currentUtilizationBps,\n currentUtilizationWad,\n currentUtilizationPct,\n borrowRatePerSecWad,\n supplyRatePerSecWad,\n borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),\n supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad),\n marketStatePacked,\n }\n}\n\nexport async function getIrmCurve(params: {\n client: PublicClient\n collateralTrackerAddress: Address\n points?: number\n blockNumber?: bigint\n}): Promise<{\n current: IrmCurrent\n points: IrmPoint[]\n}> {\n const { client, collateralTrackerAddress, points = 201, blockNumber } = params\n\n if (!Number.isInteger(points) || points < 2) {\n throw new PanopticValidationError('points must be an integer >= 2')\n }\n if (points > MAX_IRM_CURVE_POINTS) {\n throw new PanopticValidationError(`points must be <= ${MAX_IRM_CURVE_POINTS}`)\n }\n\n const current = await getIrmCurrent({\n client,\n collateralTrackerAddress,\n blockNumber,\n })\n\n const denominator = BigInt(points - 1)\n const contracts = Array.from({ length: points }, (_, idx) => {\n const i = BigInt(idx)\n const utilizationWad = (i * WAD) / denominator\n\n return {\n address: current.riskEngineAddress,\n abi: riskEngineAbi,\n functionName: 'interestRate' as const,\n args: [utilizationWad, current.marketStatePacked] as const,\n }\n })\n\n const borrowRatesPerSecWad = await client.multicall({\n contracts,\n blockNumber,\n allowFailure: false,\n })\n\n const curvePoints: IrmPoint[] = borrowRatesPerSecWad.map((borrowRatePerSecWad, idx) => {\n const i = BigInt(idx)\n const utilizationWad = (i * WAD) / denominator\n const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, utilizationWad)\n\n return {\n utilizationWad,\n utilizationPct: (idx * 100) / (points - 1),\n borrowRatePerSecWad,\n supplyRatePerSecWad,\n borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),\n supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad),\n }\n })\n\n return {\n current,\n points: curvePoints,\n }\n}\n"],"mappings":";;;;;AAAA,MAAa,gBAAgB;CAC3B;EACE,QAAQ,CACN;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY;IACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;GACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY;IACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;IACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP;GACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS;GACP;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,YAAY,CACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,GACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,CACF;IACD,cAAc;IACd,MAAM;IACN,MAAM;GACP;EACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CAAE;EACV,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS,CACP;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,iBAAiB;EACjB,MAAM;CACP;CACD;EACE,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACP,GACD;GACE,YAAY,CACV;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP,CACF;GACD,cAAc;GACd,MAAM;GACN,MAAM;EACP,CACF;EACD,MAAM;EACN,SAAS;GACP;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACP;GACD;IACE,YAAY,CACV;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,GACD;KACE,cAAc;KACd,MAAM;KACN,MAAM;IACP,CACF;IACD,cAAc;IACd,MAAM;IACN,MAAM;GACP;EACF;EACD,iBAAiB;EACjB,MAAM;CACP;AACF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"}