This repository was archived by the owner on Dec 11, 2025. It is now read-only.
forked from DefiLlama/DefiLlama-Adapters
-
Notifications
You must be signed in to change notification settings - Fork 0
Calculate TVL across all chains #1
Open
zajck
wants to merge
5
commits into
main
Choose a base branch
from
boson-tvl-adapter
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+309
−2
Open
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| const protocolDiamondAddress = "0x59A4C19b55193D5a2EAD0065c54af4d516E18Cb5"; | ||
|
|
||
| const protocolDeploymentBlock = { | ||
| polygon: 34258150, | ||
| ethereum: 18240548, | ||
| base: 25765296, | ||
| arbitrum: 321778899, | ||
| optimism: 133002790, | ||
| }; | ||
|
|
||
| /** Event topics **/ | ||
| const fundsDepositedTopic = | ||
| "0x862dfcd9710943e66ad8f1f01a99cc98ab5612a09e62ecc68f63fe2e0f86cb0e"; | ||
| const fundsEncumberedTopic = | ||
| "0x8080d30eb13935d67dfdc606fa5e4170aa03ffdfaf40136ef3fa4355c88b19f9"; | ||
| const offerCreatedTopic_v2_0_0 = | ||
| "0x845c99b8425be384387e239b85d44b6cdf63aab6c45c2534f799743e341c74f8"; | ||
| const offerCreatedTopic_v2_3_0 = | ||
| "0xb6a507882e43ec6bae2f276ce4a839f1ca9dcf2da73095eea9e633e96ecf6eb2"; | ||
| const offerCreatedTopic_v2_4_0 = | ||
| "0xa76af238b31b285c9397e2a7c55650ca18a1baf6504de15d7dd1321693144cf7"; | ||
| const offerCreatedTopic_v2_5_0 = | ||
| "0x5235a4f9db2e479e7353e22e7629a4556897ddaf0ab4eaeb9bb8660c8e49a903"; | ||
| const offerVoidedTopic = | ||
| "0xe7c7f2b8b4a6597a3aa617aff2d206ea5507c118fb6d4e54e130279510796fd5"; | ||
|
|
||
| const buyerCommittedTopic_v2_0_0 = | ||
| "0x442279a0d0683a12971990518f9f3f874391650139a762c4e94b23b51f04d94f"; | ||
| const buyerCommittedTopic_v2_5_0 = | ||
| "0xb52015a0ea2e0345baee81bf183c410328b8f8d0cfd380c43006bb84b78fc100"; | ||
|
|
||
| /** Event definitions **/ | ||
| /** | ||
| * Some event changed over time, but kept their name, so we define multiple versions here | ||
| */ | ||
| const OfferCreatedEvent_v2_0_0 = | ||
| "event OfferCreated(uint256 indexed offerId, uint256 indexed sellerId, (uint256 id, uint256 sellerId, uint256 price, uint256 sellerDeposit, uint256 buyerCancelPenalty, uint256 quantityAvailable, address exchangeToken, string metadataUri, string metadataHash, bool voided) offer, (uint256 validFrom, uint256 validUntil, uint256 voucherRedeemableFrom, uint256 voucherRedeemableUntil) offerDates, (uint256 disputePeriod, uint256 voucherValid, uint256 resolutionPeriod) offerDurations, (uint256 disputeResolverId, uint256 escalationResponsePeriod, uint256 feeAmount, uint256 buyerEscalationDeposit) disputeResolutionTerms, (uint256 protocolFee, uint256 agentFee) offerFees, uint256 indexed agentId, address executedBy)"; | ||
| const OfferCreatedEvent_v2_3_0 = | ||
| "event OfferCreated(uint256 indexed offerId, uint256 indexed sellerId, (uint256 id, uint256 sellerId, uint256 price, uint256 sellerDeposit, uint256 buyerCancelPenalty, uint256 quantityAvailable, address exchangeToken, string metadataUri, string metadataHash, bool voided, uint256 collectionIndex) offer, (uint256 validFrom, uint256 validUntil, uint256 voucherRedeemableFrom, uint256 voucherRedeemableUntil) offerDates, (uint256 disputePeriod, uint256 voucherValid, uint256 resolutionPeriod) offerDurations, (uint256 disputeResolverId, uint256 escalationResponsePeriod, uint256 feeAmount, uint256 buyerEscalationDeposit) disputeResolutionTerms, (uint256 protocolFee, uint256 agentFee) offerFees, uint256 indexed agentId, address executedBy)"; | ||
| const OfferCreatedEvent_v2_4_0 = | ||
| "event OfferCreated(uint256 indexed offerId, uint256 indexed sellerId, (uint256 id, uint256 sellerId, uint256 price, uint256 sellerDeposit, uint256 buyerCancelPenalty, uint256 quantityAvailable, address exchangeToken, uint8 priceType, string metadataUri, string metadataHash, bool voided, uint256 collectionIndex, (address[] recipients, uint256[] bps)[] royaltyInfo) offer, (uint256 validFrom, uint256 validUntil, uint256 voucherRedeemableFrom, uint256 voucherRedeemableUntil) offerDates, (uint256 disputePeriod, uint256 voucherValid, uint256 resolutionPeriod) offerDurations, (uint256 disputeResolverId, uint256 escalationResponsePeriod, uint256 feeAmount, uint256 buyerEscalationDeposit) disputeResolutionTerms, (uint256 protocolFee, uint256 agentFee) offerFees, uint256 indexed agentId, address executedBy)"; | ||
| const OfferCreatedEvent_v2_5_0 = | ||
| "event OfferCreated(uint256 indexed offerId, uint256 indexed sellerId, (uint256 id, uint256 sellerId, uint256 price, uint256 sellerDeposit, uint256 buyerCancelPenalty, uint256 quantityAvailable, address exchangeToken, uint8 priceType, uint8 creator, string metadataUri, string metadataHash, bool voided, uint256 collectionIndex, (address[] recipients, uint256[] bps)[] royaltyInfo, uint256 buyerId) offer, (uint256 validFrom, uint256 validUntil, uint256 voucherRedeemableFrom, uint256 voucherRedeemableUntil) offerDates, (uint256 disputePeriod, uint256 voucherValid, uint256 resolutionPeriod) offerDurations, (uint256 disputeResolverId, uint256 escalationResponsePeriod, uint256 feeAmount, uint256 buyerEscalationDeposit, address mutualizerAddress) disputeResolutionTerms, (uint256 protocolFee, uint256 agentFee) offerFees, uint256 indexed agentId, address executedBy)"; | ||
| const OfferVoidedEvent = | ||
| "event OfferVoided(uint256 indexed offerId, uint256 indexed creatorId, address indexed executedBy)"; | ||
|
|
||
| const FundsDepositedEvent = | ||
| "event FundsDeposited(uint256 indexed entityId, address indexed executedBy, address indexed tokenAddress, uint256 amount)"; | ||
| const FundsEncumberedEvent = | ||
| "event FundsEncumbered(uint256 indexed entityId, address indexed exchangeToken, uint256 amount, address indexed executedBy)"; | ||
|
|
||
| const BuyerCommittedEvent_v2_0_0 = | ||
| "event BuyerCommitted(uint256 indexed offerId, uint256 indexed buyerId, uint256 indexed exchangeId, (uint256 id, uint256 offerId, uint256 buyerId, uint256 finalizedDate, uint8 state) exchange, (uint256 committedDate, uint256 validUntilDate, uint256 redeemedDate, bool expired) voucher, address executedBy)"; | ||
| const BuyerCommittedEvent_v2_5_0 = | ||
| "event BuyerCommitted(uint256 indexed offerId, uint256 indexed buyerId, uint256 indexed exchangeId, (uint256 id, uint256 offerId, uint256 buyerId, uint256 finalizedDate, uint8 state, address mutualizerAddress) exchange, (uint256 committedDate, uint256 validUntilDate, uint256 redeemedDate, bool expired) voucher, address executedBy)"; | ||
|
|
||
| module.exports = { | ||
| protocolDiamondAddress, | ||
| protocolDeploymentBlock, | ||
| fundsDepositedTopic, | ||
| fundsEncumberedTopic, | ||
| offerCreatedTopic_v2_0_0, | ||
| offerCreatedTopic_v2_3_0, | ||
| offerCreatedTopic_v2_4_0, | ||
| offerCreatedTopic_v2_5_0, | ||
| offerVoidedTopic, | ||
| buyerCommittedTopic_v2_0_0, | ||
| buyerCommittedTopic_v2_5_0, | ||
| OfferCreatedEvent_v2_0_0, | ||
| OfferCreatedEvent_v2_3_0, | ||
| OfferCreatedEvent_v2_4_0, | ||
| OfferCreatedEvent_v2_5_0, | ||
| OfferVoidedEvent, | ||
| FundsDepositedEvent, | ||
| FundsEncumberedEvent, | ||
| BuyerCommittedEvent_v2_0_0, | ||
| BuyerCommittedEvent_v2_5_0, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,80 @@ | ||
| const { staking } = require("../helper/staking"); | ||
|
|
||
| const { | ||
| getVoidedOffers, | ||
| getOffers, | ||
| getCommits, | ||
| getDepositedAndEncumberedBalances, | ||
| } = require("./utils"); | ||
|
|
||
| async function tvl(api) { | ||
| // Currently Deposited and Encumbered funds. | ||
| // Includes all buyer commitments, seller deposits and dispute resolution fees for active exchanges for both Fixed Price and Price Discovery offers. | ||
| // It also includes all additional commits as result of Sequential Commitments | ||
| await getDepositedAndEncumberedBalances(api); | ||
|
|
||
| // Listed offers with uncommitted quantity | ||
| const voidedOffers = await getVoidedOffers(api); | ||
| const activeOffers = await getOffers(api, voidedOffers); | ||
|
|
||
| // Ignore Price Discovery offers. Their price is unknown until commitment. Its contribution to TVL is included in `getEncumberedFunds`. | ||
| // Work only with Fixed Price offers from here on. | ||
| const fixedPriceOffers = activeOffers.filter( | ||
| (i) => i.offer?.priceType !== 1n | ||
| ); // priceType 1 = Price Discovery | ||
|
|
||
| // Get the existing commits to avoid double counting | ||
| const commitsByOffer = await getCommits(api); | ||
|
|
||
| const tokenBalances = {}; | ||
| for (const offer of fixedPriceOffers) { | ||
| const offerId = BigInt(offer.offerId); | ||
|
|
||
| // Calculate the remaining uncommitted quantity | ||
| const uncommittedQuantity = | ||
| BigInt(offer.offer.quantityAvailable) - | ||
| BigInt(commitsByOffer[offerId]?.length || 0); | ||
|
|
||
| if (uncommittedQuantity > 0n) { | ||
| // continue; // Skip offers with uncommitted quantity | ||
| const exchangeToken = offer.offer.exchangeToken; | ||
| const price = BigInt(offer.offer.price); | ||
|
|
||
| // Use only a single price (ignore quantity) to avoid TVL inflation | ||
| // When buyers are committing, the TVL will increase accordingly | ||
| tokenBalances[exchangeToken] = | ||
| (tokenBalances[exchangeToken] || 0n) + price; | ||
| } | ||
| } | ||
|
|
||
| api.addTokens(Object.keys(tokenBalances), Object.values(tokenBalances)); | ||
| } | ||
|
|
||
| module.exports = { | ||
| ethereum: { | ||
| tvl: () => ({}), | ||
| tvl, | ||
| staking: staking( | ||
| [ | ||
| "0x6244bc0d4b661526c0c62c3610571cd1ac9df2dd", | ||
| "0xbacc083795846a67b0782327a96622447ddafe6c", | ||
| "0x081a52f02e51978ad419dd7894d7ae3555f8bc26", | ||
| "0x3ed0c99c8e8eb94438837cc8a08ca3bb187424cf", | ||
| "0x3810d9d6685812af6ef4257de0542ecdba9bfd95" | ||
| "0x3810d9d6685812af6ef4257de0542ecdba9bfd95", | ||
| "0xdDFa9c32CC6Aa3a53cC681fb6f4A65b255324BD3", | ||
| ], | ||
| "0xC477D038d5420C6A9e0b031712f61c5120090de9" | ||
| ), | ||
| }, | ||
| polygon: { | ||
| tvl, | ||
| }, | ||
| base: { | ||
| tvl, | ||
| }, | ||
| optimism: { | ||
| tvl, | ||
| }, | ||
| arbitrum: { | ||
| tvl, | ||
| }, | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| const ethers = require("ethers"); | ||
| const { getLogs } = require("../helper/cache/getLogs"); | ||
| const { sumTokens2 } = require("../helper/unwrapLPs"); | ||
|
|
||
| const { | ||
| protocolDiamondAddress, | ||
| protocolDeploymentBlock, | ||
| fundsDepositedTopic, | ||
| fundsEncumberedTopic, | ||
| offerCreatedTopic_v2_0_0, | ||
| offerCreatedTopic_v2_3_0, | ||
| offerCreatedTopic_v2_4_0, | ||
| offerCreatedTopic_v2_5_0, | ||
| offerVoidedTopic, | ||
| buyerCommittedTopic_v2_0_0, | ||
| buyerCommittedTopic_v2_5_0, | ||
| OfferCreatedEvent_v2_0_0, | ||
| OfferCreatedEvent_v2_3_0, | ||
| OfferCreatedEvent_v2_4_0, | ||
| OfferCreatedEvent_v2_5_0, | ||
| OfferVoidedEvent, | ||
| FundsDepositedEvent, | ||
| FundsEncumberedEvent, | ||
| BuyerCommittedEvent_v2_0_0, | ||
| BuyerCommittedEvent_v2_5_0, | ||
| } = require("./constants"); | ||
|
|
||
| async function getVoidedOffers(api) { | ||
| const logs = await getLogs({ | ||
| api, | ||
| target: protocolDiamondAddress, | ||
| topics: [offerVoidedTopic], | ||
| fromBlock: protocolDeploymentBlock[api.chain], | ||
| eventAbi: OfferVoidedEvent, | ||
| onlyArgs: true, | ||
| extraKey: "offerVoided", | ||
| }); | ||
|
|
||
| return logs.map((i) => BigInt(i.offerId)); | ||
| } | ||
|
|
||
| async function getOffers(api, voidedOffers = []) { | ||
| const response = await getLogs({ | ||
| api, | ||
| target: protocolDiamondAddress, | ||
| topics: [ | ||
| [ | ||
| offerCreatedTopic_v2_0_0, | ||
| offerCreatedTopic_v2_3_0, | ||
| offerCreatedTopic_v2_4_0, | ||
| offerCreatedTopic_v2_5_0, | ||
| ], | ||
| ], | ||
| fromBlock: protocolDeploymentBlock[api.chain], | ||
| extraKey: "offerCreated", | ||
| }); | ||
|
|
||
| // Combine all versions of the OfferCreated event | ||
| const iface = new ethers.Interface([ | ||
| OfferCreatedEvent_v2_0_0, | ||
| OfferCreatedEvent_v2_3_0, | ||
| OfferCreatedEvent_v2_4_0, | ||
| OfferCreatedEvent_v2_5_0, | ||
| ]); | ||
|
|
||
| const parsedLogs = response.map((log) => { | ||
| return iface.parseLog(log)?.args; | ||
| }); | ||
|
|
||
| const blockTimestamp = BigInt(api.timestamp); | ||
|
|
||
| return parsedLogs.filter( | ||
| (i) => | ||
| !voidedOffers.includes(BigInt(i.offerId)) && | ||
| BigInt(i?.offerDates?.validUntil) >= blockTimestamp && | ||
| BigInt(i?.offerDates?.validFrom) < blockTimestamp | ||
| ); | ||
| } | ||
|
|
||
| async function getCommits(api) { | ||
| const response = await getLogs({ | ||
| api, | ||
| target: protocolDiamondAddress, | ||
| topics: [[buyerCommittedTopic_v2_0_0, buyerCommittedTopic_v2_5_0]], | ||
levalleux-ludo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| fromBlock: protocolDeploymentBlock[api.chain], | ||
| extraKey: "buyerCommitted", | ||
| }); | ||
|
|
||
| // Combine all versions of the BuyerCommitted event | ||
| const iface = new ethers.Interface([ | ||
| BuyerCommittedEvent_v2_0_0, | ||
| BuyerCommittedEvent_v2_5_0, | ||
| ]); | ||
|
|
||
| const parsedLogs = response.map((log) => { | ||
| return iface.parseLog(log)?.args; | ||
| }); | ||
|
|
||
| const commitsByOffer = {}; | ||
|
|
||
| for (const commit of parsedLogs) { | ||
| const offerId = BigInt(commit.offerId); | ||
| if (!commitsByOffer[offerId]) { | ||
| commitsByOffer[offerId] = [commit.exchangeId]; | ||
| } else { | ||
| commitsByOffer[offerId].push(commit.exchangeId); | ||
| } | ||
| } | ||
|
|
||
| return commitsByOffer; | ||
| } | ||
|
|
||
| async function getDepositedAndEncumberedBalances(api) { | ||
| const response = await getLogs({ | ||
| api, | ||
| target: protocolDiamondAddress, | ||
| topics: [[fundsDepositedTopic, fundsEncumberedTopic]], | ||
| fromBlock: protocolDeploymentBlock[api.chain], | ||
| extraKey: "incomingFunds", | ||
| }); | ||
|
|
||
| // Combine all versions of the OfferCreated event | ||
| const iface = new ethers.Interface([ | ||
| FundsDepositedEvent, | ||
| FundsEncumberedEvent, | ||
| ]); | ||
|
|
||
| const parsedLogs = response.map((log) => { | ||
| return iface.parseLog(log)?.args; | ||
| }); | ||
|
|
||
| // Get the token list | ||
| const uniqueTokens = new Set( | ||
| parsedLogs.map((i) => i.tokenAddress || i.exchangeToken) | ||
| ); | ||
|
|
||
| return sumTokens2({ | ||
| api, | ||
| tokens: Array.from(uniqueTokens), | ||
| owner: protocolDiamondAddress, | ||
| }); | ||
| } | ||
|
|
||
| module.exports = { | ||
| getVoidedOffers, | ||
| getOffers, | ||
| getCommits, | ||
| getDepositedAndEncumberedBalances, | ||
| }; | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.