UNPKG

@quantara/sdk

Version:

JavaScript/TypeScript SDK for interacting with Quantara Protocol on Neura Testnet

268 lines (267 loc) 13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const chains_1 = require("../../configs/chains"); const tokens_1 = require("../../configs/tokens"); const markets_1 = require("../markets"); const numbers_1 = require("../numbers"); function getToken(symbol) { return tokens_1.TOKENS[chains_1.NEURA_TESTNET].find((token) => token.symbol === symbol); } (0, vitest_1.describe)("getMarketFullName", () => { (0, vitest_1.it)("returns proper full name", () => { const longToken = getToken("ETH"); const shortToken = getToken("USDC"); const indexToken = getToken("BTC"); const name = (0, markets_1.getMarketFullName)({ longToken, shortToken, indexToken, isSpotOnly: false, }); (0, vitest_1.expect)(name).toBe("BTC/USD [ETH-USDC]"); }); (0, vitest_1.it)("returns swap-only name", () => { const indexToken = { symbol: "ETH", address: "0xeth", decimals: 18 }; const name = (0, markets_1.getMarketFullName)({ longToken: indexToken, shortToken: indexToken, indexToken, isSpotOnly: true, }); (0, vitest_1.expect)(name).toBe("SWAP-ONLY [ETH-ETH]"); }); }); (0, vitest_1.describe)("getMarketIndexName", () => { (0, vitest_1.it)("returns 'SWAP-ONLY' if isSpotOnly is true", () => { (0, vitest_1.expect)((0, markets_1.getMarketIndexName)({ indexToken: getToken("ETH"), isSpotOnly: true, })).toBe("SWAP-ONLY"); }); (0, vitest_1.it)("returns prefix + baseSymbol/symbol + /USD", () => { const eth = getToken("ETH"); (0, vitest_1.expect)((0, markets_1.getMarketIndexName)({ indexToken: eth, isSpotOnly: false })).toBe("ETH/USD"); const pepe = getToken("PEPE"); (0, vitest_1.expect)((0, markets_1.getMarketIndexName)({ indexToken: pepe, isSpotOnly: false })).toBe("kPEPE/USD"); }); }); (0, vitest_1.describe)("getMarketPoolName", () => { (0, vitest_1.it)("returns single token symbol if long and short are the same", () => { const token = getToken("ETH"); (0, vitest_1.expect)((0, markets_1.getMarketPoolName)({ longToken: token, shortToken: token })).toBe("ETH-ETH"); }); (0, vitest_1.it)("returns combined symbol otherwise", () => { const longToken = getToken("ETH"); const shortToken = getToken("USDC"); (0, vitest_1.expect)((0, markets_1.getMarketPoolName)({ longToken, shortToken })).toBe("ETH-USDC"); }); }); (0, vitest_1.describe)("getContractMarketPrices", () => { (0, vitest_1.it)("returns undefined if any token is missing", () => { const market = { indexTokenAddress: "0xbtc", longTokenAddress: "0xeth", shortTokenAddress: "0xusdc", }; (0, vitest_1.expect)((0, markets_1.getContractMarketPrices)({}, market)).toBeUndefined(); }); (0, vitest_1.it)("returns converted contract prices if all tokens exist", () => { const tokensData = { "0xbtc": { decimals: 8, prices: { minPrice: 1000n, maxPrice: 2000n } }, "0xeth": { decimals: 18, prices: { minPrice: 3000n, maxPrice: 4000n } }, "0xusdc": { decimals: 6, prices: { minPrice: 1n, maxPrice: 2n } }, }; const market = { indexTokenAddress: "0xbtc", longTokenAddress: "0xeth", shortTokenAddress: "0xusdc", }; const result = (0, markets_1.getContractMarketPrices)(tokensData, market); (0, vitest_1.expect)(result).toBeDefined(); (0, vitest_1.expect)(result?.indexTokenPrice?.min).toBeDefined(); }); }); (0, vitest_1.describe)("getTokenPoolType", () => { (0, vitest_1.it)("returns 'long' for single-token markets if matches address", () => { const token = getToken("ETH"); (0, vitest_1.expect)((0, markets_1.getTokenPoolType)({ longToken: token, shortToken: token }, token.address)).toBe("long"); }); (0, vitest_1.it)("returns 'short' for shortToken match", () => { const longToken = getToken("ETH"); const shortToken = getToken("USDC"); (0, vitest_1.expect)((0, markets_1.getTokenPoolType)({ longToken, shortToken }, shortToken.address)).toBe("short"); }); }); (0, vitest_1.describe)("getPoolUsdWithoutPnl", () => { const marketInfo = { longPoolAmount: 1n, shortPoolAmount: 1n, longToken: { decimals: 18, prices: { minPrice: (0, numbers_1.expandDecimals)(5, 30), maxPrice: (0, numbers_1.expandDecimals)(15, 30) } }, shortToken: { decimals: 18, prices: { minPrice: (0, numbers_1.expandDecimals)(2, 30), maxPrice: (0, numbers_1.expandDecimals)(4, 30) } }, }; (0, vitest_1.it)("calculates poolUsd for isLong = true", () => { (0, vitest_1.expect)((0, markets_1.getPoolUsdWithoutPnl)(marketInfo, true, "minPrice")).toBe(5000000000000n); (0, vitest_1.expect)((0, markets_1.getPoolUsdWithoutPnl)(marketInfo, true, "maxPrice")).toBe(15000000000000n); }); (0, vitest_1.it)("calculates poolUsd for isLong = false", () => { (0, vitest_1.expect)((0, markets_1.getPoolUsdWithoutPnl)(marketInfo, false, "minPrice")).toBe(2000000000000n); (0, vitest_1.expect)((0, markets_1.getPoolUsdWithoutPnl)(marketInfo, false, "maxPrice")).toBe(4000000000000n); }); }); (0, vitest_1.describe)("getCappedPoolPnl", () => { (0, vitest_1.it)("returns capped pnl if poolPnl > maxPnl", () => { const marketInfo = { maxPnlFactorForTradersLong: 20000n, maxPnlFactorForTradersShort: 10000n, }; const result = (0, markets_1.getCappedPoolPnl)({ marketInfo, poolUsd: (0, numbers_1.expandDecimals)(1000, 30), poolPnl: 30000n, isLong: true, }); (0, vitest_1.expect)(result).toBe(30000n); }); (0, vitest_1.it)("returns poolPnl if below maxPnl", () => { const marketInfo = { maxPnlFactorForTradersLong: 20000n }; (0, vitest_1.expect)((0, markets_1.getCappedPoolPnl)({ marketInfo, poolUsd: (0, numbers_1.expandDecimals)(1000, 30), poolPnl: 5000n, isLong: true, })).toBe(5000n); }); }); (0, vitest_1.describe)("getMaxLeverageByMinCollateralFactor", () => { (0, vitest_1.it)("returns default if minCollateralFactor is undefined", () => { (0, vitest_1.expect)((0, markets_1.getMaxLeverageByMinCollateralFactor)(undefined)).toBe(1000000); }); (0, vitest_1.it)("returns correct leverage for a given factor", () => { (0, vitest_1.expect)((0, markets_1.getMaxLeverageByMinCollateralFactor)(1000000000000000000n)).toBe(10000000000000000); }); }); (0, vitest_1.describe)("getMaxAllowedLeverageByMinCollateralFactor", () => { (0, vitest_1.it)("returns half of max leverage", () => { (0, vitest_1.expect)((0, markets_1.getMaxAllowedLeverageByMinCollateralFactor)(1000000000000000000n)).toBe(5000000000000000); }); }); (0, vitest_1.describe)("getOppositeCollateral", () => { const marketInfo = { longToken: getToken("ETH"), shortToken: getToken("USDC"), }; (0, vitest_1.it)("returns shortToken if token is long", () => { (0, vitest_1.expect)((0, markets_1.getOppositeCollateral)(marketInfo, marketInfo.longToken.address)).toEqual(marketInfo.shortToken); }); (0, vitest_1.it)("returns undefined if pool type is not found", () => { (0, vitest_1.expect)((0, markets_1.getOppositeCollateral)(marketInfo, "0xbtc")).toBeUndefined(); }); }); (0, vitest_1.describe)("getAvailableUsdLiquidityForCollateral", () => { (0, vitest_1.it)("returns poolUsd if isSpotOnly", () => { const marketInfo = { isSpotOnly: true, longPoolAmount: 1n, indexToken: { ...getToken("ETH"), prices: { minPrice: (0, numbers_1.expandDecimals)(10, 18), maxPrice: (0, numbers_1.expandDecimals)(15, 18) }, }, longToken: { decimals: 18, prices: { minPrice: (0, numbers_1.expandDecimals)(1, 18), maxPrice: (0, numbers_1.expandDecimals)(2, 18) } }, }; (0, vitest_1.expect)((0, markets_1.getAvailableUsdLiquidityForCollateral)(marketInfo, true)).toBe(1n); }); (0, vitest_1.it)("calculates liquidity if not spot only", () => { const marketInfo = { isSpotOnly: false, reserveFactorLong: 1n, longPoolAmount: (0, numbers_1.expandDecimals)(5, 30), longInterestInTokens: 1n, indexToken: { ...getToken("ETH"), prices: { minPrice: (0, numbers_1.expandDecimals)(10, 18), maxPrice: (0, numbers_1.expandDecimals)(15, 18) }, }, longToken: { decimals: 18, prices: { minPrice: (0, numbers_1.expandDecimals)(10, 18), maxPrice: (0, numbers_1.expandDecimals)(15, 18) } }, }; (0, vitest_1.expect)((0, markets_1.getAvailableUsdLiquidityForCollateral)(marketInfo, true)).toBe((0, numbers_1.expandDecimals)(35, 30)); }); }); (0, vitest_1.describe)("getReservedUsd", () => { (0, vitest_1.it)("calculates reservedUsd for long side", () => { const marketInfo = { longInterestInTokens: 100n, indexToken: { decimals: 18, prices: { maxPrice: (0, numbers_1.expandDecimals)(10, 18) }, }, }; (0, vitest_1.expect)((0, markets_1.getReservedUsd)(marketInfo, true)).toBe(1000n); }); (0, vitest_1.it)("returns shortInterestUsd if isLong=false", () => { const marketInfo = { shortInterestUsd: 9999n }; (0, vitest_1.expect)((0, markets_1.getReservedUsd)(marketInfo, false)).toBe(9999n); }); }); (0, vitest_1.describe)("getMarketDivisor", () => { (0, vitest_1.it)("returns 2n if longTokenAddress equals shortTokenAddress", () => { (0, vitest_1.expect)((0, markets_1.getMarketDivisor)({ longTokenAddress: "0xsame", shortTokenAddress: "0xsame", })).toBe(2n); }); (0, vitest_1.it)("returns 1n otherwise", () => { (0, vitest_1.expect)((0, markets_1.getMarketDivisor)({ longTokenAddress: "0xeth", shortTokenAddress: "0xusdc", })).toBe(1n); }); }); (0, vitest_1.describe)("getMarketPnl", () => { (0, vitest_1.it)("returns 0n if openInterest is 0", () => { const marketInfo = { indexToken: { decimals: 18, prices: { minPrice: (0, numbers_1.expandDecimals)(1000, 18), maxPrice: (0, numbers_1.expandDecimals)(2000, 18) }, }, longInterestUsd: 0n, longInterestInTokens: 0n, }; (0, vitest_1.expect)((0, markets_1.getMarketPnl)(marketInfo, true, false)).toBe(0n); }); (0, vitest_1.it)("calculates pnl for long positions", () => { const marketInfo = { indexToken: { decimals: 18, prices: { minPrice: (0, numbers_1.expandDecimals)(1000, 18), maxPrice: (0, numbers_1.expandDecimals)(2000, 18) }, }, longInterestUsd: 1000n, longInterestInTokens: 1n, }; // maximize = false => use minPrice for long (0, vitest_1.expect)((0, markets_1.getMarketPnl)(marketInfo, true, true)).toBe(0n); // openInterestValue(1000n) - openInterestUsd(1000n) = 0 }); }); (0, vitest_1.describe)("getOpenInterestUsd", () => { (0, vitest_1.it)("returns longInterestUsd for isLong", () => { (0, vitest_1.expect)((0, markets_1.getOpenInterestUsd)({ longInterestUsd: 1234n, shortInterestUsd: 9999n }, true)).toBe(1234n); }); (0, vitest_1.it)("returns shortInterestUsd for !isLong", () => { (0, vitest_1.expect)((0, markets_1.getOpenInterestUsd)({ longInterestUsd: 1234n, shortInterestUsd: 9999n }, false)).toBe(9999n); }); }); (0, vitest_1.describe)("getOpenInterestInTokens", () => { (0, vitest_1.it)("returns longInterestInTokens for isLong", () => { (0, vitest_1.expect)((0, markets_1.getOpenInterestInTokens)({ longInterestInTokens: 100n, shortInterestInTokens: 200n }, true)).toBe(100n); }); (0, vitest_1.it)("returns shortInterestInTokens for !isLong", () => { (0, vitest_1.expect)((0, markets_1.getOpenInterestInTokens)({ longInterestInTokens: 100n, shortInterestInTokens: 200n }, false)).toBe(200n); }); }); (0, vitest_1.describe)("getPriceForPnl", () => { (0, vitest_1.it)("uses maxPrice for long when maximize=true", () => { (0, vitest_1.expect)((0, markets_1.getPriceForPnl)({ minPrice: 1000n, maxPrice: 2000n }, true, true)).toBe(2000n); }); (0, vitest_1.it)("uses maxPrice for short when maximize=false", () => { (0, vitest_1.expect)((0, markets_1.getPriceForPnl)({ minPrice: 1000n, maxPrice: 2000n }, false, false)).toBe(2000n); }); });