@@ -3,6 +3,8 @@ const sdk = require('@defillama/sdk');
33const { default : BigNumber } = require ( 'bignumber.js' ) ;
44const { Interface } = require ( 'ethers/lib/utils' ) ;
55
6+ const NULL_ADDRESS = '0x0000000000000000000000000000000000000000' ;
7+
68const EVENTS = {
79 V1 : {
810 CreateVault :
@@ -277,40 +279,170 @@ async function getVaultV2Addresses(chain, blockNumber) {
277279 return addresses ;
278280}
279281
282+ async function getAaveVaultEffectiveApy ( {
283+ aavePool,
284+ apy,
285+ assetAddress,
286+ chain,
287+ poolAddress,
288+ vaultAddress,
289+ } ) {
290+ const aToken = await sdk . api . abi
291+ . call ( {
292+ target : poolAddress ,
293+ abi : 'address:aToken' ,
294+ chain,
295+ } )
296+ . then ( ( r ) => r . output )
297+ . catch ( ( ) => NULL_ADDRESS ) ;
298+ if ( aToken === NULL_ADDRESS ) return apy ;
299+
300+ const [ assetsInThirdPool , idle ] = await Promise . all ( [
301+ sdk . api . abi
302+ . call ( {
303+ target : aToken ,
304+ abi : {
305+ inputs : [ { type : 'address' } ] ,
306+ name : 'balanceOf' ,
307+ outputs : [ { type : 'uint256' } ] ,
308+ } ,
309+ params : [ poolAddress ] ,
310+ chain,
311+ } )
312+ . then ( ( r ) => r . output ) ,
313+ sdk . api . abi
314+ . call ( {
315+ target : assetAddress ,
316+ abi : {
317+ inputs : [ { type : 'address' } ] ,
318+ name : 'balanceOf' ,
319+ outputs : [ { type : 'uint256' } ] ,
320+ } ,
321+ params : [ poolAddress ] ,
322+ chain,
323+ } )
324+ . then ( ( r ) => r . output ) ,
325+ ] ) ;
326+
327+ const idleFund = new BigNumber ( assetsInThirdPool ) . plus ( idle ) ;
328+ if ( idleFund . isZero ( ) ) return apy ;
329+
330+ const passiveRatio = new BigNumber ( assetsInThirdPool ) . div ( idleFund ) ;
331+
332+ const currentLiquidityRate = await sdk . api . abi
333+ . call ( {
334+ target : aavePool ,
335+ abi : {
336+ inputs : [ { type : 'address' } ] ,
337+ name : 'getReserveData' ,
338+ outputs : [
339+ {
340+ components : [
341+ {
342+ components : [ { type : 'uint256' , name : 'data' } ] ,
343+ name : 'configuration' ,
344+ type : 'tuple' ,
345+ } ,
346+ { type : 'uint128' , name : 'liquidityIndex' } ,
347+ { type : 'uint128' , name : 'currentLiquidityRate' } ,
348+ { type : 'uint128' , name : 'variableBorrowIndex' } ,
349+ { type : 'uint128' , name : 'currentVariableBorrowRate' } ,
350+ { type : 'uint128' , name : 'currentStableBorrowRate' } ,
351+ { type : 'uint40' , name : 'lastUpdateTimestamp' } ,
352+ { type : 'uint16' , name : 'id' } ,
353+ { type : 'address' , name : 'aTokenAddress' } ,
354+ { type : 'address' , name : 'stableDebtTokenAddress' } ,
355+ { type : 'address' , name : 'variableDebtTokenAddress' } ,
356+ { type : 'address' , name : 'interestRateStrategyAddress' } ,
357+ { type : 'uint128' , name : 'accruedToTreasury' } ,
358+ { type : 'uint128' , name : 'unbacked' } ,
359+ { type : 'uint128' , name : 'isolationModeTotalDebt' } ,
360+ ] ,
361+ name : 'res' ,
362+ type : 'tuple' ,
363+ } ,
364+ ] ,
365+ } ,
366+ params : [ assetAddress ] ,
367+ chain,
368+ } )
369+ . then ( ( r ) => r . output . currentLiquidityRate ) ;
370+
371+ const passiveApy = new BigNumber ( currentLiquidityRate ) . div (
372+ new BigNumber ( 10 ) . pow ( 27 )
373+ ) ;
374+ return new BigNumber ( apy ) . plus ( passiveApy . times ( passiveRatio ) ) . toNumber ( ) ;
375+ }
376+
377+ async function getVaultEffectiveApy ( {
378+ apy,
379+ assetAddress,
380+ chain,
381+ chainId,
382+ poolAddress,
383+ vaultAddress,
384+ } ) {
385+ const aavePool = await sdk . api . abi
386+ . call ( {
387+ target : poolAddress ,
388+ abi : 'address:aavePool' ,
389+ chain,
390+ } )
391+ . then ( ( r ) => r . output )
392+ . catch ( ( ) => NULL_ADDRESS ) ;
393+ if ( aavePool !== NULL_ADDRESS )
394+ return await getAaveVaultEffectiveApy ( {
395+ apy,
396+ assetAddress,
397+ chain,
398+ poolAddress,
399+ vaultAddress,
400+ aavePool,
401+ } ) ;
402+
403+ return apy ;
404+ }
405+
280406async function getVaultV2 ( { alias, chain, chainId, number, opportunities } ) {
281407 const vaults = [ ] ;
282408
283409 const addresses = await getVaultV2Addresses ( chain , number ) . then ( ( addresses ) =>
284410 addresses . filter ( ( a ) => ! VAULT_BLACKLIST [ chain ] . includes ( a ) )
285411 ) ;
286412 const calls = addresses . map ( ( target ) => ( { target } ) ) ;
287- const [ apys , assets , decimalses , names , totalAssetses ] = await Promise . all ( [
288- sdk . api . abi . multiCall ( {
289- chain,
290- calls,
291- abi : 'uint256:apy' ,
292- } ) ,
293- sdk . api . abi . multiCall ( {
294- chain,
295- calls,
296- abi : 'address:asset' ,
297- } ) ,
298- sdk . api . abi . multiCall ( {
299- chain,
300- calls,
301- abi : 'uint8:decimals' ,
302- } ) ,
303- sdk . api . abi . multiCall ( {
304- chain,
305- calls,
306- abi : 'string:name' ,
307- } ) ,
308- sdk . api . abi . multiCall ( {
309- chain,
310- calls,
311- abi : 'uint256:totalAssets' ,
312- } ) ,
313- ] ) ;
413+ const [ apys , assets , decimalses , names , totalAssetses , pools ] =
414+ await Promise . all ( [
415+ sdk . api . abi . multiCall ( {
416+ chain,
417+ calls,
418+ abi : 'uint256:apy' ,
419+ } ) ,
420+ sdk . api . abi . multiCall ( {
421+ chain,
422+ calls,
423+ abi : 'address:asset' ,
424+ } ) ,
425+ sdk . api . abi . multiCall ( {
426+ chain,
427+ calls,
428+ abi : 'uint8:decimals' ,
429+ } ) ,
430+ sdk . api . abi . multiCall ( {
431+ chain,
432+ calls,
433+ abi : 'string:name' ,
434+ } ) ,
435+ sdk . api . abi . multiCall ( {
436+ chain,
437+ calls,
438+ abi : 'uint256:totalAssets' ,
439+ } ) ,
440+ sdk . api . abi . multiCall ( {
441+ chain,
442+ calls,
443+ abi : 'address:pool' ,
444+ } ) ,
445+ ] ) ;
314446
315447 const [ assetNames , priceMap ] = await Promise . all ( [
316448 sdk . api . abi . multiCall ( {
@@ -328,9 +460,19 @@ async function getVaultV2({ alias, chain, chainId, number, opportunities }) {
328460 const address = addresses [ i ] ;
329461 const assetAddress = assets . output [ i ] . output ;
330462
331- const readableApy = new BigNumber ( apys . output [ i ] . output )
463+ let apy = new BigNumber ( apys . output [ i ] . output )
332464 . div ( new BigNumber ( 10 ) . pow ( 8 ) )
333465 . toNumber ( ) ;
466+ if ( pools . output [ i ] . output !== NULL_ADDRESS ) {
467+ apy = await getVaultEffectiveApy ( {
468+ apy,
469+ assetAddress,
470+ chain,
471+ chainId,
472+ poolAddress : pools . output [ i ] . output ,
473+ vaultAddress : address ,
474+ } ) ;
475+ }
334476 const tvlUsd = new BigNumber ( totalAssetses . output [ i ] . output )
335477 . div ( new BigNumber ( 10 ) . pow ( decimalses . output [ i ] . output ) )
336478 . times ( priceMap . get ( assetAddress ) || 0 )
@@ -347,7 +489,7 @@ async function getVaultV2({ alias, chain, chainId, number, opportunities }) {
347489 project : 'termmax' ,
348490 symbol : assetNames . output [ i ] . output ,
349491 tvlUsd,
350- apyBase : readableApy ,
492+ apyBase : apy ,
351493 url : String ( url ) ,
352494 underlyingTokens : [ assetAddress ] ,
353495 poolMeta : names . output [ i ] . output ,
@@ -385,7 +527,7 @@ async function getVaultsOnChain(chain, chainId, alias) {
385527
386528 const tasks = [ ] ;
387529 {
388- const task1 = async ( ) => {
530+ const taskV1 = async ( ) => {
389531 const vaultsV1 = await getVaultsV1 ( {
390532 alias,
391533 chain,
@@ -395,10 +537,10 @@ async function getVaultsOnChain(chain, chainId, alias) {
395537 } ) ;
396538 for ( const vault of vaultsV1 ) vaultsOnChain . push ( vault ) ;
397539 } ;
398- tasks . push ( task1 ( ) ) ;
540+ tasks . push ( taskV1 ( ) ) ;
399541 }
400542 {
401- const task2 = async ( ) => {
543+ const taskV2 = async ( ) => {
402544 const vaultsV2 = await getVaultV2 ( {
403545 alias,
404546 chain,
@@ -408,7 +550,7 @@ async function getVaultsOnChain(chain, chainId, alias) {
408550 } ) ;
409551 for ( const vault of vaultsV2 ) vaultsOnChain . push ( vault ) ;
410552 } ;
411- tasks . push ( task2 ( ) ) ;
553+ tasks . push ( taskV2 ( ) ) ;
412554 }
413555 await Promise . all ( tasks ) ;
414556
@@ -417,11 +559,16 @@ async function getVaultsOnChain(chain, chainId, alias) {
417559
418560async function apy ( ) {
419561 const vaults = [ ] ;
562+ const tasks = [ ] ;
420563 for ( const key of Object . keys ( VAULTS ) ) {
421- const { alias, chain, chainId } = VAULTS [ key ] ;
422- const vaultsOnChain = await getVaultsOnChain ( chain , chainId , alias ) ;
423- for ( const vault of vaultsOnChain ) vaults . push ( vault ) ;
564+ const task = async ( ) => {
565+ const { alias, chain, chainId } = VAULTS [ key ] ;
566+ const vaultsOnChain = await getVaultsOnChain ( chain , chainId , alias ) ;
567+ for ( const vault of vaultsOnChain ) vaults . push ( vault ) ;
568+ } ;
569+ tasks . push ( task ( ) ) ;
424570 }
571+ await Promise . all ( tasks ) ;
425572 return vaults ;
426573}
427574
0 commit comments