1- const ADDRESSES = require ( './helper/coreAssets.json' )
2- const { cachedGraphQuery } = require ( './helper/cache' )
31const { getLogs } = require ( './helper/cache/getLogs' )
42
5- const endPoint = 'https://d2c7awq32ho327.cloudfront.net/graphql'
63const SMART_CREDIT = '0x72e9D9038cE484EE986FEa183f8d8Df93f9aDA13' . toLowerCase ( )
74const factory = '0x31ba589072278D82207212702De9A1C2B9D42c28'
85const fromBlock = 14575305
96const factoryAbi = {
107 "FixedIncomeFundCreationComplete" : "event FixedIncomeFundCreationComplete(address indexed fixedIncomeFund, bytes32 indexed salt)" ,
118 "LoanContractCreated" : "event LoanContractCreated(address indexed creditLine, address indexed borrower, bytes32 salt, bytes32 _type)" ,
12- "createCreditLine" : "function createCreditLine(bytes32 _type, bytes32 _salt) returns (address _creditLine)" ,
13- "createNFTLoan" : "function createNFTLoan(bytes32 _type, bytes32 _salt, tuple(address assetAddress, uint256 loanAmount, uint256 loanTerm, uint256 interestRate, address collateralAddress, uint256 collateralId) _loanRequest) returns (address _loanContract)" ,
14- "createFixedIncomeFund" : "function createFixedIncomeFund(bytes32 _type, bytes32 _salt, uint256[4] _ratios) returns (address _fixedIncomeFund)" ,
15- "investFixedIncomeFundToCompound" : "function investFixedIncomeFundToCompound(address[] _fixedIncomeFunds)"
16- }
17-
18- const loanAbi = {
19- "getLoanData" : "function getLoanData(bytes32 _loanId) view returns (bytes32 loanId, uint256 currentCollateralAmount, uint256 loanEnded, uint256 outstandingAmount)" ,
209}
2110
2211const fixedIncomeAbi = {
23- "getCurrencyAddress" : "address:getCurrencyAddress" ,
2412 "getCompoundAddress" : "address:getCompoundAddress" ,
25- "fixedIncomeFundBalance" : "uint256:fixedIncomeFundBalance"
13+ "fixedIncomeFundBalance" : "uint256:fixedIncomeFundBalance" ,
14+ "getFixedIncomeFundDetails" : "function getFixedIncomeFundDetails() external view returns(address owner, address currency, uint256 balance, uint256 invested, uint256[4] memory buckets)"
2615}
2716
17+ // Supported tokens (hardcoded for efficiency - verified from protocol docs)
18+ const collateralTokens = [
19+ "0x0000000000000000000000000000000000000000" , // ETH (null address)
20+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" , // USDC
21+ "0xdAC17F958D2ee523a2206206994597C13D831ec7" , // USDT
22+ "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84" , // stETH
23+ "0x6b175474e89094c44da98b954eedeac495271d0f" , // DAI
24+ "0x221657776846890989a759ba2973e427dff5c9bb" , // REP
25+ "0x514910771af9ca656af840dff83e8264ecf986ca" , // LINK
26+ "0x0d8775f648430679a709e98d2b0cb6250d2887ef" // BAT
27+ ]
28+ const underlyingTokens = [
29+ "0x0000000000000000000000000000000000000000" , // ETH
30+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" , // USDC
31+ "0xdAC17F958D2ee523a2206206994597C13D831ec7" , // USDT
32+ "0x6b175474e89094c44da98b954eedeac495271d0f" // DAI
33+ ]
2834
29- const transformNull = i => i . toLowerCase ( ) === ADDRESSES . GAS_TOKEN_2 . toLowerCase ( ) ? ADDRESSES . null : i
30-
31- async function staking ( api ) {
32- let { loanRequests } = await cachedGraphQuery ( 'smart-credit' , endPoint , `{
33- loanRequests {
34- id,
35- contractAddress,
36- loanStatus,
37- liquidationStatus,
38- underlying { ethAddress },
39- collateral { ethAddress }
40- }
41- }` )
42- loanRequests = loanRequests . filter ( i => i )
43- const ownerTokens = loanRequests . map ( i => [ [ i . underlying . ethAddress , i . collateral . ethAddress ] . map ( transformNull ) , i . contractAddress ] )
44- return api . sumTokens ( { ownerTokens, whitelistedTokens : [ SMART_CREDIT ] } )
45- }
46-
47- module . exports = {
48- timetravel : false ,
49- ethereum : {
50- tvl,
51- staking,
52- borrowed,
53- }
54- }
5535
36+ /**
37+ * TVL: Sum of assets in Fixed Income Funds + collateral in Loan contracts
38+ * - Fixed Income: underlying tokens deposited by lenders
39+ * - Loans: collateral tokens deposited by borrowers
40+ */
5641async function tvl ( api ) {
5742 await fixedIncomeTvl ( api )
58- await loanTvl ( api )
43+ await collateralTvl ( api )
5944 return api . getBalances ( )
6045}
6146
62-
47+ /**
48+ * Fixed Income TVL: Underlying tokens deposited in Fixed Income Funds by lenders
49+ * Excludes SMARTCREDIT protocol token to avoid double-counting with staking
50+ * @param {Object } api - DefiLlama SDK api instance
51+ */
6352async function fixedIncomeTvl ( api ) {
6453 const logs = await getLogs ( {
6554 api,
@@ -70,44 +59,81 @@ async function fixedIncomeTvl(api) {
7059 extraKey : 'fixedIncomeFund' ,
7160 } )
7261 const pools = logs . map ( l => l . fixedIncomeFund )
73- const tokens = ( await api . multiCall ( { abi : fixedIncomeAbi . getCurrencyAddress , calls : pools } ) ) . map ( transformNull )
74-
75- await api . sumTokens ( { tokensAndOwners2 : [ tokens , pools ] , blacklistedTokens : [ SMART_CREDIT ] } )
62+ await api . sumTokens ( { tokens : underlyingTokens , owners : pools , blacklistedTokens : [ SMART_CREDIT ] } )
7663}
7764
78- async function loanTvl ( api ) {
79- let { loanRequests } = await cachedGraphQuery ( 'smart-credit' , endPoint , `{
80- loanRequests {
81- id,
82- contractAddress,
83- loanStatus,
84- liquidationStatus,
85- underlying { ethAddress },
86- collateral { ethAddress }
87- }
88- }` )
89- loanRequests = loanRequests . filter ( i => i )
90- const ownerTokens = loanRequests . map ( i => [ [ i . underlying . ethAddress , i . collateral . ethAddress ] . map ( transformNull ) , i . contractAddress ] )
91- return api . sumTokens ( { ownerTokens, blacklistedTokens : [ SMART_CREDIT ] } )
65+ /**
66+ * Collateral TVL: Collateral tokens in active loan contracts (creditlines)
67+ * Borrowers deposit collateral which stays locked until loans are repaid/liquidated
68+ * @param {Object } api - DefiLlama SDK api instance
69+ */
70+ async function collateralTvl ( api ) {
71+ const logs = await getLogs ( {
72+ api,
73+ target : factory ,
74+ eventAbi : factoryAbi . LoanContractCreated ,
75+ onlyArgs : true ,
76+ fromBlock,
77+ extraKey : 'creditLine' ,
78+ } )
79+ const pools = logs . map ( l => l . creditLine . toLowerCase ( ) )
80+ await api . sumTokens ( { tokens : collateralTokens , owners : pools } )
9281}
9382
83+
84+
85+ /**
86+ * Borrowed: Total outstanding loan principal across all Fixed Income Funds
87+ * All borrows originate from Fixed Income Funds → invested amount = total borrowed
88+ * Excludes SMARTCREDIT token loans (protocol-internal operations)
89+ * @param {Object } api - DefiLlama SDK api instance
90+ * @returns {Object } Balances object with borrowed amounts by token
91+ */
9492async function borrowed ( api ) {
95- let { loanRequests } = await cachedGraphQuery ( 'smart-credit' , endPoint , ` {
96- loanRequests {
97- id ,
98- contractAddress ,
99- loanStatus ,
100- liquidationStatus ,
101- underlying { ethAddress } ,
102- collateral { ethAddress }
103- }
104- }` )
105- loanRequests = loanRequests . filter ( i => i )
106- const calls = loanRequests . map ( i => ( { target : i . contractAddress , params : [ i . id ] } ) )
107- const loanInfos = await api . multiCall ( { abi : loanAbi . getLoanData , calls } )
108- loanInfos . forEach ( ( i , idx ) => {
109- if ( i . outstandingAmount === '0' ) return
110- api . add ( loanRequests [ idx ] . underlying . ethAddress , i . outstandingAmount )
93+ const logs = await getLogs ( {
94+ api ,
95+ target : factory ,
96+ eventAbi : factoryAbi . FixedIncomeFundCreationComplete ,
97+ onlyArgs : true ,
98+ fromBlock ,
99+ extraKey : 'fixedIncomeFund' ,
100+ } )
101+
102+ const pools = logs . map ( l => l . fixedIncomeFund )
103+ const poolInfos = await api . multiCall ( { abi : fixedIncomeAbi . getFixedIncomeFundDetails , calls : pools } )
104+
105+ poolInfos . forEach ( ( i , idx ) => {
106+ if ( i . currency . toLowerCase ( ) === SMART_CREDIT ) return
107+ const token = i . currency === '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' ? '0x0000000000000000000000000000000000000000' : i . currency ;
108+ api . add ( token , i . invested )
111109 } )
112110 return api . getBalances ( )
111+ }
112+
113+
114+ /**
115+ * Staking: SMARTCREDIT protocol tokens staked in Fixed Income Funds
116+ * @param {Object } api - DefiLlama SDK api instance
117+ */
118+ async function staking ( api ) {
119+ const logs = await getLogs ( {
120+ api,
121+ target : factory ,
122+ eventAbi : factoryAbi . FixedIncomeFundCreationComplete ,
123+ onlyArgs : true ,
124+ fromBlock,
125+ extraKey : 'fixedIncomeFund' ,
126+ } )
127+ const pools = logs . map ( l => l . fixedIncomeFund )
128+ return api . sumTokens ( { owners : pools , tokens : [ SMART_CREDIT ] } )
129+ }
130+
131+
132+ module . exports = {
133+ timetravel : false ,
134+ ethereum : {
135+ tvl,
136+ staking,
137+ borrowed,
138+ }
113139}
0 commit comments