Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
feat(nereus): Add Nereus Finance (#1029)
Browse files Browse the repository at this point in the history
Co-authored-by: MaisonT <ak@nereus.finance>
  • Loading branch information
volt62 and MaisonT committed Aug 3, 2022
1 parent dca4cd9 commit bd42d0b
Show file tree
Hide file tree
Showing 25 changed files with 5,762 additions and 0 deletions.
@@ -0,0 +1,87 @@
import { Inject } from '@nestjs/common';

import { Register } from '~app-toolkit/decorators';
import { presentBalanceFetcherResponse } from '~app-toolkit/helpers/presentation/balance-fetcher-response.present';
import { BalanceFetcher } from '~balance/balance-fetcher.interface';
import { Network } from '~types/network.interface';

import { NereusFinanceClaimableBalanceHelper } from '../helpers/nereus-finance.claimable.balance-helper';
import { NereusFinanceHealthFactorMetaHelper } from '../helpers/nereus-finance.health-factor-meta-helper';
import { NereusFinanceLendingBalanceHelper } from '../helpers/nereus-finance.lending.balance-helper';
import { NEREUS_FINANCE_DEFINITION } from '../nereus-finance.definition';

const network = Network.AVALANCHE_MAINNET;

@Register.BalanceFetcher(NEREUS_FINANCE_DEFINITION.id, network)
export class AvalancheNereusFinanceBalanceFetcher implements BalanceFetcher {
constructor(
@Inject(NereusFinanceLendingBalanceHelper)
private readonly nereusFinanceLendingBalanceHelper: NereusFinanceLendingBalanceHelper,
@Inject(NereusFinanceClaimableBalanceHelper)
private readonly nereusFinanceClaimableBalanceHelper: NereusFinanceClaimableBalanceHelper,
@Inject(NereusFinanceHealthFactorMetaHelper)
private readonly healthFactorHelper: NereusFinanceHealthFactorMetaHelper,
) {}

private async getLendingBalances(address: string) {
return Promise.all([
this.nereusFinanceLendingBalanceHelper.getLendingContractPositionBalances({
address,
appId: NEREUS_FINANCE_DEFINITION.id,
groupId: NEREUS_FINANCE_DEFINITION.groups.supply.id,
network,
}),
this.nereusFinanceLendingBalanceHelper.getLendingContractPositionBalances({
address,
appId: NEREUS_FINANCE_DEFINITION.id,
groupId: NEREUS_FINANCE_DEFINITION.groups.stableDebt.id,
network,
isDebt: true,
}),
this.nereusFinanceLendingBalanceHelper.getLendingContractPositionBalances({
address,
appId: NEREUS_FINANCE_DEFINITION.id,
groupId: NEREUS_FINANCE_DEFINITION.groups.variableDebt.id,
network,
isDebt: true,
}),
]).then(v => v.flat());
}

private async getClaimableBalances(address: string) {
return this.nereusFinanceClaimableBalanceHelper.getClaimableBalances({
address,
appId: NEREUS_FINANCE_DEFINITION.id,
groupId: NEREUS_FINANCE_DEFINITION.groups.claimable.id,
network,
});
}

private async getHealthFactorMeta(address: string) {
return this.healthFactorHelper.getHealthFactor({
address,
network,
lendingPoolAddress: '0xB9257597EDdfA0eCaff04FF216939FBc31AAC026',
});
}

async getBalances(address: string) {
const [lendingBalances, claimable, healthFactorMeta] = await Promise.all([
this.getLendingBalances(address),
this.getClaimableBalances(address),
this.getHealthFactorMeta(address),
]);

return presentBalanceFetcherResponse([
{
label: 'Lending',
assets: lendingBalances,
meta: lendingBalances.find(v => v.balanceUSD < 0) ? [healthFactorMeta] : [],
},
{
label: 'Reward',
assets: claimable,
},
]);
}
}
@@ -0,0 +1,32 @@
import { Inject } from '@nestjs/common';

import { Register } from '~app-toolkit/decorators';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { ContractPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { NereusFinanceClaimableContractPositionHelper } from '../helpers/nereus-finance.claimable.contract-position-helper';
import { NEREUS_FINANCE_DEFINITION } from '../nereus-finance.definition';

const appId = NEREUS_FINANCE_DEFINITION.id;
const groupId = NEREUS_FINANCE_DEFINITION.groups.claimable.id;
const network = Network.AVALANCHE_MAINNET;

@Register.ContractPositionFetcher({ appId, groupId, network })
export class AvalancheNereusFinanceClaimableContractPositionFetcher implements PositionFetcher<ContractPosition> {
constructor(
@Inject(NereusFinanceClaimableContractPositionHelper)
private readonly nereusFinanceClaimableContractPositionHelper: NereusFinanceClaimableContractPositionHelper,
) {}

async getPositions() {
return this.nereusFinanceClaimableContractPositionHelper.getTokens({
appId,
groupId,
network,
incentivesControllerAddress: '0xa57a8C5dd29bd9CC605027E62935db2cB5485378',
protocolDataProviderAddress: '0xec090929fBc1B285fc9b3c8EBB92fbc62F01D804',
rewardTokenAddress: '0xfcde4a87b8b6fa58326bb462882f1778158b02f1',
});
}
}
@@ -0,0 +1,36 @@
import { Inject } from '@nestjs/common';

import { Register } from '~app-toolkit/decorators';
import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { NereusFinanceLendingTokenHelper } from '../helpers/nereus-finance.lending.token-helper';
import { NEREUS_FINANCE_DEFINITION } from '../nereus-finance.definition';

const appId = NEREUS_FINANCE_DEFINITION.id;
const groupId = NEREUS_FINANCE_DEFINITION.groups.stableDebt.id;
const network = Network.AVALANCHE_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network })
export class AvalancheNereusFinanceStableDebtTokenFetcher implements PositionFetcher<AppTokenPosition> {
constructor(
@Inject(NereusFinanceLendingTokenHelper)
private readonly nereusFinanceLendingTokenHelper: NereusFinanceLendingTokenHelper,
) {}

async getPositions() {
return this.nereusFinanceLendingTokenHelper.getTokens({
appId,
groupId,
network,
isDebt: true,
protocolDataProviderAddress: '0xec090929fBc1B285fc9b3c8EBB92fbc62F01D804',
resolveTokenAddress: ({ reserveTokenAddressesData }) => reserveTokenAddressesData.stableDebtTokenAddress,
resolveLendingRate: ({ reserveData }) => reserveData.stableBorrowRate,
resolveLabel: ({ reserveToken }) => getLabelFromToken(reserveToken),
resolveApyLabel: ({ apy }) => `${(apy * 100).toFixed(3)}% APR (stable)`,
});
}
}
@@ -0,0 +1,35 @@
import { Inject } from '@nestjs/common';

import { Register } from '~app-toolkit/decorators';
import { getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { NereusFinanceLendingTokenHelper } from '../helpers/nereus-finance.lending.token-helper';
import { NEREUS_FINANCE_DEFINITION } from '../nereus-finance.definition';

const appId = NEREUS_FINANCE_DEFINITION.id;
const groupId = NEREUS_FINANCE_DEFINITION.groups.supply.id;
const network = Network.AVALANCHE_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network })
export class AvalancheNereusFinanceSupplyTokenFetcher implements PositionFetcher<AppTokenPosition> {
constructor(
@Inject(NereusFinanceLendingTokenHelper)
private readonly nereusFinanceLendingTokenHelper: NereusFinanceLendingTokenHelper,
) {}

async getPositions() {
return this.nereusFinanceLendingTokenHelper.getTokens({
appId,
groupId,
network,
protocolDataProviderAddress: '0xec090929fBc1B285fc9b3c8EBB92fbc62F01D804',
resolveTokenAddress: ({ reserveTokenAddressesData }) => reserveTokenAddressesData.aTokenAddress,
resolveLendingRate: ({ reserveData }) => reserveData.liquidityRate,
resolveLabel: ({ reserveToken }) => getLabelFromToken(reserveToken),
resolveApyLabel: ({ apy }) => `${(apy * 100).toFixed(3)}% APY`,
});
}
}
@@ -0,0 +1,117 @@
[
{
"inputs": [
{ "internalType": "contract ILendingPoolAddressesProvider", "name": "addressesProvider", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "ADDRESSES_PROVIDER",
"outputs": [{ "internalType": "contract ILendingPoolAddressesProvider", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAllATokens",
"outputs": [
{
"components": [
{ "internalType": "string", "name": "symbol", "type": "string" },
{ "internalType": "address", "name": "tokenAddress", "type": "address" }
],
"internalType": "struct AaveProtocolDataProvider.TokenData[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAllReservesTokens",
"outputs": [
{
"components": [
{ "internalType": "string", "name": "symbol", "type": "string" },
{ "internalType": "address", "name": "tokenAddress", "type": "address" }
],
"internalType": "struct AaveProtocolDataProvider.TokenData[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "asset", "type": "address" }],
"name": "getReserveConfigurationData",
"outputs": [
{ "internalType": "uint256", "name": "decimals", "type": "uint256" },
{ "internalType": "uint256", "name": "ltv", "type": "uint256" },
{ "internalType": "uint256", "name": "liquidationThreshold", "type": "uint256" },
{ "internalType": "uint256", "name": "liquidationBonus", "type": "uint256" },
{ "internalType": "uint256", "name": "reserveFactor", "type": "uint256" },
{ "internalType": "bool", "name": "usageAsCollateralEnabled", "type": "bool" },
{ "internalType": "bool", "name": "borrowingEnabled", "type": "bool" },
{ "internalType": "bool", "name": "stableBorrowRateEnabled", "type": "bool" },
{ "internalType": "bool", "name": "isActive", "type": "bool" },
{ "internalType": "bool", "name": "isFrozen", "type": "bool" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "asset", "type": "address" }],
"name": "getReserveData",
"outputs": [
{ "internalType": "uint256", "name": "availableLiquidity", "type": "uint256" },
{ "internalType": "uint256", "name": "totalStableDebt", "type": "uint256" },
{ "internalType": "uint256", "name": "totalVariableDebt", "type": "uint256" },
{ "internalType": "uint256", "name": "liquidityRate", "type": "uint256" },
{ "internalType": "uint256", "name": "variableBorrowRate", "type": "uint256" },
{ "internalType": "uint256", "name": "stableBorrowRate", "type": "uint256" },
{ "internalType": "uint256", "name": "averageStableBorrowRate", "type": "uint256" },
{ "internalType": "uint256", "name": "liquidityIndex", "type": "uint256" },
{ "internalType": "uint256", "name": "variableBorrowIndex", "type": "uint256" },
{ "internalType": "uint40", "name": "lastUpdateTimestamp", "type": "uint40" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "asset", "type": "address" }],
"name": "getReserveTokensAddresses",
"outputs": [
{ "internalType": "address", "name": "aTokenAddress", "type": "address" },
{ "internalType": "address", "name": "stableDebtTokenAddress", "type": "address" },
{ "internalType": "address", "name": "variableDebtTokenAddress", "type": "address" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "asset", "type": "address" },
{ "internalType": "address", "name": "user", "type": "address" }
],
"name": "getUserReserveData",
"outputs": [
{ "internalType": "uint256", "name": "currentATokenBalance", "type": "uint256" },
{ "internalType": "uint256", "name": "currentStableDebt", "type": "uint256" },
{ "internalType": "uint256", "name": "currentVariableDebt", "type": "uint256" },
{ "internalType": "uint256", "name": "principalStableDebt", "type": "uint256" },
{ "internalType": "uint256", "name": "scaledVariableDebt", "type": "uint256" },
{ "internalType": "uint256", "name": "stableBorrowRate", "type": "uint256" },
{ "internalType": "uint256", "name": "liquidityRate", "type": "uint256" },
{ "internalType": "uint40", "name": "stableRateLastUpdated", "type": "uint40" },
{ "internalType": "bool", "name": "usageAsCollateralEnabled", "type": "bool" }
],
"stateMutability": "view",
"type": "function"
}
]

0 comments on commit bd42d0b

Please sign in to comment.