Smart Contract

FixesTVL

A.d2abb5dbf5e08666.FixesTVL

Deployed

1d ago
Feb 26, 2026, 10:29:26 PM UTC

Dependents

0 imports
1/**
2
3> Author: Fixes Lab <https://github.com/fixes-world/>
4
5# FixesTVL
6
7This is an utility contract for calculating the Total Value Locked (TVL) of the Fixes ecosystem.
8
9*/
10import FungibleToken from 0xf233dcee88fe0abe
11import LiquidStaking from 0xd6f80565193ad727
12import stFlowToken from 0xd6f80565193ad727
13// Fixes Imports
14import FRC20FTShared from 0xd2abb5dbf5e08666
15import FRC20Indexer from 0xd2abb5dbf5e08666
16import FRC20Staking from 0xd2abb5dbf5e08666
17import FRC20AccountsPool from 0xd2abb5dbf5e08666
18import FRC20Marketplace from 0xd2abb5dbf5e08666
19import FRC20Storefront from 0xd2abb5dbf5e08666
20import FGameLottery from 0xd2abb5dbf5e08666
21import FGameLotteryRegistry from 0xd2abb5dbf5e08666
22import FGameLotteryFactory from 0xd2abb5dbf5e08666
23import FixesFungibleTokenInterface from 0xd2abb5dbf5e08666
24import FixesTokenLockDrops from 0xd2abb5dbf5e08666
25import FixesTradablePool from 0xd2abb5dbf5e08666
26
27/// The Fixes Asset Genes contract
28///
29access(all) contract FixesTVL {
30
31    /// Get Flow Value of all staked $flows tokens
32    ///
33    access(all)
34    fun getAllStakedFlowValue(): UFix64 {
35        let acctsPool = FRC20AccountsPool.borrowAccountsPool()
36        let stakingTokens = acctsPool.getAddresses(type: FRC20AccountsPool.ChildAccountType.Staking)
37
38        var totalTVL = 0.0
39        let ticks = stakingTokens.keys
40
41        for tick in ticks {
42            let stakingAddr = stakingTokens[tick]!
43            let stakingPool = FRC20Staking.borrowPool(stakingAddr)
44            if stakingPool == nil {
45                continue
46            }
47
48            let indexer = FRC20Indexer.getIndexer()
49            // calculate floor price
50            let benchmarkPrice = indexer.getBenchmarkValue(tick: tick)
51            var floorPrice = benchmarkPrice
52
53            if let marketAddr = acctsPool.getFRC20MarketAddress(tick: tick) {
54                if let market = FRC20Marketplace.borrowMarket(marketAddr) {
55                    let buyPriceRanks = market.getPriceRanks(type: FRC20Storefront.ListingType.FixedPriceBuyNow)
56                    if buyPriceRanks.length > 0 {
57                        var i = 0
58                        let floorPriceRank = buyPriceRanks[i]
59                        let listIds = market.getListedIds(type: FRC20Storefront.ListingType.FixedPriceBuyNow, rank: floorPriceRank)
60                        if listIds.length > 0 {
61                            if let listing = market.getListedItem(
62                                type: FRC20Storefront.ListingType.FixedPriceBuyNow,
63                                rank: floorPriceRank,
64                                id: listIds[0]
65                            ) {
66                                if let details = listing.getDetails() {
67                                    floorPrice = details.pricePerToken()
68                                }
69                            }
70                        }
71                    }
72                }
73            } // end if
74
75            var details = stakingPool!.getDetails()
76            let validStaked = details.totalStaked - details.totalUnstakingLocked
77
78            totalTVL = totalTVL + (validStaked * (floorPrice - benchmarkPrice))
79        }
80        return totalTVL
81    }
82
83    /// Get Flow Value of all treasury pool balances
84    ///
85    access(all)
86    fun getAllTreasuryFlowValue(): UFix64 {
87        let indexer = FRC20Indexer.getIndexer()
88        let tokens = indexer.getTokens()
89        var totalBalance = 0.0
90        // all treasury pool balance
91        for tick in tokens {
92            let balance = indexer.getPoolBalance(tick: tick)
93            totalBalance = totalBalance + balance
94        }
95
96        // FLOW lottery jackpot balance
97        let registry = FGameLotteryRegistry.borrowRegistry()
98        let flowLotteryPoolName = FGameLotteryFactory.getFIXESMintingLotteryPoolName()
99        if let poolAddr = registry.getLotteryPoolAddress(flowLotteryPoolName) {
100            if let poolRef = FGameLottery.borrowLotteryPool(poolAddr) {
101                let jackpotBalance = poolRef.getJackpotPoolBalance()
102                totalBalance = totalBalance + jackpotBalance
103            }
104        }
105
106        // Unclaimed FLOW Reward in the staking reward pool
107        let acctsPool = FRC20AccountsPool.borrowAccountsPool()
108        let platformStakingTick = FRC20FTShared.getPlatformStakingTickerName()
109        if let stakingPoolAddr = acctsPool.getFRC20StakingAddress(tick: platformStakingTick) {
110            if let stakingPool = FRC20Staking.borrowPool(stakingPoolAddr) {
111                if let detail = stakingPool.getRewardDetails("") {
112                    totalBalance = totalBalance + detail.totalReward
113                }
114            }
115        }
116
117        return totalBalance
118    }
119
120    /// Get Flow Value of all locked Fixes coins
121    ///
122    access(all)
123    fun getAllLockedCoinFlowValue(): UFix64 {
124        // singleton resource and constants
125        let acctsPool = FRC20AccountsPool.borrowAccountsPool()
126        let frc20Indexer = FRC20Indexer.getIndexer()
127        let stFlowTokenKey = "@".concat(Type<@stFlowToken.Vault>().identifier)
128
129        // dictionary of addresses
130        let addrsDict = acctsPool.getAddresses(type: FRC20AccountsPool.ChildAccountType.FungibleToken)
131        // dictionary of tickers and total locked token balances
132        let tickerTotal: {String: UFix64} = {}
133        // This is the soft burned LP value which is fully locked in the BlackHole Vault
134        var flowLockedInBondingCurve = 0.0
135        var flowValueLockedInLotteryPool = 0.0
136        addrsDict.forEachKey(fun (key: String): Bool {
137            if let addr = addrsDict[key] {
138                // sum up all locked token balances in LockDrops Pool
139                if let dropsPool = FixesTokenLockDrops.borrowDropsPool(addr) {
140                    let lockedTokenSymbol = dropsPool.getLockingTokenTicker()
141                    tickerTotal[lockedTokenSymbol] = (tickerTotal[lockedTokenSymbol] ?? 0.0) + dropsPool.getTotalLockedTokenBalance()
142                }
143                // sum up all locked flow in Bonding Curve
144                if let tradablePool = FixesTradablePool.borrowTradablePool(addr) {
145                    flowLockedInBondingCurve = flowLockedInBondingCurve + tradablePool.getFlowBalanceInPool()
146
147                    // sum up all locked flow in Lottery Pool
148                    if let lotteryPool = FGameLottery.borrowLotteryPool(addr) {
149                        let lotteryPoolBalance = lotteryPool.getPoolTotalBalance()
150                        let flowValue = tradablePool.getEstimatedSellingValueByAmount(lotteryPoolBalance)
151                        flowValueLockedInLotteryPool = flowValueLockedInLotteryPool + flowValue
152                    }
153                }
154            }
155            return true
156        })
157        // sum up all locked token balances in LockDrops Pool
158        var totalLockingTokenTVL = 0.0
159        tickerTotal.forEachKey(fun (key: String): Bool {
160            let lockedAmount = tickerTotal[key]!
161            if key == "" {
162                // this is locked FLOW
163                totalLockingTokenTVL = totalLockingTokenTVL + lockedAmount
164            } else if key == "fixes" {
165                // this is locked FIXES
166                let price = frc20Indexer.getBenchmarkValue(tick: "fixes")
167                totalLockingTokenTVL = totalLockingTokenTVL + lockedAmount * price
168            } else if key == stFlowTokenKey {
169                // this is locked stFlow
170                totalLockingTokenTVL = totalLockingTokenTVL + LiquidStaking.calcFlowFromStFlow(stFlowAmount: lockedAmount)
171            }
172            return true
173        })
174        return totalLockingTokenTVL + flowLockedInBondingCurve + flowValueLockedInLotteryPool
175    }
176}
177