Skip to content

Commit

Permalink
update tokennetbalance farm display ui in stake modal (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
xieqiancaosissi authored Aug 27, 2024
1 parent c3e422b commit 4c9c6c4
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 39 deletions.
3 changes: 1 addition & 2 deletions hooks/useRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ export function useStakeRewardApy() {
return balance * (asset.price?.usd || 0);
})
.reduce((acc, cur) => acc + cur, 0);

// tokennet
const totalTokenNetMap = tokenNetRewards.reduce((acc, cur) => {
const { tokenId, newDailyAmount, assetTokenId } = cur as any;
Expand Down Expand Up @@ -200,7 +199,7 @@ export function useStakeRewardApy() {
};
}

function getTokennetMarketAPY(asset, assets) {
export function getTokennetMarketAPY(asset, assets) {
const assetDecimals = asset.metadata.decimals + asset.config.extra_decimals;
const tokenNetFarmsPending = asset.farms.tokennetbalance || {};
// Filter out the ones rewards sent out
Expand Down
12 changes: 10 additions & 2 deletions redux/selectors/getAccountRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { getStaking } from "./getStaking";
import { INetTvlFarmRewards } from "../../interfaces";
import { hasAssets, toUsd, emptySuppliedAsset, emptyBorrowedAsset } from "../utils";
import { cloneObj } from "../../helpers/helpers";
import { lpTokenPrefix, DEFAULT_POSITION } from "../../utils/config";
import { useAppSelector } from "../hooks";
import { getMarketRewardsDataUtil } from "./getMarketRewards";
import {
standardizeAsset,
filterAccountSentOutFarms,
Expand Down Expand Up @@ -590,7 +591,10 @@ export const getAccountBoostRatioData = createSelector(
(state: RootState) => state.account,
(state: RootState) => state.app,
getStaking,
(account, app, staking) => {
(state: RootState) => state.assets,
(account, app, staking, assets) => {
const { booster_log_base: booster_log_base_only_tokenBalance } =
getMarketRewardsDataUtil(assets);
const { totalXBRRR, BRRR, amount, totalXBRRRStaked } = staking;
const xBRRRAmount = totalXBRRR;
if (!app?.config?.boost_suppress_factor || !app?.config?.booster_decimals)
Expand All @@ -601,6 +605,10 @@ export const getAccountBoostRatioData = createSelector(
booster_log_base = getBoosterLogBaseFromAccountFarms(supplied);
if (!booster_log_base) {
booster_log_base = getBoosterLogBaseFromAccountFarms(borrowed);
if (!booster_log_base) {
// for no supply situation but has tokenBalance farm on market
booster_log_base = booster_log_base_only_tokenBalance;
}
}
}
if (booster_log_base) {
Expand Down
56 changes: 56 additions & 0 deletions redux/selectors/getMarketRewards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createSelector } from "@reduxjs/toolkit";
import { isEmpty } from "lodash";
import { RootState } from "../store";
import { getTokennetMarketAPY } from "../../hooks/useRewards";
import { AssetsState } from "../assetState";

export const getMarketRewardsData = createSelector(
(state: RootState) => state.assets,
(assets) => {
const result = getMarketRewardsDataUtil(assets);
return result;
},
);

export function getMarketRewardsDataUtil(assets: AssetsState) {
const allFarms = assets?.allFarms;
if (!allFarms || !assets?.data) return {};
const { tokenNetBalance } = allFarms;
// filter ended farms
const newTokenNetBalance = {};
Object.entries(tokenNetBalance || {}).forEach(([assetId, rewards]) => {
const activeFarms = filterEndedFarms(rewards);
if (!isEmpty(activeFarms)) {
newTokenNetBalance[assetId] = activeFarms;
}
});
const tokenNetBalanceMarketFarmData = Object.entries(newTokenNetBalance).map(([assetId]) => {
const asset = assets.data[assetId];
return {
asset,
marketAPY: getTokennetMarketAPY(asset, assets),
};
});
// eslint-disable-next-line consistent-return
return {
tokenNetBalance: tokenNetBalanceMarketFarmData,
booster_log_base: getBoosterLogBaseFromFarms(newTokenNetBalance),
};
}
function filterEndedFarms(rewards: any) {
const newRewards = {};
Object.entries(rewards).forEach(([rewardId, rewardData]: any) => {
if (rewardData.remaining_rewards !== "0") {
newRewards[rewardId] = rewardData;
}
});
return newRewards;
}
function getBoosterLogBaseFromFarms(marketFarms) {
const farms = Object.values(marketFarms)?.[0];
const farm = Object.values(farms || {})?.[0];
if (farm) {
return farm.booster_log_base;
}
return "";
}
6 changes: 3 additions & 3 deletions screens/Staking/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ const Staking = () => {
<div className="h2 flex items-center gap-3 mb-4 md:mb-0">
<BrrrLogo color="#D2FF3A" className="brrr-logo" />
<div className="brrr-amount flex flex-col md:flex-row md:gap-4 md:items-center">
{totalAmount > 0 ? totalAmount.toLocaleString(undefined, TOKEN_FORMAT) : 0}
{totalAmount > 0 ? totalAmount.toLocaleString() : 0}
<div className="text-gray-300 brrr-token">BRRR</div>
</div>
</div>
</StyledStakingHeader>
<div className="md:flex justify-center gap-4 md:gap-6">
<StakingBox
text1="💰 Available"
value1={Number(total || 0) > 0 ? total.toLocaleString(undefined, TOKEN_FORMAT) : 0}
value1={Number(total || 0) > 0 ? total.toLocaleString() : 0}
text2="Your APY"
value2={<YourAPY />}
text3="WalletBalance"
Expand Down Expand Up @@ -130,7 +130,7 @@ const Staking = () => {
logoIcon={disabledUnstake ? <LockIcon /> : <UnlockIcon />}
disabled={BRRR === 0}
text1="🔒 Staking"
value1={BRRR ? BRRR.toLocaleString(undefined, TOKEN_FORMAT) : 0}
value1={BRRR ? BRRR.toLocaleString() : 0}
text2={BRRR ? "Due to" : ""}
text4="Boost Ratio"
value4={displayMultiplierStaked}
Expand Down
46 changes: 14 additions & 32 deletions screens/Staking/modalStaking.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useEffect, useMemo, useState } from "react";
import _ from "lodash";
import Decimal from "decimal.js";
import { DateTime } from "luxon";
import styled from "styled-components";
Expand All @@ -18,21 +19,15 @@ import { Alerts } from "../../components/Modal/components";
import { ArrowRight } from "../../components/Icons/Icons";
import Booster from "./booster";
import { format_apy } from "../../utils/uiNumber";
import { getAccountBoostRatioData } from "../../redux/selectors/getAccountRewards";
import { getMarketRewardsData } from "../../redux/selectors/getMarketRewards";

const ModalStaking = ({ isOpen, onClose }) => {
const [total, totalUnclaim, totalToken] = useAppSelector(getTotalBRRR);
const app = useAppSelector((state) => state.app);
const [monthPercent, setMonthPercent] = useState(0);
const [loadingStake, setLoadingStake] = useState(false);
const {
stakingTimestamp,
amount,
months,
setAmount,
setMonths,
stakingNetAPY,
stakingNetTvlAPY,
} = useStaking();
const { stakingTimestamp, amount, months, setAmount, setMonths } = useStaking();
const [minMonth, maxMonth, monthList] = useMemo(() => {
if (app?.config) {
const { minimum_staking_duration_sec, maximum_staking_duration_sec } = app?.config || {};
Expand All @@ -53,6 +48,8 @@ const ModalStaking = ({ isOpen, onClose }) => {
const disabledStake = !amount || invalidAmount || invalidMonths;
const { avgStakeSupplyAPY, avgStakeBorrowAPY, avgStakeNetAPY, totalTokenNetMap } =
useStakeRewardApy();
const [, , multiplier] = useAppSelector(getAccountBoostRatioData);
const { tokenNetBalance } = useAppSelector(getMarketRewardsData);

const inputAmount = `${amount}`
.replace(/[^0-9.-]/g, "")
Expand All @@ -65,26 +62,19 @@ const ModalStaking = ({ isOpen, onClose }) => {
trackMaxStaking({ total: totalToken });
setAmount(totalToken);
};

const handleInputChange = (e) => {
let { value } = e?.target || {};
const numRegex = /^([0-9]*\.?[0-9]*$)/;
if (!numRegex.test(value)) {
e.preventDefault();
return;
}

if (Number(value) > Number(total)) {
value = total;
}
setAmount(value);
};

const handleSliderChange = (e) => {
const { value: percent } = e.target;
setAmount((Number(total) * percent) / 100);
};

const handleRangeSliderChange = (percent) => {
if (Number(percent) >= 99.7) {
setAmount(totalToken);
Expand All @@ -93,19 +83,10 @@ const ModalStaking = ({ isOpen, onClose }) => {
}
};

const handleMonthChange = (percent, v) => {
setMonths(v);
setMonthPercent(percent);
};

const handleMonthSliderChange = (v) => {
setMonths(v);
};

const handleFocus = (e) => {
e.target.select();
};

const handleStake = async () => {
try {
setLoadingStake(true);
Expand Down Expand Up @@ -138,7 +119,7 @@ const ModalStaking = ({ isOpen, onClose }) => {
<div className="px-2">
<div className="flex justify-between mb-2">
<span className="h5 text-gray-300">Available</span>
<span className="h5 text-gray-300">{total.toLocaleString(undefined, TOKEN_FORMAT)}</span>
<span className="h5 text-gray-300">{total.toLocaleString()}</span>
</div>
<StyledRow className="custom-input-wrap relative gap-2">
<BrrrLogo color="#D2FF3A" />
Expand Down Expand Up @@ -196,12 +177,13 @@ const ModalStaking = ({ isOpen, onClose }) => {
<div className="h5 text-gray-300">Avg. NetLiquidity Reward APY</div>
<div className="h5 text-primary">{format_apy(avgStakeNetAPY)}</div>
</div>
{Object.values(totalTokenNetMap).map((tokenNetData) => {
const { asset, totalTokenNetPrincipal, dailyRewardsUsd, marketAPY } =
tokenNetData as any;
const apy = new Decimal(totalTokenNetPrincipal).gt(0)
? new Decimal(dailyRewardsUsd).div(totalTokenNetPrincipal).mul(365).mul(100)
: new Decimal("0");
{_.orderBy(
Object.values(tokenNetBalance || {}),
(b) => Number(b.marketAPY || 0),
"desc",
).map((tokenNetData) => {
const { asset, marketAPY } = tokenNetData as any;
const apy = new Decimal(multiplier || 0).mul(marketAPY || 0);
return (
<div
key={asset.token_id}
Expand Down

0 comments on commit 4c9c6c4

Please sign in to comment.