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

feat(sturdy): Adds Ethereum version of Sturdy Finance #574

Merged
merged 25 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7876a04
pika-protocol: create app
theonepichael Jun 3, 2022
b88dd8d
wip pika-protocol implementation
theonepichael Jun 3, 2022
4f27706
wip-balance-fetcher
theonepichael Jun 3, 2022
724abe7
updates getFarmBalances
theonepichael Jun 3, 2022
09cf7dd
removes unused variable
theonepichael Jun 3, 2022
74e9418
reverts to untouched state
theonepichael Jun 3, 2022
429ba9a
implements contract-position-fetcher
theonepichael Jun 3, 2022
49ecc0a
implements balance-fetcher
theonepichael Jun 3, 2022
bb2d4b3
Merge branch 'main' into main
theonepichael Jun 3, 2022
5518d88
implements TVL fetcher
theonepichael Jun 3, 2022
b812f9f
Merge branch 'main' of https://github.com/theonepichael/studio
theonepichael Jun 3, 2022
0523de4
fix(getFarmBalances): now deformalizes staked balances to human-readable
theonepichael Jun 4, 2022
51b22ac
resolves merge conflicts
theonepichael Jun 4, 2022
14b7b2c
refactor(sturdy): adds filter to getBalances to ensure only ftm vault…
theonepichael Jun 4, 2022
01ae6bb
fixes linting errors
theonepichael Jun 4, 2022
2694ada
removes unnecessary await
theonepichael Jun 4, 2022
9571359
fixes import/order
theonepichael Jun 4, 2022
a6006e4
Merge branch 'Zapper-fi:main' into main
theonepichael Jun 5, 2022
bf41c0f
feat(sturdy): Adds Ethereum version of Sturdy Finance
theonepichael Jun 5, 2022
f5bc607
Merge branch 'Zapper-fi:main' into main
theonepichael Jun 7, 2022
6b0c10f
defines helpers
theonepichael Jun 7, 2022
97f8254
implements caching to reduce the # of API calls to the /getVaultMonit…
theonepichael Jun 7, 2022
1ddc4a8
fixes linting errors
theonepichael Jun 7, 2022
09e75d1
fixes linting import/order errors
theonepichael Jun 7, 2022
213cdf9
fixes linting import/order errors
theonepichael Jun 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/apps/sturdy/ethereum/sturdy.balance-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Inject } from '@nestjs/common';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { TokenBalanceHelper } from '~app-toolkit';
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 { STURDY_DEFINITION } from '../sturdy.definition';

const network = Network.ETHEREUM_MAINNET;
const appId = STURDY_DEFINITION.id;

@Register.BalanceFetcher(STURDY_DEFINITION.id, network)
export class EthereumSturdyBalanceFetcher implements BalanceFetcher {
constructor(@Inject(TokenBalanceHelper) private readonly tokenBalanceHelper: TokenBalanceHelper) {}

private async getLendingTokenBalances(address: string) {
return this.tokenBalanceHelper.getTokenBalances({
address,
appId,
groupId: STURDY_DEFINITION.groups.lending.id,
network,
});
}

async getBalances(address: string) {
const [lendingTokenBalances] = await Promise.all([this.getLendingTokenBalances(address)]);

return presentBalanceFetcherResponse([
{
label: 'Lending',
assets: lendingTokenBalances,
},
]);
}
}
106 changes: 106 additions & 0 deletions src/apps/sturdy/ethereum/sturdy.lending.token-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Inject } from '@nestjs/common';
import axios from 'axios';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { ZERO_ADDRESS } from '~app-toolkit/constants/address';
import { Register } from '~app-toolkit/decorators';
import {
buildNumberDisplayItem,
buildPercentageDisplayItem,
} from '~app-toolkit/helpers/presentation/display-item.present';
import { getImagesFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { ContractType } from '~position/contract.interface';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { BaseToken } from '~position/token.interface';
import { Network } from '~types/network.interface';

import { SturdyContractFactory } from '../contracts';
import { STURDY_DEFINITION } from '../sturdy.definition';

const appId = STURDY_DEFINITION.id;
const groupId = STURDY_DEFINITION.groups.lending.id;
const network = Network.ETHEREUM_MAINNET;

type VaultMonitoringResponse = {
chain: string;
tokens: string;
decimals: number;
address: string;
supply: number;
price: number;
base: number;
reward: number;
rewards: {
CRV: number;
CVX: number;
};
url: number;
tvl: number;
active: boolean;
}[];

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

async getPositions() {
const multicall = this.appToolkit.getMulticall(network);
const baseTokens = await this.appToolkit.getBaseTokenPrices(network);
const ethToken = baseTokens.find(t => t.address === ZERO_ADDRESS);
if (!ethToken) return [];

const endpoint = 'https://us-central1-stu-dashboard-a0ba2.cloudfunctions.net/getVaultMonitoring?chain=ethereum';
const tokenData = await axios.get<VaultMonitoringResponse>(endpoint).then(v => v.data);
theonepichael marked this conversation as resolved.
Show resolved Hide resolved

const tokens = tokenData.map(async data => {
const symbol = data.tokens;
const underlyingTokens: BaseToken[] = [];

const contract = this.sturdyContractFactory.sturdyToken({ address: data.address, network });
const underlyingTokenAddress = await multicall
.wrap(contract)
.UNDERLYING_ASSET_ADDRESS()
.then(v => v.toLowerCase());
const underlyingToken = baseTokens.find(t => t.address === underlyingTokenAddress);
if (underlyingToken) underlyingTokens.push(underlyingToken);

const token: AppTokenPosition = {
type: ContractType.APP_TOKEN,
appId,
groupId,
address: data.address,
network,
symbol,
decimals: data.decimals,
supply: data.supply,
pricePerShare: 1,
price: underlyingTokens[0].price,
tokens: underlyingTokens,
dataProps: {
apy: data.base,
tvl: data.tvl,
},
displayProps: {
label: symbol,
images: getImagesFromToken(underlyingTokens[0]),
statsItems: [
{
label: 'apy',
theonepichael marked this conversation as resolved.
Show resolved Hide resolved
value: buildPercentageDisplayItem(data.base),
},
{
label: 'Liquidity',
value: buildNumberDisplayItem(data.tvl),
},
],
},
};
return token;
});
return Promise.all(tokens);
}
}
26 changes: 26 additions & 0 deletions src/apps/sturdy/ethereum/sturdy.tvl-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Inject } from '@nestjs/common';
import { sumBy } from 'lodash';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { TvlFetcher } from '~stats/tvl/tvl-fetcher.interface';
import { Network } from '~types/network.interface';

import { STURDY_DEFINITION } from '../sturdy.definition';

const appId = STURDY_DEFINITION.id;
const network = Network.ETHEREUM_MAINNET;

@Register.TvlFetcher({ appId, network })
export class EthereumSturdyTvlFetcher implements TvlFetcher {
constructor(@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit) {}

async getTvl() {
const lendingTokens = await this.appToolkit.getAppTokenPositions({
appId,
groupIds: [STURDY_DEFINITION.groups.lending.id],
network,
});
return sumBy(lendingTokens, v => v.supply * v.price);
}
}
4 changes: 1 addition & 3 deletions src/apps/sturdy/fantom/sturdy.lending.token-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ export class FantomSturdyLendingTokenFetcher implements PositionFetcher<AppToken
if (!ethToken) return [];

const endpoint = 'https://us-central1-stu-dashboard-a0ba2.cloudfunctions.net/getVaultMonitoring';
const tokenData = (await axios.get<VaultMonitoringResponse>(endpoint).then(v => v.data)).filter(
data => data.chain === 'ftm',
);
const tokenData = await axios.get<VaultMonitoringResponse>(endpoint).then(v => v.data);

const tokens = tokenData.map(async data => {
const symbol = data.tokens;
Expand Down
1 change: 1 addition & 0 deletions src/apps/sturdy/sturdy.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const STURDY_DEFINITION = appDefinition({
},

supportedNetworks: {
[Network.ETHEREUM_MAINNET]: [AppAction.VIEW],
[Network.FANTOM_OPERA_MAINNET]: [AppAction.VIEW],
},

Expand Down
6 changes: 6 additions & 0 deletions src/apps/sturdy/sturdy.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { Register } from '~app-toolkit/decorators';
import { AbstractApp } from '~app/app.dynamic-module';

import { SturdyContractFactory } from './contracts';
import { EthereumSturdyBalanceFetcher } from './ethereum/sturdy.balance-fetcher';
import { EthereumSturdyLendingTokenFetcher } from './ethereum/sturdy.lending.token-fetcher';
import { EthereumSturdyTvlFetcher } from './ethereum/sturdy.tvl-fetcher';
import { FantomSturdyBalanceFetcher } from './fantom/sturdy.balance-fetcher';
import { FantomSturdyLendingTokenFetcher } from './fantom/sturdy.lending.token-fetcher';
import { FantomSturdyTvlFetcher } from './fantom/sturdy.tvl-fetcher';
Expand All @@ -10,6 +13,9 @@ import { SturdyAppDefinition, STURDY_DEFINITION } from './sturdy.definition';
@Register.AppModule({
appId: STURDY_DEFINITION.id,
providers: [
EthereumSturdyBalanceFetcher,
EthereumSturdyLendingTokenFetcher,
EthereumSturdyTvlFetcher,
FantomSturdyBalanceFetcher,
FantomSturdyLendingTokenFetcher,
FantomSturdyTvlFetcher,
Expand Down