diff --git a/projects/helper/utils/solana/layouts/raydium-layout.js b/projects/helper/utils/solana/layouts/raydium-layout.js index 7c3b3cafd8c3..55f4669c9b11 100644 --- a/projects/helper/utils/solana/layouts/raydium-layout.js +++ b/projects/helper/utils/solana/layouts/raydium-layout.js @@ -185,6 +185,18 @@ const RAYDIUM_STABLE_STATE_LAYOUT_V1 = struct([ seq(u64("padding"), 64, "padding"), ]) +const KeyLayoutv4 = struct([ + publicKey('vaultA'), + publicKey('vaultB'), + publicKey('mintA'), + publicKey('mintB'), +]) + +const TokenAmountLayout = struct([ + u64('amount'), +]) + + module.exports = { - RAYDIUM_LIQUIDITY_STATE_LAYOUT_CLMM, RAYDIUM_STABLE_STATE_LAYOUT_V1, + RAYDIUM_LIQUIDITY_STATE_LAYOUT_CLMM, RAYDIUM_STABLE_STATE_LAYOUT_V1, KeyLayoutv4, TokenAmountLayout, } \ No newline at end of file diff --git a/projects/marinade-native/index.js b/projects/marinade-native/index.js index ecb86f706c54..8f84c77ce062 100644 --- a/projects/marinade-native/index.js +++ b/projects/marinade-native/index.js @@ -2,25 +2,15 @@ const { StakeProgram } = require("@solana/web3.js") const { getConnection } = require('../helper/solana') async function tvl() { - let hasNext = true - let offset = 0 - let length = 9 - let nativeTvl = 0 - do { - const _stakeAccounts = await getConnection().getProgramAccounts(StakeProgram.programId, { - filters: [{ - memcmp: { bytes: 'stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq', offset: 4 + 8 } - }], - dataSlice: { offset, length } - }) - nativeTvl += _stakeAccounts.reduce((tvl, { account }) => { return tvl + account.lamports / 1e9 }, 0) - - hasNext = _stakeAccounts.length === length - offset += length - } while (hasNext) + const stakeAccounts = await getConnection().getProgramAccounts(StakeProgram.programId, { + filters: [{ + memcmp: { bytes: 'stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq', offset: 4 + 8 } + }], + dataSlice: { offset: 0, length: 1 } // we dont care about the data, just the lamports + }) return { - solana: nativeTvl + solana: stakeAccounts.reduce((tvl, { account }) => { return tvl + account.lamports / 1e9 }, 0) } } diff --git a/projects/raydium.js b/projects/raydium.js index cad0631e7c30..b179ff1d78fd 100644 --- a/projects/raydium.js +++ b/projects/raydium.js @@ -1,6 +1,10 @@ const { getConnection, sumTokens2, decodeAccount, } = require("./helper/solana"); const { PublicKey, } = require("@solana/web3.js"); -const sdk = require('@defillama/sdk'); +const sdk = require('@defillama/sdk') + +const { TokenAmountLayout, KeyLayoutv4 } = require("./helper/utils/solana/layouts/raydium-layout"); +const { transformDexBalances } = require("./helper/portedTokens"); +const { sleep } = require("./helper/utils"); const CLMM = 'CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK' const AmmV4 = '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8' @@ -31,49 +35,90 @@ async function tvlCLMM() { } -async function ammV4Tvl() { - const owner = '5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1' - return sumTokens2({ owner, getAllTokenAccounts: true }) +async function ammV4Tvl(api) { + const connection = getConnection() + const auth = '5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1' + + await sleep(10000) + const allPoolVaultAmount = await connection.getProgramAccounts(new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'), { filters: [{ dataSize: 165 }, { memcmp: { offset: 32, bytes: auth } }], dataSlice: { offset: 64, length: TokenAmountLayout.span } }) + await sleep(30000) + const allPoolKeyInfo = await connection.getProgramAccounts(new PublicKey(AmmV4), { filters: [{ dataSize: 752 }], dataSlice: { offset: 336, length: KeyLayoutv4.span } }) + + const vaultIdToAmount = {} + for (const item of allPoolVaultAmount) { + vaultIdToAmount[item.pubkey.toString()] = TokenAmountLayout.decode(item.account.data).amount.toString() + } + + let i = 0 + let j = 0 + let data = [] + const emptyKey = PublicKey.default.toString() + for (const item of allPoolKeyInfo) { + const poolKey = KeyLayoutv4.decode(item.account.data) + if (poolKey.vaultA.toString() === emptyKey) continue + const vaultA = poolKey.vaultA.toString() + const vaultB = poolKey.vaultB.toString() + if (isNaN(vaultIdToAmount[vaultA]) || isNaN(vaultIdToAmount[vaultB])) continue + + data.push({ + token0: poolKey.mintA.toString(), + token1: poolKey.mintB.toString(), + token0Bal: vaultIdToAmount[vaultA], + token1Bal: vaultIdToAmount[vaultB], + }) + j++ + if (i > 5000) { + await transformDexBalances({ api, data }) + data = [] + i = 0 + } + i++ + } + await transformDexBalances({ api, data }) + return api.getBalances() } async function ammV2V3() { - return sumTokens2({ tokenAccounts: [ - // v2 - '8tA74jqYPNmr8pcvZE3FBxmLMDqFMvZryny8XojCD5CE', - '7t51g6PFAfnBtWqooQhHErneVqQb4SN1QuPnG7iGa87M', - '5fHS778vozoDDYzzJz2xYG39whTzGGW6bF71GVxRyMXi', - 'CzVe191iLM2E31DBW7isXpZBPtcufRRsaxNRc8uShcEs', - 'G2zmxUhRGn12fuePJy9QsmJKem6XCRnmAEkf8G6xcRTj', - 'H617sH2JNjMqPhRxsu43C8vDYfjZrFuoMEKdJyMu7V3t', - 'CJukFFmH9FZ98uzFkUNgqRn8xUmSBTUETEDUMxZXk6p8', - 'DoZyq9uo3W4WWBZJvPCvfB5cCBFvjU9oq3DdYjNgJNRX', - 'Gej1jXVRMdDKWSxmEZ78KJp5jruGJfR9dV3beedXe3BG', - 'FUDEbQKfMTfAaKS3dGdPEacfcC9bRpa5gmmDW8KNoUKp', - '3NAqRJFepsd2dae98Yj7uALQxiV1YRcZJoUcuXErK1FF', - '9RPGJb7pSyiLKKACmeoSgqeypiEymZneBHWbHerQC9Qm', - '7r5YjMLMnmoYkD1bkyYq374yiTBG9XwBHMwi5ZVDptre', - '6vMeQvJcC3VEGvtZ2TDXcShZerevxkqfW43yjX14vmSz', - 'CvcqJtGdS9C1jKKFzgCi5p8qsnR5BZCohWvYMBJXcnJ8', - 'AiYm8jzb2WB4HTTFTHX1XCS7uVSQM5XWnMsure5sMeQY', - // v3 - 'DujWhSxnwqFd3TrLfScyUhJ3FdoaHrmoiVE6kU4ETQyL', - 'D6F5CDaLDCHHWfE8kMLbMNAFULXLfM572AGDx2a6KeXc', - 'Eg6sR9H28cFaek5DVdgxxDcRKKbS85XvCFEzzkdmYNhq', - '8g2nHtayS2JnRxaAY5ugsYC8CwiZutQrNWA9j2oH8UVM', - 'DTQTBTSy3tiy7kZZWgaczWxs9snnTVTi8DBYBzjaVwbj', - 'Bk2G4zhjB7VmRsaBwh2ijPwq6tavMHALEq4guogxsosT', - 'ENjXaFNDiLTh44Gs89ZtfUH2i5MGLLkfYbSY7TmP4Du3', - '9uzWJD2WqJYSmB6UHSyPMskFGoP5L6hB7FxqUdYP4Esm', - 'Fy6SnHwAkxoGMhUH2cLu2biqAnHmaAwFDDww9k6gq5ws', - 'GoRindEPofTJ3axsonTnbyf7cFwdFdG1A3MG9ENyBZsn', - ] }) + return sumTokens2({ + tokenAccounts: [ + // v2 + '8tA74jqYPNmr8pcvZE3FBxmLMDqFMvZryny8XojCD5CE', + '7t51g6PFAfnBtWqooQhHErneVqQb4SN1QuPnG7iGa87M', + '5fHS778vozoDDYzzJz2xYG39whTzGGW6bF71GVxRyMXi', + 'CzVe191iLM2E31DBW7isXpZBPtcufRRsaxNRc8uShcEs', + 'G2zmxUhRGn12fuePJy9QsmJKem6XCRnmAEkf8G6xcRTj', + 'H617sH2JNjMqPhRxsu43C8vDYfjZrFuoMEKdJyMu7V3t', + 'CJukFFmH9FZ98uzFkUNgqRn8xUmSBTUETEDUMxZXk6p8', + 'DoZyq9uo3W4WWBZJvPCvfB5cCBFvjU9oq3DdYjNgJNRX', + 'Gej1jXVRMdDKWSxmEZ78KJp5jruGJfR9dV3beedXe3BG', + 'FUDEbQKfMTfAaKS3dGdPEacfcC9bRpa5gmmDW8KNoUKp', + '3NAqRJFepsd2dae98Yj7uALQxiV1YRcZJoUcuXErK1FF', + '9RPGJb7pSyiLKKACmeoSgqeypiEymZneBHWbHerQC9Qm', + '7r5YjMLMnmoYkD1bkyYq374yiTBG9XwBHMwi5ZVDptre', + '6vMeQvJcC3VEGvtZ2TDXcShZerevxkqfW43yjX14vmSz', + 'CvcqJtGdS9C1jKKFzgCi5p8qsnR5BZCohWvYMBJXcnJ8', + 'AiYm8jzb2WB4HTTFTHX1XCS7uVSQM5XWnMsure5sMeQY', + // v3 + 'DujWhSxnwqFd3TrLfScyUhJ3FdoaHrmoiVE6kU4ETQyL', + 'D6F5CDaLDCHHWfE8kMLbMNAFULXLfM572AGDx2a6KeXc', + 'Eg6sR9H28cFaek5DVdgxxDcRKKbS85XvCFEzzkdmYNhq', + '8g2nHtayS2JnRxaAY5ugsYC8CwiZutQrNWA9j2oH8UVM', + 'DTQTBTSy3tiy7kZZWgaczWxs9snnTVTi8DBYBzjaVwbj', + 'Bk2G4zhjB7VmRsaBwh2ijPwq6tavMHALEq4guogxsosT', + 'ENjXaFNDiLTh44Gs89ZtfUH2i5MGLLkfYbSY7TmP4Du3', + '9uzWJD2WqJYSmB6UHSyPMskFGoP5L6hB7FxqUdYP4Esm', + 'Fy6SnHwAkxoGMhUH2cLu2biqAnHmaAwFDDww9k6gq5ws', + 'GoRindEPofTJ3axsonTnbyf7cFwdFdG1A3MG9ENyBZsn', + ] + }) } module.exports = { timetravel: false, + misrepresentedTokens: true, hallmarks: [[1667865600, "FTX collapse"]], solana: { tvl: sdk.util.sumChainTvls([tvlCLMM, ammStableTvl, ammV4Tvl, ammV2V3]), - staking: () => sumTokens2({ tokenAccounts: ['8tnpAECxAT9nHBqR1Ba494Ar5dQMPGhL31MmPJz1zZvY']}) + staking: () => sumTokens2({ tokenAccounts: ['8tnpAECxAT9nHBqR1Ba494Ar5dQMPGhL31MmPJz1zZvY'] }) }, }; \ No newline at end of file