diff --git a/redux/accountState.ts b/redux/accountState.ts index 1df06873..fe38c983 100644 --- a/redux/accountState.ts +++ b/redux/accountState.ts @@ -47,6 +47,9 @@ export interface Portfolio { borrowed: { [tokenId: string]: PortfolioAsset; }; + supplies: any[]; + collaterals: any[]; + borrows: any[]; positions: IPositions; farms: { supplied: { @@ -83,6 +86,9 @@ export const initialState: AccountState = { accountId: "", balances: {}, portfolio: { + supplies: [], + borrows: [], + collaterals: [], supplied: {}, collateral: {}, collateralAll: {}, diff --git a/redux/selectors/getAccountRewards.ts b/redux/selectors/getAccountRewards.ts index f9c629c9..27cbc09d 100644 --- a/redux/selectors/getAccountRewards.ts +++ b/redux/selectors/getAccountRewards.ts @@ -43,23 +43,42 @@ export interface IAccountRewards { export const getGains = ( portfolio: Portfolio, assets: AssetsState, - source: "supplied" | "collateral" | "borrowed", + source: "supplied" | "collateral" | "borrowed" | "collateralAll", withNetTvlMultiplier = false, ) => { - const sourceType = source === "collateral" ? "collateralAll" : source; - const data = portfolio[sourceType]; // TODO - return Object.keys(data) - .map((id) => { - const asset = assets.data[id]; - const netTvlMultiplier = asset.config.net_tvl_multiplier / 10000; - - const { balance } = data[id]; - const apr = Number(data[id].apr); - const balanceUSD = toUsd(balance, asset); - - return [balanceUSD * (withNetTvlMultiplier ? netTvlMultiplier : 1), apr]; - }) - .reduce(([gain, sum], [balance, apr]) => [gain + balance * apr, sum + balance], [0, 0]); + const data = portfolio[source]; + const res = Object.keys(data).map((id) => { + const asset = assets.data[id]; + const netTvlMultiplier = asset.config.net_tvl_multiplier / 10000; + + const { balance } = data[id]; + const apr = Number(data[id].apr); + const balanceUSD = toUsd(balance, asset); + + return [balanceUSD * (withNetTvlMultiplier ? netTvlMultiplier : 1), apr]; + }); + const result = res.reduce( + ([gain, sum], [balance, apr]) => [gain + balance * apr, sum + balance], + [0, 0], + ); + return result; +}; + +export const getGainsArr = (tokens: any[], assets: AssetsState, withNetTvlMultiplier = false) => { + const res = tokens.map((data) => { + const asset = assets.data[data.token_id]; + const netTvlMultiplier = asset.config.net_tvl_multiplier / 10000; + const { balance } = data; + const apr = Number(data.apr); + const balanceUSD = toUsd(balance, asset); + + return [balanceUSD * (withNetTvlMultiplier ? netTvlMultiplier : 1), apr]; + }); + const result = res.reduce( + ([gain, sum], [balance, apr]) => [gain + balance * apr, sum + balance], + [0, 0], + ); + return result; }; export const computePoolsDailyAmount = ( @@ -157,10 +176,14 @@ export const getAccountRewards = createSelector( const brrrTokenId = app.config.booster_token_id; const { xBRRR, extraXBRRRAmount } = staking; const xBRRRAmount = xBRRR + extraXBRRRAmount; - - const [, totalCollateral] = getGains(account.portfolio, assets, "collateral"); + const { borrows, collaterals } = account.portfolio || {}; const [, totalSupplied] = getGains(account.portfolio, assets, "supplied"); - const [, totalBorrowed] = getGains(account.portfolio, assets, "borrowed"); + const [, totalCollateral] = collaterals + ? getGainsArr(account.portfolio.collaterals, assets) + : getGains(account.portfolio, assets, "collateral"); + const [, totalBorrowed] = borrows + ? getGainsArr(account.portfolio.borrows, assets) + : getGains(account.portfolio, assets, "borrowed"); const netLiquidity = totalCollateral + totalSupplied - totalBorrowed; @@ -172,7 +195,6 @@ export const getAccountRewards = createSelector( const rewardAsset = assets.data[rewardTokenId]; const rewardAssetDecimals = rewardAsset.metadata.decimals + rewardAsset.config.extra_decimals; - const { icon, symbol, name } = rewardAsset.metadata; const unclaimedAmount = Number( @@ -282,10 +304,14 @@ export const getWeightedNetLiquidity = createSelector( (state: RootState) => state.account, (assets, account) => { if (!hasAssets(assets)) return 0; - - const [, totalCollateral] = getGains(account.portfolio, assets, "collateral", true); + const { borrows, collaterals } = account.portfolio || {}; const [, totalSupplied] = getGains(account.portfolio, assets, "supplied", true); - const [, totalBorrowed] = getGains(account.portfolio, assets, "borrowed", true); + const [, totalCollateral] = collaterals + ? getGainsArr(account.portfolio.collaterals, assets, true) + : getGains(account.portfolio, assets, "collateral", true); + const [, totalBorrowed] = borrows + ? getGainsArr(account.portfolio.borrows, assets, true) + : getGains(account.portfolio, assets, "borrowed", true); const netLiquidity = totalCollateral + totalSupplied - totalBorrowed; return netLiquidity; diff --git a/redux/selectors/getNetAPY.ts b/redux/selectors/getNetAPY.ts index 49381cc0..275f910e 100644 --- a/redux/selectors/getNetAPY.ts +++ b/redux/selectors/getNetAPY.ts @@ -3,9 +3,8 @@ import { createSelector } from "@reduxjs/toolkit"; import { RootState } from "../store"; import { hasAssets } from "../utils"; import { getExtraDailyTotals } from "./getExtraDailyTotals"; -import { getAccountRewards, getGains } from "./getAccountRewards"; +import { getAccountRewards, getGains, getGainsArr } from "./getAccountRewards"; import { getProtocolRewards } from "./getProtocolRewards"; -import { getTotalBalance } from "./getTotalBalance"; import { shrinkToken } from "../../store/helper"; export const getNetAPY = ({ isStaking = false }: { isStaking: boolean }) => @@ -15,11 +14,15 @@ export const getNetAPY = ({ isStaking = false }: { isStaking: boolean }) => getExtraDailyTotals({ isStaking }), (assets, account, extraDaily) => { if (!hasAssets(assets)) return 0; - - const [gainCollateral, totalCollateral] = getGains(account.portfolio, assets, "collateral"); + // check if new data borrows/collaterals exist, could be remove in next patch + const { borrows, collaterals } = account?.portfolio || {}; + const [gainBorrowed, totalBorrowed] = borrows + ? getGainsArr(borrows, assets) + : getGains(account.portfolio, assets, "borrowed"); + const [gainCollateral, totalCollateral] = collaterals + ? getGainsArr(collaterals, assets) + : getGains(account.portfolio, assets, "collateral"); const [gainSupplied, totalSupplied] = getGains(account.portfolio, assets, "supplied"); - const [gainBorrowed, totalBorrowed] = getGains(account.portfolio, assets, "borrowed"); - const gainExtra = extraDaily * 365; const netGains = gainCollateral + gainSupplied + gainExtra - gainBorrowed; @@ -37,10 +40,14 @@ export const getNetTvlAPY = ({ isStaking = false }) => getAccountRewards, (assets, account, rewards) => { if (!hasAssets(assets)) return 0; - - const [, totalCollateral] = getGains(account.portfolio, assets, "collateral"); + const { borrows, collaterals } = account.portfolio || {}; const [, totalSupplied] = getGains(account.portfolio, assets, "supplied"); - const [, totalBorrowed] = getGains(account.portfolio, assets, "borrowed"); + const [, totalCollateral] = collaterals + ? getGainsArr(account.portfolio.collaterals, assets) + : getGains(account.portfolio, assets, "collateral"); + const [, totalBorrowed] = borrows + ? getGainsArr(account.portfolio.borrows, assets) + : getGains(account.portfolio, assets, "borrowed"); const netTvlRewards = Object.values(rewards.net).reduce( (acc, r) => acc + (isStaking ? r.newDailyAmount : r.dailyAmount) * r.price, diff --git a/redux/selectors/getTotalAccountBalance.ts b/redux/selectors/getTotalAccountBalance.ts index 409806bc..f95d91c4 100644 --- a/redux/selectors/getTotalAccountBalance.ts +++ b/redux/selectors/getTotalAccountBalance.ts @@ -1,5 +1,5 @@ +import _ from "lodash"; import { createSelector } from "@reduxjs/toolkit"; - import { shrinkToken } from "../../store"; import { RootState } from "../store"; import { sumReducer, hasAssets } from "../utils"; @@ -10,16 +10,21 @@ export const getTotalAccountBalance = (source: "borrowed" | "supplied") => (state: RootState) => state.account, (assets, account) => { if (!hasAssets(assets)) return 0; - const allTokens = { - ...account.portfolio.collateralAll, - ...account.portfolio.supplied, - ...account.portfolio.borrowed, - }; - const sourceTokens = account.portfolio[source]; + const { collateralAll, borrows, collaterals, supplies } = account.portfolio || {}; - const { collateral, collateralAll } = account.portfolio; - return Object.keys(allTokens) - .map((tokenId) => { + let tokenAmounts: any[] = []; + if (borrows && collaterals && supplies) { + tokenAmounts = sumTokenAmounts(account, assets, source); + } + // todo: remove on next patch + else { + const allTokens = { + ...account.portfolio.collateralAll, + ...account.portfolio.supplied, + ...account.portfolio.borrowed, + }; + const sourceTokens = account.portfolio[source]; + tokenAmounts = Object.keys(allTokens).map((tokenId) => { const { price, metadata, config } = assets.data[tokenId]; const total = Number( @@ -36,9 +41,33 @@ export const getTotalAccountBalance = (source: "borrowed" | "supplied") => metadata.decimals + config.extra_decimals, ), ) * (price?.usd || 0); - + // console.log(`== tokenId:${tokenId} total:${total} totalCollateral:${totalCollateral}`) return source === "supplied" ? total + totalCollateral : total; - }) - .reduce(sumReducer, 0); + }); + } + return tokenAmounts.reduce(sumReducer, 0); }, ); + +const sumTokenAmounts = (account, assets, source) => { + const { collateral, borrows, collaterals, supplies } = account.portfolio || {}; + let tokens = source === "supplied" ? [...supplies, ...collaterals] : borrows; + tokens = _.uniqBy(tokens, "token_id"); + const tokenAmounts = tokens.map((d) => { + const { token_id } = d || {}; + const { price, metadata, config } = assets.data[token_id]; + + const total = + Number(shrinkToken(d?.balance || 0, metadata.decimals + config.extra_decimals)) * + (price?.usd || 0); + + const totalCollateral = + Number( + shrinkToken(collateral[token_id]?.balance || 0, metadata.decimals + config.extra_decimals), + ) * (price?.usd || 0); + // console.log(`>> source:${source} tokenId:${token_id} total:${total} totalCollateral:${totalCollateral} metadata:${metadata}`) + return source === "supplied" ? total + totalCollateral : total; + }); + + return tokenAmounts; +}; diff --git a/transformers/account.ts b/transformers/account.ts index fdeded00..9a7d3e22 100644 --- a/transformers/account.ts +++ b/transformers/account.ts @@ -20,15 +20,36 @@ export const transformPortfolio = (account) => { }); let collateralAll = {}; - Object.entries(positions).forEach(([key, value]: [string, any]) => { + const collaterals: any[] = []; + const borrows: any[] = []; + + Object.entries(positions).forEach(([positionId, value]: [string, any]) => { if (value?.collateral) { collateralAll = { ...collateralAll, ...value.collateral, }; } + Object.entries(value.borrowed).forEach(([tokenId, tokenObj]: [string, any]) => { + borrows.push({ + ...tokenObj, + token_id: tokenId, + positionId, + }); + }); + Object.entries(value.collateral).forEach(([tokenId, tokenObj]: [string, any]) => { + collaterals.push({ + ...tokenObj, + token_id: tokenId, + positionId, + }); + }); }); + return { + supplies: supplied, + borrows, + collaterals, supplied: listToMap(supplied), borrowed: positions[DEFAULT_POSITION].borrowed, collateral: positions[DEFAULT_POSITION].collateral,