|
| 1 | + |
| 2 | +const { cachedGraphQuery } = require("../helper/cache"); |
| 3 | + |
| 4 | +const config = { |
| 5 | + sei: { |
| 6 | + reader: "0xfeafb31AC7f09892B50c4d6DA06a1e48D487499E", |
| 7 | + api_url: "https://indexer-sei.mgvinfra.com/", |
| 8 | + chainId: 1329, |
| 9 | + } |
| 10 | +} |
| 11 | + |
| 12 | +const abi = { |
| 13 | + openMarkets: "function openMarkets() view returns ((address,address,uint256)[])", |
| 14 | + offerList: "function offerList((address,address,uint256),uint256,uint256) view returns (uint256,uint256[],(uint256,uint256,int256,uint256)[],(address,uint256,uint256,uint256)[])", |
| 15 | + getUnderlyingBalances: "function getUnderlyingBalances() public view returns (uint256 baseAmount, uint256 quoteAmount)", |
| 16 | +} |
| 17 | + |
| 18 | + |
| 19 | +const query = (chainId) => ` |
| 20 | +query DefiLlama { |
| 21 | + mangroveVaults (where:{chainId:${chainId}}) { |
| 22 | + items { |
| 23 | + address |
| 24 | + baseAddress |
| 25 | + quoteAddress |
| 26 | + kandelAddress |
| 27 | + } |
| 28 | + } |
| 29 | +} |
| 30 | +` |
| 31 | + |
| 32 | +module.exports = { |
| 33 | + methodology: "TVL is the total value promised on oxium markets in addition to all non promised value that are in the ALM vaults.", |
| 34 | + start: "2025-04-25", |
| 35 | + doublecounted: true, // tokens are kept in yei vault to get the yield |
| 36 | +} |
| 37 | + |
| 38 | +Object.keys(config).forEach(chain => { |
| 39 | + const configEntry = config[chain] |
| 40 | + module.exports[chain] = { |
| 41 | + tvl: async (api) => { |
| 42 | + |
| 43 | + // vault tvl |
| 44 | + const { mangroveVaults: { items } } = await cachedGraphQuery(`oxium-vaults-${configEntry.chainId}`, configEntry.api_url, query(configEntry.chainId)) |
| 45 | + const vaultMakers = new Set() |
| 46 | + const vaultBals = await api.multiCall({ abi: abi.getUnderlyingBalances, calls: items.map(vault => vault.address) }) |
| 47 | + vaultBals.forEach((bals, i) => { |
| 48 | + const { baseAddress, quoteAddress, kandelAddress } = items[i] |
| 49 | + vaultMakers.add(kandelAddress.toLowerCase()) |
| 50 | + |
| 51 | + api.add(baseAddress.toLowerCase(), bals.baseAmount) |
| 52 | + api.add(quoteAddress.toLowerCase(), bals.quoteAmount) |
| 53 | + }) |
| 54 | + |
| 55 | + |
| 56 | + // book tvl |
| 57 | + const openMarkets = await api.call({ target: configEntry.reader, abi: abi.openMarkets, }) |
| 58 | + for (const market of openMarkets) { |
| 59 | + let currentId = 0 |
| 60 | + const token = market[0] |
| 61 | + do { |
| 62 | + |
| 63 | + const [newCurrId, _, offers, offerDetails] = await api.call({ |
| 64 | + target: configEntry.reader, |
| 65 | + abi: abi.offerList, |
| 66 | + params: [market, currentId, 100], |
| 67 | + }) |
| 68 | + offers.forEach((offer, index) => { |
| 69 | + const maker = offerDetails[index][0].toLowerCase() |
| 70 | + if (vaultMakers.has(maker)) return // skip vaults |
| 71 | + const gives = offer[3] |
| 72 | + api.add(token.toLowerCase(), gives) |
| 73 | + }) |
| 74 | + |
| 75 | + currentId = +newCurrId |
| 76 | + } while (currentId !== 0) |
| 77 | + } |
| 78 | + } |
| 79 | + } |
| 80 | +}) |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | + |
0 commit comments