// usage: // $ npm install graphql-request table ts-node // $ npm install -D @types/table // $ ts-node fields_tvl.ts import { request, gql } from "graphql-request"; import { table } from "table"; const ASTRO_GENERATOR = "terra1zgrx9jjqrfye8swykfgmd6hpde60j0nszzupp9"; const MARS_RED_BANK = "terra19dtgj9j5j7kyf3pmejqv8vzfpxtejaypgzkz5u"; const graphUrl = "https://mantle.terra.dev"; type PoolResponse = { assets: { info: { token: { contract_addr: string } } | { native_token: { denom: string } }; amount: string; }[]; total_share: string; }; type BondResponse = string; interface DebtResponse { amount: string; } async function calculateStrategyTvl(strategy: string, pair: string, lpToken: string) { const query = gql` query fieldsTvl( $poolQuery: String!, $bondQuery: String!, $debtQuery: String!, ) { poolResponse: WasmContractsContractAddressStore( ContractAddress: "${pair}", QueryMsg: $poolQuery ) { Result }, bondResponse: WasmContractsContractAddressStore( ContractAddress: "${ASTRO_GENERATOR}", QueryMsg: $bondQuery ) { Result }, debtResponse: WasmContractsContractAddressStore( ContractAddress: "${MARS_RED_BANK}", QueryMsg: $debtQuery ) { Result } } `; const results = await request(graphUrl, query, { poolQuery: JSON.stringify({ pool: {}, }), bondQuery: JSON.stringify({ deposit: { lp_token: lpToken, user: strategy, }, }), debtQuery: JSON.stringify({ user_asset_debt: { user_address: strategy, asset: { native: { denom: "uusd", }, }, }, }), }); const poolResponse: PoolResponse = JSON.parse(results.poolResponse.Result); const bondResponse: BondResponse = JSON.parse(results.bondResponse.Result); const debtResponse: DebtResponse = JSON.parse(results.debtResponse.Result); const assetDepth = parseInt( poolResponse.assets.find( (asset) => JSON.stringify(asset.info) != '{"native_token":{"denom":"uusd"}}', )!.amount, ); const uusdDepth = parseInt( poolResponse.assets.find( (asset) => JSON.stringify(asset.info) == '{"native_token":{"denom":"uusd"}}', )!.amount, ); const bondedShares = parseInt(bondResponse); const totalShares = parseInt(poolResponse.total_share); const uusdBorrowed = parseInt(debtResponse.amount); const assetBonded = (assetDepth * bondedShares) / totalShares; const uusdBonded = (uusdDepth * bondedShares) / totalShares; const assetPrice = uusdDepth / assetDepth; const bondValue = (assetBonded * assetPrice + uusdBonded * 1) / 1e6; const debtValue = (uusdBorrowed * 1) / 1e6; return { bondValue, debtValue }; } const formatInteger = (x: number) => x.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, ","); const formatPercentage = (x: number) => (100 * x).toFixed(1) + "%"; (async function () { const lunaStrategyTvl = await calculateStrategyTvl( "terra1kztywx50wv38r58unxj9p6k3pgr2ux6w5x68md", // Fields of Mars LUNA-UST strategy "terra1m6ywlgn6wrjuagcmmezzz2a029gtldhey5k552", // Astroport LUNA-UST pair "terra1m24f7k4g66gnh9f7uncp32p722v0kyt3q4l3u5", // Astroport LUNA-UST LP token ); const ancStrategyTvl = await calculateStrategyTvl( "terra1vapq79y9cqghqny7zt72g4qukndz282uvqwtz6", // Fields of Mars ANC-UST strategy "terra1qr2k6yjjd5p2kaewqvg93ag74k6gyjr7re37fs", // Astroport ANC-UST pair "terra1wmaty65yt7mjw6fjfymkd9zsm6atsq82d9arcd", // Astroport ANC-UST LP token ); const mirStrategyTvl = await calculateStrategyTvl( "terra12dq4wmfcsnz6ycep6ek4umtuaj6luhfp256hyu", // Fields of Mars MIR-UST strategy "terra143xxfw5xf62d5m32k3t4eu9s82ccw80lcprzl9", // Astroport MIR-UST pair "terra17trxzqjetl0q6xxep0s2w743dhw2cay0x47puc", // Astroport MIR-UST LP token ); console.log( table( [ ["strategy", "asset_value", "debt_value", "overall_ltv"], [ "LUNA-UST", formatInteger(lunaStrategyTvl.bondValue), formatInteger(lunaStrategyTvl.debtValue), formatPercentage(lunaStrategyTvl.debtValue / lunaStrategyTvl.bondValue), ], [ "ANC-UST", formatInteger(ancStrategyTvl.bondValue), formatInteger(ancStrategyTvl.debtValue), formatPercentage(ancStrategyTvl.debtValue / ancStrategyTvl.bondValue), ], [ "MIR-UST", formatInteger(mirStrategyTvl.bondValue), formatInteger(mirStrategyTvl.debtValue), formatPercentage(mirStrategyTvl.debtValue / mirStrategyTvl.bondValue), ], [ "total", formatInteger(lunaStrategyTvl.bondValue + ancStrategyTvl.bondValue + mirStrategyTvl.bondValue), formatInteger(lunaStrategyTvl.debtValue + ancStrategyTvl.debtValue + mirStrategyTvl.debtValue), "n/a" ] ], { drawHorizontalLine: (lineIndex, rowCount) => { return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount - 1 || lineIndex === rowCount; }, columns: [ { alignment: "left" }, { alignment: "right" }, { alignment: "right" }, { alignment: "right" }, ], }, ), ); })();