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

Commit

Permalink
feat(hector): Updates to add Fantom bonds, BSC bonds, and new tokens (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
0x A.K committed Aug 25, 2022
1 parent 1c1b47b commit 773d56d
Show file tree
Hide file tree
Showing 21 changed files with 7,027 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Inject } from '@nestjs/common';
import { BigNumber } from 'ethers';

import { drillBalance } from '~app-toolkit';
import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { PositionBalanceFetcher } from '~position/position-balance-fetcher.interface';
import { ContractPositionBalance } from '~position/position-balance.interface';
import { isClaimable, isVesting } from '~position/position.utils';
import { Network } from '~types/network.interface';

import { HectorNetworkContractFactory } from '../contracts';
import { HECTOR_NETWORK_DEFINITION } from '../hector-network.definition';

const appId = HECTOR_NETWORK_DEFINITION.id;
const groupId = HECTOR_NETWORK_DEFINITION.groups.bscBond.id;
const network = Network.ETHEREUM_MAINNET;

@Register.ContractPositionBalanceFetcher({ appId, groupId, network })
export class BinanceSmartChainHectorNetworkBscBondContractPositionBalanceFetcher
implements PositionBalanceFetcher<ContractPositionBalance>
{
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(HectorNetworkContractFactory) private readonly contractFactory: HectorNetworkContractFactory,
) {}

async getBalances(address: string) {
return this.appToolkit.helpers.contractPositionBalanceHelper.getContractPositionBalances({
network,
appId,
address,
groupId: HECTOR_NETWORK_DEFINITION.groups.bscBond.id,
resolveBalances: async ({ address, contractPosition, multicall }) => {
const contract = this.contractFactory.hectorNetworkBscBondDepository(contractPosition);
const vestingToken = contractPosition.tokens.find(isVesting);
const claimableToken = contractPosition.tokens.find(isClaimable);
if (!vestingToken || !claimableToken) return [];

const count = await multicall.wrap(contract).depositCounts(address);
const depositIds = await Promise.all(
Array(count.toNumber()).map((_, i) => multicall.wrap(contract).ownedDeposits(address, i)),
);
const bondInfos = await Promise.all(depositIds.map(id => multicall.wrap(contract).bondInfo(id)));
const claimablePayouts = await Promise.all(depositIds.map(id => multicall.wrap(contract).pendingPayoutFor(id)));

let totalPayout = BigNumber.from(0);
let totalClaimablePayout = BigNumber.from(0);
bondInfos.forEach(info => (totalPayout = totalPayout.add(info.payout)));
claimablePayouts.forEach(payout => (totalClaimablePayout = totalClaimablePayout.add(payout)));

return [
drillBalance(vestingToken, totalPayout.sub(totalClaimablePayout).toString()),
drillBalance(claimableToken, totalClaimablePayout.toString()),
];
},
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Inject } from '@nestjs/common';
import { BigNumber } from 'ethers';

import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { getImagesFromToken, getLabelFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { MetaType } from '~position/position.interface';
import {
ContractPositionTemplatePositionFetcher,
DisplayPropsStageParams,
GetTokenBalancesPerPositionParams,
TokenStageParams,
} from '~position/template/contract-position.template.position-fetcher';
import { Network } from '~types';

import { HectorNetworkBscBondDepository, HectorNetworkContractFactory } from '../contracts';
import { HECTOR_NETWORK_DEFINITION } from '../hector-network.definition';

const appId = HECTOR_NETWORK_DEFINITION.id;
const groupId = HECTOR_NETWORK_DEFINITION.groups.bscBond.id;
const network = Network.BINANCE_SMART_CHAIN_MAINNET;

@Register.ContractPositionFetcher({ appId, groupId, network })
export class BinanceSmartChainHectorNetworkBscBondContractPositionFetcher extends ContractPositionTemplatePositionFetcher<HectorNetworkBscBondDepository> {
appId = HECTOR_NETWORK_DEFINITION.id;
groupId = HECTOR_NETWORK_DEFINITION.groups.bscBond.id;
network = Network.BINANCE_SMART_CHAIN_MAINNET;
groupLabel = 'Bonds';

constructor(
@Inject(APP_TOOLKIT) protected readonly appToolkit: IAppToolkit,
@Inject(HectorNetworkContractFactory) protected readonly contractFactory: HectorNetworkContractFactory,
) {
super(appToolkit);
}

async getDescriptors() {
return [
{ address: '0xf28390501753275d12f750c759baf7365368499f' },
{ address: '0x23b9bf624f6fa56cad401586f477c32f3a41d852' },
{ address: '0x4f4271cd7a7ebd5ca908effaf35c06a208c8c2b2' },
];
}

getContract(address: string) {
return this.contractFactory.hectorNetworkBscBondDepository({ address, network: this.network });
}

async getTokenDescriptors({ contract }: TokenStageParams<HectorNetworkBscBondDepository>) {
const [principle, claimable] = await Promise.all([contract.principle(), contract.HEC()]);

return [
{ address: claimable, metaType: MetaType.VESTING },
{ address: claimable, metaType: MetaType.CLAIMABLE },
{ address: principle, metaType: MetaType.SUPPLIED },
];
}

async getLabel({ contractPosition }: DisplayPropsStageParams<HectorNetworkBscBondDepository>) {
return `${getLabelFromToken(contractPosition.tokens[2])} Bond`;
}

async getImages({ contractPosition }: DisplayPropsStageParams<HectorNetworkBscBondDepository>) {
return getImagesFromToken(contractPosition.tokens[2]);
}

async getTokenBalancesPerPosition({
address,
contract,
multicall,
}: GetTokenBalancesPerPositionParams<HectorNetworkBscBondDepository>) {
const count = await multicall.wrap(contract).depositCounts(address);
const depositIds = await Promise.all(
Array(count.toNumber()).map((_, i) => multicall.wrap(contract).ownedDeposits(address, i)),
);
const bondInfos = await Promise.all(depositIds.map(id => multicall.wrap(contract).bondInfo(id)));
const claimablePayouts = await Promise.all(depositIds.map(id => multicall.wrap(contract).pendingPayoutFor(id)));

let totalPayout = BigNumber.from(0);
let totalClaimablePayout = BigNumber.from(0);
bondInfos.forEach(info => (totalPayout = totalPayout.add(info.payout)));
claimablePayouts.forEach(payout => (totalClaimablePayout = totalClaimablePayout.add(payout)));

return [totalPayout.sub(totalClaimablePayout).toString(), totalClaimablePayout.toString()];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Inject } from '@nestjs/common';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { ContractType } from '~position/contract.interface';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { HectorNetworkContractFactory } from '../contracts';
import { HECTOR_NETWORK_DEFINITION } from '../hector-network.definition';

const appId = HECTOR_NETWORK_DEFINITION.id;
const groupId = HECTOR_NETWORK_DEFINITION.groups.hec.id;
const network = Network.BINANCE_SMART_CHAIN_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network })
export class BinanceSmartChainHectorNetworkHecTokenFetcher implements PositionFetcher<AppTokenPosition> {
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(HectorNetworkContractFactory) private readonly hectorNetworkContractFactory: HectorNetworkContractFactory,
) {}

async getPositions() {
const tokenAddresses = [
'0x638eebe886b0e9e7c6929e69490064a6c94d204d', // hec
'0x1d6cbdc6b29c6afbae65444a1f65ba9252b8ca83', // tor
];

// Build out the token objects
const multicall = this.appToolkit.getMulticall(network);
const tokens = await Promise.all(
tokenAddresses.map(async tokenAddress => {
const contract = this.hectorNetworkContractFactory.hectorNetworkToken({
address: tokenAddress,
network,
});

// Request the symbol, decimals, ands supply for the jar token
const [symbol, decimals, supplyRaw] = await Promise.all([
multicall.wrap(contract).symbol(),
multicall.wrap(contract).decimals(),
multicall.wrap(contract).totalSupply(),
]);

// Denormalize the supply
const supply = Number(supplyRaw) / 10 ** decimals;

// Create the token object
const token = {
type: ContractType.APP_TOKEN,
appId,
groupId,
address: tokenAddress,
network,
symbol,
decimals,
supply,
};

return token;
}),
);

return tokens as any;
}
}
Loading

0 comments on commit 773d56d

Please sign in to comment.