Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
94a262d
init Klaytn Bluewhale
bluewhale-saito Feb 5, 2024
9985e74
Refactor Bluewhale contract and update token addresses
g1nt0ki Feb 6, 2024
c712bb7
Merge branch 'DefiLlama:main' into main
bluewhale-saito Feb 7, 2024
bb8370c
Add bluewhale v3 tvl
bluewhale-saito May 10, 2024
bdfd36d
Merge branch 'DefiLlama:main' into main
bluewhale-saito Oct 22, 2025
0a77c11
add PumpSpace.
bluewhale-saito Oct 23, 2025
0f6144d
add PumpSpace Token WAVAX
bluewhale-saito Oct 23, 2025
49a49bb
feat(pumpspace): token mappings for bUSDT & WAVAX
bluewhale-saito Oct 23, 2025
4f6353b
Merge branch 'DefiLlama:main' into main
bluewhale-saito Oct 23, 2025
f8ad4d7
Merge branch 'DefiLlama:main' into main
bluewhale-saito Oct 24, 2025
c9bed2d
Add AquaBank TVL and Staking adapter (Avalanche)
bluewhale-saito Oct 24, 2025
7e6ce16
Merge branch 'DefiLlama:main' into main
bluewhale-saito Oct 27, 2025
261fcd3
I’ve removed staking and kept only tvl
bluewhale-saito Oct 27, 2025
9ec2c94
Merge commit '7e6ce160982b0b274ba89e7aee4b8e76f8c63828'
bluewhale-saito Oct 27, 2025
f7cb315
WAVAX mapping can be safely removed
bluewhale-saito Oct 27, 2025
2e9629b
Merge branch 'DefiLlama:main' into main
bluewhale-saito Oct 28, 2025
cbc3dac
removed staking, transformAddress mappings
bluewhale-saito Oct 28, 2025
cbabb11
use DefiLlama helpers
bluewhale-saito Oct 29, 2025
7854cdc
TVL adapter using bUSDT supply backed
bluewhale-saito Nov 5, 2025
8e1e265
Merge branch 'DefiLlama:main' into main
bluewhale-saito Nov 5, 2025
4486442
adapter will sum `balanceOf`for each receipt token
bluewhale-saito Nov 6, 2025
6e55f10
Merge branch 'DefiLlama:main' into main
bluewhale-saito Nov 6, 2025
5d2e175
Merge commit '6e55f107f6df43e838960552b4a67811635a67ae'
bluewhale-saito Nov 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions projects/aquabank/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// projects/aquabank/index.js
const ADDRESSES = require('../helper/coreAssets.json')
const { sumTokens2 } = require('../helper/unwrapLPs')

const USDt = ADDRESSES.avax.USDt // 0x9702230A8Ea53601f5Cd2dc00fDBc13d4dF4A8c7

// Vaults that hold receipt tokens (not the underlying)
const BENQI_VAULT = '0x7D336B49879a173626E51BFF780686D88b8081ec'
const EULER_VAULT = '0x61E8f77eD693d3edeCBCc2dd9c55c1d987c47775'

// Protocol receipt tokens (convertible to USDt underlying)
const BENQI_RECEIPT = '0xd8fcDa6ec4Bdc547C0827B8804e89aCd817d56EF'
const EULER_RECEIPT = '0xa446938b0204Aa4055cdFEd68Ddf0E0d1BAB3E9E'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we price both of these too, you can just export a balance of the receipt tokens, no need for conversion


// Bank staking contracts where bUSDT is deposited
const bUSDT = '0x3C594084dC7AB1864AC69DFd01AB77E8f65B83B7'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is now priced on the server

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I’ve made the following updates based on your feedback:

Aquabank: removed staking and kept only tvl to prevent double counting of the USDt underlying.

PumpSpace: removed the temporary transformAddress mappings (bUSDT → USDt, WAVAX proxy → WAVAX) since these assets are now priced on the server.

const STAKERS = [
'0x00F8a3B9395B4B02d12ee26536046c3C52459674', // Benqi BankStaking
'0x743BcD612866fC7485BfC487B14Ebf9a67D753Cb', // Euler BankStaking
]

// ABIs
const erc20Bal = 'function balanceOf(address) view returns (uint256)'

const benqiAbi = {
// Compound-style exchange rate (scaled by 1e18)
exchangeRateStored: 'function exchangeRateStored() view returns (uint256)',
underlying: 'function underlying() view returns (address)',
}

const eulerAbi = {
// ERC4626-style conversion from shares to assets
convertToAssets: 'function convertToAssets(uint256 shares) view returns (uint256)',
asset: 'function asset() view returns (address)',
}

const toStr = (x) => (x?.toString?.() ?? String(x))
const toBN = (x) => BigInt(toStr(x))

// TVL: sum USDt underlying represented by Benqi/Euler receipt tokens held in the vaults
async function tvl(api) {

// 1) Read receipt balances held by the two vaults
const [benqiShares, eulerShares] = await Promise.all([
api.call({ target: BENQI_RECEIPT, abi: erc20Bal, params: BENQI_VAULT, permitFailure: true }),
api.call({ target: EULER_RECEIPT, abi: erc20Bal, params: EULER_VAULT, permitFailure: true }),
])

// 2) Convert Benqi shares -> USDt underlying using Compound-style exchange rate
let benqiUnderlying = 0n
if (benqiShares) {
const rate = await api.call({ target: BENQI_RECEIPT, abi: benqiAbi.exchangeRateStored, permitFailure: true })
if (rate) {
// underlying = shares * rate / 1e18
benqiUnderlying = (toBN(benqiShares) * toBN(rate)) / 10n**18n
}
}

// 3) Convert Euler shares -> USDt underlying using ERC4626 conversion
let eulerUnderlying = 0n
if (eulerShares) {
const out = await api.call({
target: EULER_RECEIPT, abi: eulerAbi.convertToAssets, params: eulerShares, permitFailure: true
})
if (out) eulerUnderlying = toBN(out)
}

// 4) Add both underlyings as USDt
if (benqiUnderlying > 0n) api.add(USDt, benqiUnderlying)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we price these vault receipt tokens, you can just export a balance of the receipt tokens, no need for conversion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks! 👍
I’ve updated the adapter to export the raw balances of the Benqi and Euler receipt tokens directly,
removing the manual USDt conversion since they’re already priced server-side.

if (eulerUnderlying > 0n) api.add(USDt, eulerUnderlying)

return api.getBalances()
}

// Staking: sum bUSDT deposited in BankStaking contracts, mapped 1:1 to USDt
async function staking(api) {
const tokensAndOwners = STAKERS.map(owner => [bUSDT, owner])

// - bUSDT → USDt (Tether on Avalanche)
return await sumTokens2({
api,
tokensAndOwners,
transformAddress: (addr) => {
const a = addr.toLowerCase()
if (a === bUSDT.toLowerCase()) return `avax:${USDt.toLowerCase()}`
return `avax:${a}`
},
})
}


module.exports = {
methodology:
' TVL = USDt underlying represented by Benqi/Euler receipt tokens held in vaults (Benqi: shares*exchangeRate/1e18, Euler: convertToAssets). Staking = bUSDT deposited in BankStaking contracts, reported as USDt via 1:1 mapping.',
avax: {
tvl,
staking,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove this as it is doublecounting the underlying in tvl

},
}


146 changes: 146 additions & 0 deletions projects/pumpspace/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// projects/pumpspace/index.js
const ADDRESSES = require('../helper/coreAssets.json')
const { staking } = require('../helper/staking')
const { getUniTVL } = require('../helper/unknownTokens');
const { getTridentTVL } = require('../helper/sushi-trident')
const { sumTokens2 } = require('../helper/unwrapLPs')
const sdk = require('@defillama/sdk')

const CHAIN = 'avax'

// --- FACTORIES / CONTRACTS ---
const PUMP_FACTORY = '0x26B42c208D8a9d8737A2E5c9C57F4481484d4616' // V2
const PUMP_V3 = '0xE749c1cA2EA4f930d1283ad780AdE28625037CeD' // V3/Trident

// If you later expose staking for other MasterChefs, add here
const MASTERCHEFS = [
'0x40a58fc672F7878F068bD8ED234a47458Ec33879', // SHELL
'0x56b54a1384d35C63cD95b39eDe9339fEf7df3E42', // KRILL
'0x06C551B19239fE6a425b3c45Eb8b49d28e8283C6', // PEARL
]

// --- TOKENS (project/local wrappers + protocol tokens) ---
const TOKENS = {
bUSDT: '0x3C594084dC7AB1864AC69DFd01AB77E8f65B83B7', // mapped to USDt
WAVAX_PROXY: "0xAB4fBa02a2905a03adA8BD3d493FB289Dcf84024", // mapped to canonical WAVAX below
sBWPM: "0x6c960648d5F16f9e12895C28655cc6Dd73B660f7",
sADOL: "0x6214D13725d458890a8EF39ECB2578BdfCd82170",
CLAM: "0x1ea53822f9B2a860A7d20C6D2560Fd07db7CFF85",
PEARL: "0x08c4b51e6Ca9Eb89C255F0a5ab8aFD721420e447",
KRILL: "0x4ED0A710a825B9FcD59384335836b18C75A34270",
SHELL: '0xaD4CB79293322c07973ee83Aed5DF66A53214dc6',
}


// Map wrapped/local tokens to canonical core assets for pricing/aggregation.
// - bUSDT → USDt (Tether on Avalanche)
// - WAVAX proxy (0xAB4f...) → canonical WAVAX (0xB31f...)
function transformAddress(addr) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will add support for these assets so this transform will no longer be required DefiLlama/defillama-server#10877

const a = addr.toLowerCase()
if (a === TOKENS.bUSDT.toLowerCase())
return `avax:${ADDRESSES.avax.USDt.toLowerCase()}`
if (a === TOKENS.WAVAX_PROXY.toLowerCase())
return `avax:${ADDRESSES.avax.WAVAX.toLowerCase()}`
return `avax:${a}`
}

// ---------- V2 factory TVL (sum token reserves held by each pair) ----------
const uniAbis = {
allPairsLength: 'function allPairsLength() view returns (uint256)',
allPairs: 'function allPairs(uint256) view returns (address)',
token0: 'function token0() view returns (address)',
token1: 'function token1() view returns (address)',
}

// ---------- V3 (Trident) TVL: factory → pool list → asset list → sum with transforms ----------
const tridentAbis = {
totalPoolsCount: "uint256:totalPoolsCount",
getPoolAddress: "function getPoolAddress(uint256 idx) view returns (address pool)",
getAssets: "address[]:getAssets",
}


async function v2FactoryTVLWithBusdtMapping(api) {
// 1) enumerate all pairs from the V2 factory
const n = await api.call({ target: PUMP_FACTORY, abi: uniAbis.allPairsLength })
const idx = Array.from({ length: Number(n) }, (_, i) => i)
const pairs = await api.multiCall({
abi: uniAbis.allPairs,
calls: idx.map(i => ({ target: PUMP_FACTORY, params: i })),
})

// 2) get token0/token1 for each pair
const [token0s, token1s] = await Promise.all([
api.multiCall({ abi: uniAbis.token0, calls: pairs.map(p => ({ target: p })) }),
api.multiCall({ abi: uniAbis.token1, calls: pairs.map(p => ({ target: p })) }),
])

// 3) for each pair, count reserves via ERC20.balanceOf(pair)
const tokensAndOwners = []
for (let i = 0; i < pairs.length; i++) {
const t0 = token0s[i]?.toLowerCase()
const t1 = token1s[i]?.toLowerCase()
if (!t0 || !t1) continue
tokensAndOwners.push([t0, pairs[i]])
tokensAndOwners.push([t1, pairs[i]])
}

// 4) aggregate with transforms (bUSDT→USDt, WAVAX proxy→WAVAX)
return sumTokens2({
api,
tokensAndOwners,
transformAddress,
// resolveLP: false // V2 pairs counted by reserves; no unwrapping required here
})
}

async function v3FactoryTVLWithMappings(ts, _block, { [CHAIN]: block }) {
// 1) number of pools
const pairLength = (await sdk.api.abi.call({
target: PUMP_V3, abi: tridentAbis.totalPoolsCount, chain: CHAIN, block
})).output

// 2) pool addresses
const idxs = Array.from({ length: Number(pairLength) }, (_, i) => i)
const pools = (await sdk.api.abi.multiCall({
abi: tridentAbis.getPoolAddress, chain: CHAIN,
calls: idxs.map(i => ({ target: PUMP_V3, params: [i] })), block
})).output.map(r => r.output)

// 3) assets per pool
const { output: assetLists } = await sdk.api.abi.multiCall({
abi: tridentAbis.getAssets, chain: CHAIN,
calls: pools.map(p => ({ target: p })), block,
})

// 4) build [token, owner(pool)] tuples
const toa = []
assetLists.forEach(({ output, input: { target: pool } }) =>
output.forEach(token => toa.push([token, pool]))
)

// 5) aggregate with transforms (bUSDT→USDt, WAVAX proxy→WAVAX)
return sumTokens2({ chain: CHAIN, block, tokensAndOwners: toa, transformAddress })
}

module.exports = {
misrepresentedTokens: true,
methodology: `
TVL is calculated by summing up all reserves from both PumpSpace V2 and V3 (Trident) factories.
For accurate valuation, the following transformations are applied:
- bUSDT is mapped 1:1 to USDt (Tether) so its liquidity and price are aggregated under USDT.
- WAVAX proxy token (0xAB4f...) is mapped to the canonical Avalanche WAVAX (0xB31f...).
This ensures all liquidity pools using wrapped variants are properly reflected in total TVL.
Staking represents single-token staking of SHELL from the Shell MasterChef contract.
`,
avax: {
tvl: sdk.util.sumChainTvls([
v2FactoryTVLWithBusdtMapping,
v3FactoryTVLWithMappings,
]),
staking: sdk.util.sumChainTvls([
// If you later add KRILL/PEARL single-asset staking, append similar lines here.
staking([MASTERCHEFS[0]], [TOKENS.SHELL]),
])
},
}
Loading