1+ const sdk = require ( '@defillama/sdk' ) ;
2+ const utils = require ( '../utils' ) ;
3+
4+ const API_URL = 'https://yield.accountable.capital/api/loan' ;
5+ const chainIdToName = { 143 : 'monad' } ;
6+ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' ;
7+
8+ const abis = {
9+ asset : 'function asset() view returns (address)' ,
10+ convertToAssets : 'function convertToAssets(uint256 shares) view returns (uint256)' ,
11+ } ;
12+
13+ const basisPointsToPercent = ( value ) => Number ( value ) / 1e4 ;
14+ const formatAmountWithDecimlas = ( value , decimals ) => value / 10 ** decimals ;
15+
16+ const fetchVaultsByLoanIds = async ( loanIds ) => {
17+ const results = await Promise . allSettled (
18+ loanIds . map ( ( id ) => utils . getData ( `${ API_URL } /${ id } ` ) )
19+ ) ;
20+
21+ return results . reduce ( ( acc , res , idx ) => {
22+ if ( res . status !== 'fulfilled' ) return acc ;
23+ const vault = res . value . on_chain_loan . loan . vault ;
24+ if ( vault && vault !== ZERO_ADDRESS )
25+ acc [ loanIds [ idx ] ] = vault . toLowerCase ( ) ;
26+ return acc ;
27+ } , { } ) ;
28+ } ;
29+
30+ const getVaultAddressesFromApi = async ( ) => {
31+ const { items } = await utils . getData ( API_URL ) ;
32+ const vaults = items
33+ . map ( ( item ) => item . on_chain_loan . loan . vault )
34+ . filter ( ( addr ) => addr && addr !== ZERO_ADDRESS )
35+ . map ( ( addr ) => addr . toLowerCase ( ) ) ;
36+ return Array . from ( new Set ( vaults ) ) ;
37+ } ;
38+
39+ const getVaultStats = async ( vaults , chain = 'monad' ) => {
40+ if ( ! vaults . length ) return { } ;
41+
42+ const [ suppliesRes , underlyingsRes ] = await Promise . all ( [
43+ sdk . api . abi . multiCall ( {
44+ chain,
45+ abi : 'erc20:totalSupply' ,
46+ calls : vaults . map ( ( vault ) => ( { target : vault } ) ) ,
47+ permitFailure : true ,
48+ } ) ,
49+ sdk . api . abi . multiCall ( {
50+ chain,
51+ abi : abis . asset ,
52+ calls : vaults . map ( ( vault ) => ( { target : vault } ) ) ,
53+ permitFailure : true ,
54+ } ) ,
55+ ] ) ;
56+
57+ const supplies = suppliesRes . output . map ( ( o ) => o . output ) ;
58+ const underlyings = underlyingsRes . output . map ( ( o ) => o . output ) ;
59+
60+ const [ totalAssetsRes , liquidityRes ] = await Promise . all ( [
61+ sdk . api . abi . multiCall ( {
62+ chain,
63+ abi : abis . convertToAssets ,
64+ calls : vaults . map ( ( vault , i ) => ( {
65+ target : vault ,
66+ params : [ supplies [ i ] ] ,
67+ } ) ) ,
68+ permitFailure : true ,
69+ } ) ,
70+ sdk . api . abi . multiCall ( {
71+ chain,
72+ abi : 'erc20:balanceOf' ,
73+ calls : vaults . map ( ( vault , i ) => ( {
74+ target : underlyings [ i ] ,
75+ params : vault ,
76+ } ) ) ,
77+ permitFailure : true ,
78+ } ) ,
79+ ] ) ;
80+
81+ const totalAssets = totalAssetsRes . output . map ( ( o ) => o . output ) ;
82+ const liquidity = liquidityRes . output . map ( ( o ) => o . output ) ;
83+ console . log ( totalAssets , liquidity ) ;
84+ return vaults . reduce ( ( acc , address , i ) => {
85+ acc [ address ] = {
86+ totalSupplied : supplies [ i ] ,
87+ totalBorrowed : totalAssets [ i ] - liquidity [ i ] ,
88+ tvl : liquidity [ i ] ,
89+ } ;
90+ return acc ;
91+ } , { } ) ;
92+ } ;
93+
94+ const apy = async ( ) => {
95+ const { items } = await utils . getData ( API_URL ) ;
96+ const activeLoans = items . filter ( ( item ) => item . loan_state === 3 ) ;
97+ const loanIds = activeLoans . map ( ( item ) => item . id ) ;
98+
99+ const loanVaultMap = await fetchVaultsByLoanIds ( loanIds ) ;
100+ const vaultAddresses = Object . values ( loanVaultMap ) ;
101+ const vaultStats = await getVaultStats ( vaultAddresses ) ;
102+
103+ return activeLoans . map ( ( item ) => {
104+ const chainName = chainIdToName [ item . chain_id ] || 'unknown' ;
105+ const vaultAddress = loanVaultMap [ item . id ] ;
106+ const stats = vaultAddress ? vaultStats [ vaultAddress ] || { } : { } ;
107+
108+ return {
109+ pool : `${ item . loan_address } -${ chainName } ` . toLowerCase ( ) ,
110+ chain : chainName ,
111+ project : 'accountable' ,
112+ symbol : utils . formatSymbol ( item . asset_symbol ) ,
113+ tvlUsd : formatAmountWithDecimlas ( stats . tvl , 6 ) ,
114+ apyBase : basisPointsToPercent ( item . net_apy ) ,
115+ url : `https://yield.accountable.capital/vaults/${ item . loan_address } ` ,
116+ totalSupplyUsd : formatAmountWithDecimlas ( stats . totalSupplied , 6 ) ,
117+ totalBorrowUsd : formatAmountWithDecimlas ( stats . totalBorrowed , 6 ) ,
118+ } ;
119+ } ) ;
120+ } ;
121+
122+ module . exports = {
123+ timetravel : false ,
124+ apy,
125+ } ;
0 commit comments