From 2345afcf359fc730bbaefb48e0cc48da0bb6da89 Mon Sep 17 00:00:00 2001 From: Zak Date: Thu, 7 Nov 2024 12:02:17 +0000 Subject: [PATCH 01/14] feat: yield text tweaks --- .../vault/yield/YieldPerformanceModal.jsx | 4 +- src/components/vault/yield/YieldSummary.jsx | 75 +++++++++---------- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/components/vault/yield/YieldPerformanceModal.jsx b/src/components/vault/yield/YieldPerformanceModal.jsx index 0d6c71f..56280a0 100644 --- a/src/components/vault/yield/YieldPerformanceModal.jsx +++ b/src/components/vault/yield/YieldPerformanceModal.jsx @@ -189,8 +189,8 @@ const YieldPerformanceModal = ({ Current Value - - ${currentUSD?.toFixed(2) || ''} + + ~${currentUSD?.toFixed(2) || ''} diff --git a/src/components/vault/yield/YieldSummary.jsx b/src/components/vault/yield/YieldSummary.jsx index 19fbd92..a443bbc 100644 --- a/src/components/vault/yield/YieldSummary.jsx +++ b/src/components/vault/yield/YieldSummary.jsx @@ -148,26 +148,15 @@ const YieldSummary = ({
- - Assets in Yield Pools - - {gammaUserLoading ? ( - <> - - - ) : ( - <> - - {formatUSD(metrics.totalBalance)} - - - )} -
-
- - Yield Generated - -
+
+ + Market Movement + + + If held without yield pools + +
+
{gammaUserLoading ? ( <> @@ -176,30 +165,25 @@ const YieldSummary = ({ <> = 0 ? 'text-green-500' : 'text-red-400'}`} > - {formatUSD(metrics.totalYieldEarned)} + {formatUSD(metrics.totalMarketYield)} = 0 ? 'text-green-500' : 'text-red-400'}`} > - {formatPercentage(metrics.weightedAverageYieldAPY)} APY + {formatPercentage(metrics.weightedAverageMarketAPY)} )}
-
- - Market Movement - - - If held without yield pools - -
-
+ + Yield Generated + +
{gammaUserLoading ? ( <> @@ -208,22 +192,37 @@ const YieldSummary = ({ <> = 0 ? 'text-green-500' : 'text-red-400'}`} + className={`text-end ${getYieldColor(metrics.totalYieldEarned)}`} > - {formatUSD(metrics.totalMarketYield)} + {formatUSD(metrics.totalYieldEarned)} = 0 ? 'text-green-500' : 'text-red-400'}`} + className={`text-end ${getYieldColor(metrics.weightedAverageYieldAPY)}`} > - {formatPercentage(metrics.weightedAverageMarketAPY)} + {formatPercentage(metrics.weightedAverageYieldAPY)} APY )}
+
+ + Assets in Yield Pools + + {gammaUserLoading ? ( + <> + + + ) : ( + <> + + {formatUSD(metrics.totalBalance)} + + + )} +
-
From d480287983abdd8c6ad5ff5078091364df76386e Mon Sep 17 00:00:00 2001 From: Zak Date: Thu, 7 Nov 2024 12:11:49 +0000 Subject: [PATCH 02/14] chore: undo temp hide --- src/App.jsx | 6 +- src/components/ui/SideNav.jsx | 8 +- src/pages/staking-pool/StakingPoolLegacy.jsx | 182 ------------------- 3 files changed, 6 insertions(+), 190 deletions(-) delete mode 100644 src/pages/staking-pool/StakingPoolLegacy.jsx diff --git a/src/App.jsx b/src/App.jsx index 3029833..cb1470a 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -11,7 +11,6 @@ import Vault from './pages/vault/Vault'; import VaultHistory from './pages/vault/VaultHistory'; import LiquidationPools from './pages/liquidation-pools/LiquidationPools'; import TstStaking from './pages/tst-staking/TstStaking'; -import StakingPool from './pages/staking-pool/StakingPoolLegacy'; import LegacyPools from './pages/legacy-pools/LegacyPools'; import TermsOfUse from './pages/TermsOfUse'; import Dex from './pages/dex/Dex'; @@ -33,9 +32,8 @@ function App() { } /> } /> } /> - {/* } /> */} - {/* } /> */} - } /> + } /> + } /> } /> } /> } /> diff --git a/src/components/ui/SideNav.jsx b/src/components/ui/SideNav.jsx index 9041c89..97e0fcb 100644 --- a/src/components/ui/SideNav.jsx +++ b/src/components/ui/SideNav.jsx @@ -93,7 +93,7 @@ const SideNav = (props) => { Cross-Chain Dex - {/* + @@ -107,7 +107,7 @@ const SideNav = (props) => { Legacy Pools - */} +
{/* Med + */}
@@ -172,7 +172,7 @@ const SideNav = (props) => { - {/* @@ -191,7 +191,7 @@ const SideNav = (props) => { - */} +
diff --git a/src/pages/staking-pool/StakingPoolLegacy.jsx b/src/pages/staking-pool/StakingPoolLegacy.jsx deleted file mode 100644 index 09380d4..0000000 --- a/src/pages/staking-pool/StakingPoolLegacy.jsx +++ /dev/null @@ -1,182 +0,0 @@ -import { useState } from "react"; -import moment from 'moment'; -import { - useReadContract, - useAccount, - useChainId, - useWatchBlockNumber -} from "wagmi"; -import { arbitrumSepolia } from "wagmi/chains"; -import { - ArrowTrendingUpIcon, - BanknotesIcon, -} from '@heroicons/react/24/outline'; - -import { - useStakingPoolv2AbiStore, - useStakingPoolv2AddressStore, -} from "../../store/Store"; - -import StakingIncrease from "../../components/staking-pool/StakingIncrease"; -import StakingAssets from "../../components/staking-pool/StakingAssets"; -import StakingRewards from "../../components/staking-pool/StakingRewards"; -import VolumeChart from "../../components/staking-pool/VolumeChart"; -import ValueChart from "../../components/staking-pool/ValueChart"; - -import Card from "../../components/ui/Card"; -import CenterLoader from "../../components/ui/CenterLoader"; -import Typography from "../../components/ui/Typography"; -import Button from "../../components/ui/Button"; - -const StakingPool = (props) => { - const { stakingPoolv2Abi } = useStakingPoolv2AbiStore(); - const [showValue, setShowValue] = useState(false); - - const { - arbitrumSepoliaStakingPoolv2Address, - arbitrumStakingPoolv2Address, - } = useStakingPoolv2AddressStore(); - - const { address } = useAccount(); - const chainId = useChainId(); - - const stakingPoolv2Address = - chainId === arbitrumSepolia.id - ? arbitrumSepoliaStakingPoolv2Address - : arbitrumStakingPoolv2Address; - - const { data: poolPositions, refetch: refetchPositions } = useReadContract({ - address: stakingPoolv2Address, - abi: stakingPoolv2Abi, - functionName: "positions", - args: [address], - }); - - const { data: poolRewards, isLoading: poolRewardsLoading, refetch: refetchRewards } = useReadContract({ - address: stakingPoolv2Address, - abi: stakingPoolv2Abi, - functionName: "projectedEarnings", - args: [address], - }); - - const { data: dailyYield, refetch: refetchDailyReward } = useReadContract({ - address: stakingPoolv2Address, - abi: stakingPoolv2Abi, - functionName: "dailyYield", - args: [], - }); - - useWatchBlockNumber({ - onBlockNumber() { - refetchPositions(); - refetchRewards(); - refetchDailyReward(); - }, - }) - - const positions = poolPositions; - const rewards = poolRewards; - const dailyRewards = dailyYield; - - - let sEuroAmount = 0n; - let collaterals = []; - - if (rewards && rewards[0]) { - sEuroAmount = rewards[0] || 0n; - } - if (rewards && rewards[1]) { - collaterals = rewards[1] || []; - } - - let sEuroDaily = 0n; - let collatDaily = []; - - if (dailyRewards && dailyRewards[0]) { - sEuroDaily = dailyRewards[0] || 0n; - } - if (dailyRewards && dailyRewards[1]) { - collatDaily = dailyRewards[1] || []; - } - - let stakedSince = 0; - if (positions && positions[0]) { - stakedSince = positions[0] || 0; - } - - let useStakedSince; - if (stakedSince) { - useStakedSince = moment.unix(Number(stakedSince)).format('Do MMM YYYY'); - } - - return ( -
-
- -
- -
- -
- -
- -
- - {showValue ? ( - 'Asset Value' - ) : ( - 'Asset Totals' - )} - - - {showValue ? ( - <> - - - ) : ( - <> - - - )} -
-
-
- -
- {poolRewardsLoading ? ( - -
- -
-
- ) : ( - - )} -
- -
- ); -}; - -export default StakingPool; \ No newline at end of file From 18f5a530202e70e0f48561ea0c1259947c7c1161 Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 15:03:28 +0000 Subject: [PATCH 03/14] feat: revamp tst staking and code cleanup --- src/assets/facebooklogo.svg | 3 + .../tst-staking/StakingDecreaseModal.jsx | 6 +- src/components/tst-staking/StakingRewards.jsx | 153 ++--- .../tst-staking/StakingRewardsList.jsx | 119 ++++ .../tst-staking/StakingShareModal.jsx | 142 +++++ src/components/tst-staking/StakingSummary.jsx | 548 ++++++++++++++++++ src/components/ui/Notifications.jsx | 6 +- src/components/vault/BorrowModal.jsx | 2 +- src/components/vault/EurosCompare.jsx | 2 +- src/components/vault/VaultStats.jsx | 26 +- src/components/vault/yield/YieldList.jsx | 4 +- .../vault/yield/YieldPerformanceModal.jsx | 4 +- src/components/vault/yield/YieldSummary.jsx | 6 +- src/components/vault/yield/YieldViewModal.jsx | 14 +- src/pages/tst-staking/TstStaking.jsx | 73 ++- 15 files changed, 951 insertions(+), 157 deletions(-) create mode 100644 src/assets/facebooklogo.svg create mode 100644 src/components/tst-staking/StakingRewardsList.jsx create mode 100644 src/components/tst-staking/StakingShareModal.jsx create mode 100644 src/components/tst-staking/StakingSummary.jsx diff --git a/src/assets/facebooklogo.svg b/src/assets/facebooklogo.svg new file mode 100644 index 0000000..3216363 --- /dev/null +++ b/src/assets/facebooklogo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/components/tst-staking/StakingDecreaseModal.jsx b/src/components/tst-staking/StakingDecreaseModal.jsx index 24769df..f73f96d 100644 --- a/src/components/tst-staking/StakingDecreaseModal.jsx +++ b/src/components/tst-staking/StakingDecreaseModal.jsx @@ -20,7 +20,7 @@ import Input from "../ui/Input"; import CenterLoader from "../ui/CenterLoader"; const StakingDecreaseModal = ({ - stakedPositions, + tstAmount, isOpen, handleCloseModal, }) => { @@ -36,9 +36,7 @@ const StakingDecreaseModal = ({ const tstInputRef = useRef(null); - const tstPosition = stakedPositions?.find((item) => item.asset === 'TST'); - - const tstStakedAmount = tstPosition?.amount; + const tstStakedAmount = tstAmount; const useTstStakedAmount = formatEther(tstStakedAmount.toString()); diff --git a/src/components/tst-staking/StakingRewards.jsx b/src/components/tst-staking/StakingRewards.jsx index db0e00f..20d1c89 100644 --- a/src/components/tst-staking/StakingRewards.jsx +++ b/src/components/tst-staking/StakingRewards.jsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import { ethers } from "ethers"; import { useReadContracts, } from "wagmi"; @@ -8,29 +7,40 @@ import { useErc20AbiStore, } from "../../store/Store"; -import Button from "../ui/Button"; import Card from "../ui/Card"; -import Typography from "../ui/Typography"; import CenterLoader from "../ui/CenterLoader"; -import ClaimingRewardsModal from "./ClaimingRewardsModal"; +import StakingSummary from "./StakingSummary"; +import StakingRewardsList from "./StakingRewardsList"; const StakingRewards = ({ - stakedSince, - collaterals, + positions, poolRewardsLoading, + dailyYieldLoading, + rewards, + collaterals, + stakedSince, + rawStakedSince, collatDaily, + priceData, + priceDataLoading, }) => { - const [open, setOpen] = useState(false); const { erc20Abi } = useErc20AbiStore(); - if (poolRewardsLoading) { + if (poolRewardsLoading || dailyYieldLoading || priceDataLoading) { return ( - -
- -
-
+ <> + +
+ +
+
+ +
+ +
+
+ ) } @@ -87,93 +97,42 @@ const StakingRewards = ({ } }); - const handleCloseModal = () => { - setOpen(false) - }; - - const rows = rewardData || []; - - let noRewards = true; - if (rows.some(e => e.amount > 0)) { - noRewards = false; + const handleDailyPrices = () => { + const prices = {}; + for (const [token, tokenData] of Object.entries(priceData)) { + if (tokenData.prices && tokenData.prices.length > 0) { + const latestPrice = tokenData.prices[tokenData.prices.length - 1].price; + // Convert price to USD considering decimals + prices[token] = parseFloat(latestPrice) / 1000000; + } + } + return prices; } - return ( - -
- - Projected Rewards - -
- - You can earn rewards every 24 hours after your staking period begins. - - - Your reward rates are based on a the number of tokens you have staked. - - {stakedSince ? ( - - Staked Since: - {stakedSince} - - ) : null} -
- -
- - - - - - - - - {poolRewardsLoading ? (null) : ( - - {rows.map(function(asset, index) { - const amount = asset?.amount || 0n; - const decimals = asset?.decimals; - const symbol = asset?.asset; - const dailyReward = asset?.dailyReward || 0n; - - return( - - - - - - )} - )} - - )} -
AssetAmountDaily Reward Per Token
- {symbol} - - {ethers.formatUnits(amount, decimals)} - - {ethers.formatUnits(dailyReward, decimals)} - / TST -
- {poolRewardsLoading ? ( - - ) : (null)} -
+ const latestPrices = handleDailyPrices(); -
- -
- -
-
+ return ( +
+ + +
) }; diff --git a/src/components/tst-staking/StakingRewardsList.jsx b/src/components/tst-staking/StakingRewardsList.jsx new file mode 100644 index 0000000..9657f26 --- /dev/null +++ b/src/components/tst-staking/StakingRewardsList.jsx @@ -0,0 +1,119 @@ +import { useState } from "react"; +import { ethers } from "ethers"; + +import Button from "../ui/Button"; +import Card from "../ui/Card"; +import Typography from "../ui/Typography"; +import CenterLoader from "../ui/CenterLoader"; + +import ClaimingRewardsModal from "./ClaimingRewardsModal"; + +const StakingRewardsList = ({ + stakedSince, + poolRewardsLoading, + rewardData, +}) => { + const [open, setOpen] = useState(false); + + if (poolRewardsLoading) { + return ( + +
+ +
+
+ ) + } + + const handleCloseModal = () => { + setOpen(false) + }; + + const rows = rewardData || []; + + let noRewards = true; + if (rows.some(e => e.amount > 0)) { + noRewards = false; + } + + return ( + +
+ + Your Claimable Staking Rewards + +
+ + You can earn rewards every 24 hours after your staking period begins. + + + Your reward rates are based on a the number of tokens you have staked. + + {stakedSince ? ( + + Staked Since: + {stakedSince} + + ) : null} +
+ +
+ + + + + + + + + {poolRewardsLoading ? (null) : ( + + {rows.map(function(asset, index) { + const amount = asset?.amount || 0n; + const decimals = asset?.decimals; + const symbol = asset?.asset; + const dailyReward = asset?.dailyReward || 0n; + + return( + + + + + + )} + )} + + )} +
AssetAmountDaily Reward Per Token
+ {symbol} + + {ethers.formatUnits(amount, decimals)} + + {ethers.formatUnits(dailyReward, decimals)} + / TST +
+ {poolRewardsLoading ? ( + + ) : (null)} +
+ +
+ +
+ +
+
+ ) +}; + +export default StakingRewardsList; diff --git a/src/components/tst-staking/StakingShareModal.jsx b/src/components/tst-staking/StakingShareModal.jsx new file mode 100644 index 0000000..1a22559 --- /dev/null +++ b/src/components/tst-staking/StakingShareModal.jsx @@ -0,0 +1,142 @@ +import { useState, useEffect, useRef } from "react"; +import { toast } from 'react-toastify'; + +import { + useLocalThemeModeStore, +} from "../../store/Store"; + +import { + DocumentDuplicateIcon, +} from '@heroicons/react/24/solid'; + +import Button from "../ui/Button"; +import Modal from "../ui/Modal"; +import Typography from "../ui/Typography"; + +import twitterLogo from "../../assets/twitterlogo.svg"; +import facebookLogo from "../../assets/facebooklogo.svg"; +import linkedinLogo from "../../assets/linkedinlogo.svg"; + +const StakingShareModal = ({ + isOpen, + handleCloseModal, + shareText, +}) => { + const { localThemeModeStore } = useLocalThemeModeStore(); + const isLight = localThemeModeStore && localThemeModeStore.includes('light'); + + const handleCopyText = () => { + const textElement = shareText; + + if (navigator.clipboard && textElement) { + const text = textElement; + + navigator.clipboard + .writeText(text) + .then(() => { + toast.success('Copied to clipboard!'); + }) + .catch((error) => { + toast.error('There was a problem'); + }); + } + }; + + return ( + <> + { + handleCloseModal(); + }} + > +
+ + Share Your Success + +
+            {shareText.toString()}
+          
+
+ +
+ + + + + +
+ +
+ +
+
+ + ) + +}; + +export default StakingShareModal; diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx new file mode 100644 index 0000000..96185a0 --- /dev/null +++ b/src/components/tst-staking/StakingSummary.jsx @@ -0,0 +1,548 @@ +import { useState } from "react"; +import moment from 'moment'; + +import { ethers } from "ethers"; + +import { + Progress, + Tooltip, +} from 'react-daisyui'; + +import { + QuestionMarkCircleIcon, + ShareIcon, + TrophyIcon, + ShieldCheckIcon, + BookOpenIcon, +} from '@heroicons/react/24/outline'; + +import Button from "../ui/Button"; +import Card from "../ui/Card"; +import Typography from "../ui/Typography"; +import CenterLoader from "../ui/CenterLoader"; + +import StakingDecreaseModal from "./StakingDecreaseModal"; +import StakingShareModal from "./StakingShareModal"; + +const tierIconClass = 'h-6 w-6'; + +const STATUS_TIERS = [ + { + tier: 1, + name: 'Protocol Hero', + minAmount: 5000000, + icon: , + gradient: 'from-rose-100 via-purple-100 to-indigo-100', + description: 'Legendary protocol champion', + iconColor: 'text-purple-600' + }, + { + tier: 2, + name: 'Protocol Guardian', + minAmount: 1000000, + icon: , + gradient: 'from-violet-50 to-purple-50', + description: 'Elite guardian of protocol stability', + iconColor: 'text-violet-600' + }, + { + tier: 3, + name: 'Protocol Sentinel', + minAmount: 500000, + icon: , + gradient: 'from-indigo-50 to-violet-50', + description: 'Sentinel of protocol security', + iconColor: 'text-indigo-600' + }, + { + tier: 4, + name: 'Protocol Custodian', + minAmount: 250000, + icon: , + gradient: 'from-blue-50 to-indigo-50', + description: 'Custodian of protocol growth', + iconColor: 'text-blue-600' + }, + { + tier: 5, + name: 'Master Staker', + minAmount: 100000, + icon: , + gradient: 'from-cyan-50 to-blue-50', + description: 'Master of protocol operations', + iconColor: 'text-cyan-600' + }, + { + tier: 6, + name: 'Expert Staker', + minAmount: 50000, + icon: , + gradient: 'from-teal-50 to-cyan-50', + description: 'Expert protocol participant', + iconColor: 'text-teal-600' + }, + { + tier: 7, + name: 'Advanced Staker', + minAmount: 25000, + icon: , + gradient: 'from-emerald-50 to-teal-50', + description: 'Advanced protocol supporter', + iconColor: 'text-emerald-600' + }, + { + tier: 8, + name: 'Seasoned Staker', + minAmount: 10000, + icon: , + gradient: 'from-green-50 to-emerald-50', + description: 'Seasoned protocol backer', + iconColor: 'text-green-600' + }, + { + tier: 9, + name: 'Active Staker', + minAmount: 5000, + icon: , + gradient: 'from-lime-50 to-green-50', + description: 'Active protocol supporter', + iconColor: 'text-lime-600' + }, + { + tier: 10, + name: 'Protocol Supporter', + minAmount: 1000, + icon: , + gradient: 'from-yellow-50 to-lime-50', + description: 'Dedicated protocol supporter', + iconColor: 'text-yellow-600' + }, + { + tier: 11, + name: 'Protocol Participant', + minAmount: 0, + icon: , + gradient: 'from-gray-50 to-yellow-50', + description: 'Protocol participant', + iconColor: 'text-gray-600' + } +]; + + +const formatNumber = (number, decimals = 2) => { + if (typeof number === 'string') number = parseFloat(number); + return new Intl.NumberFormat('en-US', { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals + }).format(number); +} + +const formatUSD = (value) => { + if (value >= 0) { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }).format(Math.abs(value)); + } +}; + +const StakingSummary = ({ + positions, + poolRewardsLoading, + dailyYieldLoading, + rewards, + rewardsData, + collaterals, + stakedSince, + rawStakedSince, + collatDaily, + latestPrices, +}) => { + const [open, setOpen] = useState(false); + const [shareOpen, setShareOpen] = useState(false); + + if (!positions) { + return ( + +
+ +
+
+ ) + } + + const tstAmount = positions[1] || 0; + + let noStaked = true; + if (tstAmount > 0) { + noStaked = false; + } + + // formatted amount + const stakedAmount = ethers.formatEther(tstAmount.toString()); + + const handleCloseModal = () => { + setOpen(false) + }; + + const handleCloseShare = () => { + setShareOpen(false) + }; + + + const getCurrentTier = (stakedAmount) => { + const currentTier = STATUS_TIERS.filter(function(tier) { + const currentTier = tier.tier; + const isLess = stakedAmount >= tier.minAmount; + const hasLowerTier = STATUS_TIERS.some(lower => ( + (lower.tier > currentTier) && (stakedAmount <= lower.minAmount) + )) + return isLess && !hasLowerTier; + }) + return currentTier[0]; + } + + const getNextTier = (stakedAmount) => { + const currentTier = getCurrentTier(stakedAmount); + const nextTier = STATUS_TIERS?.find((tier) => ( + tier.tier === currentTier.tier -1 + )); + if (nextTier) { + return nextTier; + } else { + return currentTier; + } + } + + function getDaysStaked() { + const start = moment.unix((Number(rawStakedSince))); + const today = moment(); + const testSince = start.diff(today, 'days')+1; + return testSince; + } + + const calculateSimpleAPY = (stakedAmount, totalRewardsValue, daysStaked) => { + const dailyEarnings = totalRewardsValue / daysStaked; + const annualEarningsPerTST = (dailyEarnings * 365) / stakedAmount; + return annualEarningsPerTST * 100; + } + + const rewardsWithPrices = rewardsData.map(reward => { + const price = latestPrices[reward.asset] || 1; // Default to 1 for stablecoins + const usdValue = parseFloat(reward.amount) * price; + return { + ...reward, + usdValue: usdValue, + price: price + }; + }) + + const totalValue = rewardsWithPrices.reduce((sum, reward) => sum + reward.usdValue, 0) || 0; + + const daysStaked = getDaysStaked() || 0; + const dailyEarnings = (totalValue / daysStaked) || 0; + const monthlyProjection = (dailyEarnings * 30) || 0; + + const currentTier = getCurrentTier(stakedAmount); + const nextTier = getNextTier(stakedAmount); + + let progress = 0; + if (nextTier?.minAmount) { + progress = (stakedAmount / nextTier.minAmount) * 100; + } + const apyDisplay = calculateSimpleAPY(stakedAmount, totalValue, daysStaked) + '%' || '0%'; + + let stakeRatio = 'TODO.DOTO'; + + let progressPercentage = `${progress}%`; + + let tierRemaining = '0'; + if (nextTier && nextTier.minAmount) { + tierRemaining = formatNumber(nextTier.minAmount - stakedAmount); + } + + const lowestTier = STATUS_TIERS[STATUS_TIERS.length - 1]; + + const shareText = `🏆 ${currentTier.name} on @TheStandardIO\n\n💫 Staking ${formatNumber(stakedAmount)} TST\n💰 Earning ${formatUSD(dailyEarnings)} daily\n⚡️ Supporting zero-interest borrowing\n\nJoin the future of DeFi!\nthestandard.io`; + + if (!rawStakedSince) { + return ( + +
+ + TST Staking + + + + Participate in protocol governance + + +
+
+
+ + Total TST Staked + + + 0 TST + +
+
+
+
+ + Historical APY + + + + + + 0% + +
+
+
+ +
+
+
+ + Your Daily Earnings + + + {formatUSD(0)} + +
+ + Earning {formatUSD(0)} monthly at current rates + +
+
+ +
+
+
+
+ +
+
+ + Current Status + + + Not Staked + +
+
+
+ + Total Value Accrued + + + {formatUSD(totalValue)} + +
+
+ +
+ + Progress to {lowestTier?.name || 'next tier'} + {progressPercentage} + + + + Deposit TST to start earning rewards + +
+
+
+
+ ) + } + + return ( + +
+ + TST Staking + + + + Participate in protocol governance + + + {/*
*/} +
+
+
+ + Total TST Staked + + + {stakedAmount} TST + +
+
+
+
+ + Historical APY + + + + + + {apyDisplay} + +
+
+ {/*
+
+ + Your Pool Share + + + + + + {stakeRatio} + +
+
*/} + +
+ +
+
+
+ + Your Daily Earnings + + + {formatUSD(dailyEarnings)} + +
+ + Earning {formatUSD(monthlyProjection)} monthly at current rates + +
+
+ +
+
+
+
+ {currentTier?.icon} +
+
+ + Current Status + + + {currentTier.name || ( + + )} + + + Staking since {stakedSince} + +
+
+
+ + Total Value Accrued + + + {formatUSD(totalValue)} + + + Current market prices + +
+
+ +
+ + Progress to {nextTier?.name || 'next tier'} + {progressPercentage} + + + + {currentTier?.tier == 1 ? ( + <> + You've staked {stakedAmount} TST! + + ) : ( + <> + Stake {tierRemaining} more TST to reach the next tier + + )} + +
+
+ +
+ + +
+ + +
+ + ) +}; + +export default StakingSummary; diff --git a/src/components/ui/Notifications.jsx b/src/components/ui/Notifications.jsx index c9948e1..301e1dd 100644 --- a/src/components/ui/Notifications.jsx +++ b/src/components/ui/Notifications.jsx @@ -56,9 +56,9 @@ const Notifications = (props) => { >
{hasUnread ? ( - - - + + + ) : null} diff --git a/src/components/vault/BorrowModal.jsx b/src/components/vault/BorrowModal.jsx index 32f38f5..03b34ad 100644 --- a/src/components/vault/BorrowModal.jsx +++ b/src/components/vault/BorrowModal.jsx @@ -101,7 +101,7 @@ const BorrowModal = (props) => { // //
- //
OR
+ //
OR
//
// { return (
-
+
+ ) : ( Number(ethers.formatEther(minted)).toFixed(2) ) @@ -146,7 +146,7 @@ const VaultStats = ({ title: "Balance", value: ( currentVaultLoading ? ( - + ) : ( currencySymbol + Number( ethers.formatEther(totalCollateralValue) @@ -161,7 +161,7 @@ const VaultStats = ({ title: "Global Borrow Limit", value: ( isLoadingSupplyLimit || isLoadingTotalSupply ? ( - + ) : ( Number(ethers.formatEther(availableSupply)).toFixed(2) ) @@ -175,13 +175,13 @@ const VaultStats = ({ value: ( vaultType === 'USDs' ? ( currentVaultLoading || isLoadingSupplyLimit || isLoadingTotalSupply ? ( - + ) : ( Number(maxBorrow).toFixed(2) ) ) : ( currentVaultLoading ? ( - + ) : ( Number(maxBorrow).toFixed(2) ) @@ -209,14 +209,14 @@ const VaultStats = ({ {item.title} {item.tooltip ? ( - - + className="flex-col justify-center items-center cursor-pointer before:w-[12rem]" + position="top" + message={item.tooltip} + > + + ) : (null)}
diff --git a/src/components/vault/yield/YieldList.jsx b/src/components/vault/yield/YieldList.jsx index f9e154b..9b9362f 100644 --- a/src/components/vault/yield/YieldList.jsx +++ b/src/components/vault/yield/YieldList.jsx @@ -149,7 +149,7 @@ const YieldList = (props) => { {gammaReturnsLoading ? ( <> - + ) : ( <> @@ -160,7 +160,7 @@ const YieldList = (props) => { {gammaUserLoading ? ( <> - + ) : ( <> diff --git a/src/components/vault/yield/YieldPerformanceModal.jsx b/src/components/vault/yield/YieldPerformanceModal.jsx index 56280a0..353ba72 100644 --- a/src/components/vault/yield/YieldPerformanceModal.jsx +++ b/src/components/vault/yield/YieldPerformanceModal.jsx @@ -151,7 +151,7 @@ const YieldPerformanceModal = ({ {gammaStatsLoading ? ( <> - + ) : ( <> @@ -167,7 +167,7 @@ const YieldPerformanceModal = ({ {gammaReturnsLoading ? ( <> - + ) : ( <> diff --git a/src/components/vault/yield/YieldSummary.jsx b/src/components/vault/yield/YieldSummary.jsx index a443bbc..b0a9d21 100644 --- a/src/components/vault/yield/YieldSummary.jsx +++ b/src/components/vault/yield/YieldSummary.jsx @@ -159,7 +159,7 @@ const YieldSummary = ({
{gammaUserLoading ? ( <> - + ) : ( <> @@ -186,7 +186,7 @@ const YieldSummary = ({
{gammaUserLoading ? ( <> - + ) : ( <> @@ -212,7 +212,7 @@ const YieldSummary = ({ {gammaUserLoading ? ( <> - + ) : ( <> diff --git a/src/components/vault/yield/YieldViewModal.jsx b/src/components/vault/yield/YieldViewModal.jsx index 6a37601..3d1c45a 100644 --- a/src/components/vault/yield/YieldViewModal.jsx +++ b/src/components/vault/yield/YieldViewModal.jsx @@ -83,7 +83,7 @@ const YieldViewModal = ({ {gammaStatsLoading ? ( <> - + ) : ( <> @@ -99,7 +99,7 @@ const YieldViewModal = ({ {gammaReturnsLoading ? ( <> - + ) : ( <> @@ -129,7 +129,7 @@ const YieldViewModal = ({ {gammaUserLoading ? ( <> - + ) : ( <> @@ -154,7 +154,7 @@ const YieldViewModal = ({ {gammaUserLoading ? ( <> - + ) : ( <> @@ -181,7 +181,7 @@ const YieldViewModal = ({ {gammaUserLoading ? ( <> - + ) : ( <> @@ -224,7 +224,7 @@ const YieldViewModal = ({ {gammaUserLoading ? ( <> - + ) : ( <> @@ -270,7 +270,7 @@ const YieldViewModal = ({ {gammaUserLoading ? ( <> - + ) : ( <> diff --git a/src/pages/tst-staking/TstStaking.jsx b/src/pages/tst-staking/TstStaking.jsx index 1185a38..29b1f54 100644 --- a/src/pages/tst-staking/TstStaking.jsx +++ b/src/pages/tst-staking/TstStaking.jsx @@ -1,6 +1,7 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import moment from 'moment'; +import axios from "axios"; import { useReadContract, useAccount, @@ -60,7 +61,7 @@ const TstStaking = (props) => { args: [address], }); - const { data: dailyYield, refetch: refetchDailyReward } = useReadContract({ + const { data: dailyYield, isLoading, dailyYieldLoading, refetch: refetchDailyReward } = useReadContract({ address: stakingPoolv3Address, abi: stakingPoolv3Abi, functionName: "dailyYield", @@ -75,6 +76,31 @@ const TstStaking = (props) => { }, }) + const [priceData, setPriceData] = useState(undefined); + const [priceDataLoading, setPriceDataLoading] = useState(true); + + const getPriceData = async () => { + try { + setPriceDataLoading(true); + const response = await axios.get( + "https://smart-vault-api.thestandard.io/asset_prices" + ); + const chainData = + chainId === arbitrumSepolia.id + ? response.data.arbitrum_sepolia + : response.data.arbitrum; + setPriceData(chainData); + setPriceDataLoading(false); + } catch (error) { + console.log(error); + setPriceDataLoading(false); + } + }; + + useEffect(() => { + getPriceData(); + }, []); + const positions = poolPositions; const rewards = poolRewards; const dailyRewards = dailyYield; @@ -103,31 +129,27 @@ const TstStaking = (props) => { return ( <> - -
- - - Staking Pool - +
+
+ +
+ + + Staking Pool + - - Stake TST to earn USDs & more tokens daily. - + + Stake TST to earn USDs & more tokens daily. + - - If you're looking for our previous staking pools, navigate("/legacy-pools")}>they can be found here. - + + If you're looking for our previous staking pools, navigate("/legacy-pools")}>they can be found here. + -
-
+
+ -
- -
-
- -
@@ -139,18 +161,21 @@ const TstStaking = (props) => { ) : ( )}
-
- ); }; From 556a6a9236980e28946fc6314ad37fadf164d47e Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 15:16:30 +0000 Subject: [PATCH 04/14] chore: code cleanup --- src/components/tst-staking/StakingAssets.jsx | 107 ------------------ .../tst-staking/StakingIncrease.jsx | 9 -- src/components/tst-staking/StakingRewards.jsx | 23 ---- .../tst-staking/StakingShareModal.jsx | 1 - src/components/tst-staking/StakingSummary.jsx | 5 - src/pages/tst-staking/TstStaking.jsx | 50 ++++---- 6 files changed, 27 insertions(+), 168 deletions(-) delete mode 100644 src/components/tst-staking/StakingAssets.jsx diff --git a/src/components/tst-staking/StakingAssets.jsx b/src/components/tst-staking/StakingAssets.jsx deleted file mode 100644 index 0f52f86..0000000 --- a/src/components/tst-staking/StakingAssets.jsx +++ /dev/null @@ -1,107 +0,0 @@ -import { useState } from "react"; - -import { ethers } from "ethers"; - -import Button from "../ui/Button"; -import Card from "../ui/Card"; -import Typography from "../ui/Typography"; -import CenterLoader from "../ui/CenterLoader"; - -import StakingDecreaseModal from "./StakingDecreaseModal"; - -const StakingAssets = ({ - positions, -}) => { - const [open, setOpen] = useState(false); - - if (!positions) { - return ( - -
- -
-
- ) - } - - const tstAmount = positions[1] || 0; - - const useRows = [ - { - asset: 'TST', - amount: tstAmount || 0 - }, - ] - - const handleCloseModal = () => { - setOpen(false) - }; - - const rows = useRows || []; - - let noStaked = true; - if (rows.some(e => e.amount > 0)) { - noStaked = false; - } - - return ( - -
- - Staked Assets - - -
- - - - - - - - {!positions ? (null) : ( - - {rows.map(function(asset, index) { - const amount = asset?.amount; - const decimals = asset?.dec; - const symbol = asset?.asset; - - return( - - - - - )} - )} - - )} -
AssetAmount
- {symbol} - - {ethers.formatUnits(amount, decimals)} -
- {!positions ? ( - - ) : (null)} -
- -
- -
- -
-
- ) -}; - -export default StakingAssets; diff --git a/src/components/tst-staking/StakingIncrease.jsx b/src/components/tst-staking/StakingIncrease.jsx index e4684db..6af51b0 100644 --- a/src/components/tst-staking/StakingIncrease.jsx +++ b/src/components/tst-staking/StakingIncrease.jsx @@ -14,7 +14,6 @@ import { ethers } from "ethers"; import { useTstAddressStore, useErc20AbiStore, - usesEuroAddressStore, useStakingPoolv3AbiStore, useStakingPoolv3AddressStore, } from "../../store/Store.jsx"; @@ -30,10 +29,6 @@ const StakingIncrease = () => { arbitrumTstAddress, arbitrumSepoliaTstAddress, } = useTstAddressStore(); - const { - arbitrumsEuroAddress, - arbitrumSepoliasEuroAddress, - } = usesEuroAddressStore(); const { arbitrumSepoliaStakingPoolv3Address, arbitrumStakingPoolv3Address, @@ -43,7 +38,6 @@ const StakingIncrease = () => { const { stakingPoolv3Abi } = useStakingPoolv3AbiStore(); const [tstStakeAmount, setTstStakeAmount] = useState(0); const [stage, setStage] = useState(''); - const [helpOpen, setHelpOpen] = useState(false); const tstInputRef = useRef(null); @@ -197,9 +191,6 @@ const StakingIncrease = () => { Depositing will automatically claim your existing rewards, ending your current staking period and restarting a new one.
- {/* - TST Deposit Amount - */}
{ const { erc20Abi } = useErc20AbiStore(); - if (poolRewardsLoading || dailyYieldLoading || priceDataLoading) { - return ( - <> - -
- -
-
- -
- -
-
- - ) - } - const { data: rewardDecimals } = useReadContracts({ contracts:collaterals.map((item) =>({ address: item.token, @@ -102,7 +80,6 @@ const StakingRewards = ({ for (const [token, tokenData] of Object.entries(priceData)) { if (tokenData.prices && tokenData.prices.length > 0) { const latestPrice = tokenData.prices[tokenData.prices.length - 1].price; - // Convert price to USD considering decimals prices[token] = parseFloat(latestPrice) / 1000000; } } diff --git a/src/components/tst-staking/StakingShareModal.jsx b/src/components/tst-staking/StakingShareModal.jsx index 1a22559..3be2eac 100644 --- a/src/components/tst-staking/StakingShareModal.jsx +++ b/src/components/tst-staking/StakingShareModal.jsx @@ -1,4 +1,3 @@ -import { useState, useEffect, useRef } from "react"; import { toast } from 'react-toastify'; import { diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx index 96185a0..00bd5d9 100644 --- a/src/components/tst-staking/StakingSummary.jsx +++ b/src/components/tst-staking/StakingSummary.jsx @@ -150,14 +150,9 @@ const formatUSD = (value) => { const StakingSummary = ({ positions, - poolRewardsLoading, - dailyYieldLoading, - rewards, rewardsData, - collaterals, stakedSince, rawStakedSince, - collatDaily, latestPrices, }) => { const [open, setOpen] = useState(false); diff --git a/src/pages/tst-staking/TstStaking.jsx b/src/pages/tst-staking/TstStaking.jsx index 29b1f54..0e2d4c6 100644 --- a/src/pages/tst-staking/TstStaking.jsx +++ b/src/pages/tst-staking/TstStaking.jsx @@ -10,8 +10,6 @@ import { } from "wagmi"; import { arbitrumSepolia } from "wagmi/chains"; import { - ArrowTrendingUpIcon, - BanknotesIcon, Square3Stack3DIcon, } from '@heroicons/react/24/outline'; @@ -21,17 +19,14 @@ import { } from "../../store/Store"; import StakingIncrease from "../../components/tst-staking/StakingIncrease"; -import StakingAssets from "../../components/tst-staking/StakingAssets"; import StakingRewards from "../../components/tst-staking/StakingRewards"; import Card from "../../components/ui/Card"; import CenterLoader from "../../components/ui/CenterLoader"; import Typography from "../../components/ui/Typography"; -import Button from "../../components/ui/Button"; const TstStaking = (props) => { const { stakingPoolv3Abi } = useStakingPoolv3AbiStore(); - const [showValue, setShowValue] = useState(false); const navigate = useNavigate(); const { @@ -153,25 +148,34 @@ const TstStaking = (props) => {
- {poolRewardsLoading ? ( - -
- -
-
+ {poolRewardsLoading || dailyYieldLoading || priceDataLoading ? ( + <> + +
+ +
+
+ +
+ +
+
+ ) : ( - + <> + + )}
From 03456f565b1d865d7b4c7fcc57e3589adfdc457a Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 15:26:20 +0000 Subject: [PATCH 05/14] feat: add usdval to reward list and convert prices to dollar val from penny val --- src/components/tst-staking/StakingRewards.jsx | 3 +- .../tst-staking/StakingRewardsList.jsx | 34 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/components/tst-staking/StakingRewards.jsx b/src/components/tst-staking/StakingRewards.jsx index 07545fe..37120af 100644 --- a/src/components/tst-staking/StakingRewards.jsx +++ b/src/components/tst-staking/StakingRewards.jsx @@ -80,7 +80,8 @@ const StakingRewards = ({ for (const [token, tokenData] of Object.entries(priceData)) { if (tokenData.prices && tokenData.prices.length > 0) { const latestPrice = tokenData.prices[tokenData.prices.length - 1].price; - prices[token] = parseFloat(latestPrice) / 1000000; + // convert to dollar value + prices[token] = parseFloat(latestPrice) / 100000000; } } return prices; diff --git a/src/components/tst-staking/StakingRewardsList.jsx b/src/components/tst-staking/StakingRewardsList.jsx index 9657f26..29b3326 100644 --- a/src/components/tst-staking/StakingRewardsList.jsx +++ b/src/components/tst-staking/StakingRewardsList.jsx @@ -8,10 +8,22 @@ import CenterLoader from "../ui/CenterLoader"; import ClaimingRewardsModal from "./ClaimingRewardsModal"; +const formatUSD = (value) => { + if (value >= 0) { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }).format(Math.abs(value)); + } +}; + const StakingRewardsList = ({ stakedSince, poolRewardsLoading, rewardData, + latestPrices, }) => { const [open, setOpen] = useState(false); @@ -29,13 +41,25 @@ const StakingRewardsList = ({ setOpen(false) }; - const rows = rewardData || []; + const rewardsWithPrices = rewardData.map(reward => { + const price = latestPrices[reward.asset] || 1; // Default to 1 for stablecoins + const usdValue = parseFloat(reward.amount) * price; + return { + ...reward, + usdValue: usdValue, + price: price + }; + }) + + const rows = rewardsWithPrices || []; let noRewards = true; if (rows.some(e => e.amount > 0)) { noRewards = false; } + console.log(123213, {rewardsWithPrices}, {latestPrices}) + return (
@@ -63,7 +87,8 @@ const StakingRewardsList = ({ Asset Amount - Daily Reward Per Token + Value (USD) + Daily Rate Per TST {poolRewardsLoading ? (null) : ( @@ -73,6 +98,7 @@ const StakingRewardsList = ({ const decimals = asset?.decimals; const symbol = asset?.asset; const dailyReward = asset?.dailyReward || 0n; + const value = asset?.usdValue || 0; return( @@ -82,9 +108,11 @@ const StakingRewardsList = ({ {ethers.formatUnits(amount, decimals)} + + {formatUSD(value)} + {ethers.formatUnits(dailyReward, decimals)} - / TST )} From 74e4b8c9e387779debb60c2bc574d8eae0625320 Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 15:26:50 +0000 Subject: [PATCH 06/14] chore: remove console log --- src/components/tst-staking/StakingRewardsList.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/tst-staking/StakingRewardsList.jsx b/src/components/tst-staking/StakingRewardsList.jsx index 29b3326..0b1b767 100644 --- a/src/components/tst-staking/StakingRewardsList.jsx +++ b/src/components/tst-staking/StakingRewardsList.jsx @@ -58,8 +58,6 @@ const StakingRewardsList = ({ noRewards = false; } - console.log(123213, {rewardsWithPrices}, {latestPrices}) - return (
From d96537ee98755adf1f7a57317bb7ee0ca5d97e6a Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 15:58:32 +0000 Subject: [PATCH 07/14] fix: fix token quantity decimals --- src/components/tst-staking/StakingRewards.jsx | 2 ++ src/components/tst-staking/StakingRewardsList.jsx | 4 +++- src/components/tst-staking/StakingSummary.jsx | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/tst-staking/StakingRewards.jsx b/src/components/tst-staking/StakingRewards.jsx index 37120af..4673922 100644 --- a/src/components/tst-staking/StakingRewards.jsx +++ b/src/components/tst-staking/StakingRewards.jsx @@ -89,6 +89,8 @@ const StakingRewards = ({ const latestPrices = handleDailyPrices(); + console.log(10101, rewardData) + return (
{ + const useAmount = ethers.formatUnits(reward.amount, reward.decimals); const price = latestPrices[reward.asset] || 1; // Default to 1 for stablecoins - const usdValue = parseFloat(reward.amount) * price; + const usdValue = parseFloat(useAmount) * price; return { ...reward, usdValue: usdValue, @@ -58,6 +59,7 @@ const StakingRewardsList = ({ noRewards = false; } + return (
diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx index 00bd5d9..1c9582c 100644 --- a/src/components/tst-staking/StakingSummary.jsx +++ b/src/components/tst-staking/StakingSummary.jsx @@ -225,8 +225,9 @@ const StakingSummary = ({ } const rewardsWithPrices = rewardsData.map(reward => { + const useAmount = ethers.formatUnits(reward.amount, reward.decimals); const price = latestPrices[reward.asset] || 1; // Default to 1 for stablecoins - const usdValue = parseFloat(reward.amount) * price; + const usdValue = parseFloat(useAmount) * price; return { ...reward, usdValue: usdValue, From a1de29fdd41c9b195a57e1e0dde15acd2970b6d8 Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 15:58:59 +0000 Subject: [PATCH 08/14] chore: remove console log --- src/components/tst-staking/StakingRewards.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/tst-staking/StakingRewards.jsx b/src/components/tst-staking/StakingRewards.jsx index 4673922..37120af 100644 --- a/src/components/tst-staking/StakingRewards.jsx +++ b/src/components/tst-staking/StakingRewards.jsx @@ -89,8 +89,6 @@ const StakingRewards = ({ const latestPrices = handleDailyPrices(); - console.log(10101, rewardData) - return (
Date: Fri, 8 Nov 2024 15:59:53 +0000 Subject: [PATCH 09/14] chore: remove console log --- src/components/tst-staking/StakingSummary.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx index 1c9582c..500639a 100644 --- a/src/components/tst-staking/StakingSummary.jsx +++ b/src/components/tst-staking/StakingSummary.jsx @@ -127,7 +127,6 @@ const STATUS_TIERS = [ iconColor: 'text-gray-600' } ]; - const formatNumber = (number, decimals = 2) => { if (typeof number === 'string') number = parseFloat(number); From 13b9bf746b3363189fa63e6041d0a782a711bf7b Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 16:16:58 +0000 Subject: [PATCH 10/14] fix: fix days since --- src/components/tst-staking/StakingSummary.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx index 500639a..4dda213 100644 --- a/src/components/tst-staking/StakingSummary.jsx +++ b/src/components/tst-staking/StakingSummary.jsx @@ -213,13 +213,14 @@ const StakingSummary = ({ function getDaysStaked() { const start = moment.unix((Number(rawStakedSince))); const today = moment(); - const testSince = start.diff(today, 'days')+1; - return testSince; + const since = today.diff(start, 'days'); + return since; } const calculateSimpleAPY = (stakedAmount, totalRewardsValue, daysStaked) => { const dailyEarnings = totalRewardsValue / daysStaked; const annualEarningsPerTST = (dailyEarnings * 365) / stakedAmount; + // console.log(123123, stakedAmount, totalRewardsValue, daysStaked) return annualEarningsPerTST * 100; } From 763e7ffa640c5d1972b047639196ccf8111a3fa3 Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 17:07:12 +0000 Subject: [PATCH 11/14] feat: fix rate maths and temp hide APY field --- .../tst-staking/StakingRewardsList.jsx | 30 +++++-------- src/components/tst-staking/StakingSummary.jsx | 45 ++++++++++++------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/components/tst-staking/StakingRewardsList.jsx b/src/components/tst-staking/StakingRewardsList.jsx index a58cc33..b012b1f 100644 --- a/src/components/tst-staking/StakingRewardsList.jsx +++ b/src/components/tst-staking/StakingRewardsList.jsx @@ -8,17 +8,6 @@ import CenterLoader from "../ui/CenterLoader"; import ClaimingRewardsModal from "./ClaimingRewardsModal"; -const formatUSD = (value) => { - if (value >= 0) { - return new Intl.NumberFormat('en-US', { - style: 'currency', - currency: 'USD', - minimumFractionDigits: 2, - maximumFractionDigits: 2 - }).format(Math.abs(value)); - } -}; - const StakingRewardsList = ({ stakedSince, poolRewardsLoading, @@ -43,15 +32,17 @@ const StakingRewardsList = ({ const rewardsWithPrices = rewardData.map(reward => { const useAmount = ethers.formatUnits(reward.amount, reward.decimals); + const useRate = ethers.formatUnits(reward.dailyReward, reward.decimals); const price = latestPrices[reward.asset] || 1; // Default to 1 for stablecoins const usdValue = parseFloat(useAmount) * price; + const usdRate = parseFloat(useRate) * price; return { ...reward, usdValue: usdValue, + usdRate: usdRate, price: price }; }) - const rows = rewardsWithPrices || []; let noRewards = true; @@ -87,7 +78,6 @@ const StakingRewardsList = ({ Asset Amount - Value (USD) Daily Rate Per TST @@ -99,6 +89,7 @@ const StakingRewardsList = ({ const symbol = asset?.asset; const dailyReward = asset?.dailyReward || 0n; const value = asset?.usdValue || 0; + const rate = asset?.usdRate || 0; return( @@ -106,13 +97,16 @@ const StakingRewardsList = ({ {symbol} - {ethers.formatUnits(amount, decimals)} + {ethers.formatUnits(amount, decimals)}
+ + ~${value.toFixed(8)} + - {formatUSD(value)} - - - {ethers.formatUnits(dailyReward, decimals)} + {ethers.formatUnits(dailyReward, decimals)}
+ + ~${rate.toFixed(8)} + )} diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx index 4dda213..3b9e2d0 100644 --- a/src/components/tst-staking/StakingSummary.jsx +++ b/src/components/tst-staking/StakingSummary.jsx @@ -211,34 +211,47 @@ const StakingSummary = ({ } function getDaysStaked() { - const start = moment.unix((Number(rawStakedSince))); + let start = moment.unix((Number(rawStakedSince))); const today = moment(); + if (!rawStakedSince) { + start = today; + } const since = today.diff(start, 'days'); return since; } + // const calculateSimpleAPY = (stakedAmount, totalRewardsValue, daysStaked) => { + // const dailyEarnings = Number(totalRewardsValue / daysStaked) || 0; + // const annualEarningsPerTST = (dailyEarnings * 365) / Number(stakedAmount) || 0; + // return annualEarningsPerTST * 100; + // } const calculateSimpleAPY = (stakedAmount, totalRewardsValue, daysStaked) => { - const dailyEarnings = totalRewardsValue / daysStaked; - const annualEarningsPerTST = (dailyEarnings * 365) / stakedAmount; - // console.log(123123, stakedAmount, totalRewardsValue, daysStaked) - return annualEarningsPerTST * 100; + const dailyEarnings = totalRewardsValue || 0; + const annualEarningsPerTST = (dailyEarnings * 365) / Number(stakedAmount) || 0; + + return annualEarningsPerTST; } const rewardsWithPrices = rewardsData.map(reward => { const useAmount = ethers.formatUnits(reward.amount, reward.decimals); + const useRate = ethers.formatUnits(reward.dailyReward, reward.decimals); const price = latestPrices[reward.asset] || 1; // Default to 1 for stablecoins const usdValue = parseFloat(useAmount) * price; + const usdRate = parseFloat(useRate) * price; return { ...reward, usdValue: usdValue, + usdRate: usdRate, price: price }; }) - const totalValue = rewardsWithPrices.reduce((sum, reward) => sum + reward.usdValue, 0) || 0; + + const totalValueUSD = rewardsWithPrices.reduce((sum, reward) => sum + reward.usdValue, 0) || 0; + const totalRateUSD = rewardsWithPrices.reduce((sum, reward) => sum + reward.usdRate, 0) || 0; const daysStaked = getDaysStaked() || 0; - const dailyEarnings = (totalValue / daysStaked) || 0; + const dailyEarnings = (totalRateUSD / daysStaked) || 0; const monthlyProjection = (dailyEarnings * 30) || 0; const currentTier = getCurrentTier(stakedAmount); @@ -248,7 +261,7 @@ const StakingSummary = ({ if (nextTier?.minAmount) { progress = (stakedAmount / nextTier.minAmount) * 100; } - const apyDisplay = calculateSimpleAPY(stakedAmount, totalValue, daysStaked) + '%' || '0%'; + const apyDisplay = calculateSimpleAPY(stakedAmount, totalRateUSD, daysStaked) + '%' || '0%'; let stakeRatio = 'TODO.DOTO'; @@ -275,7 +288,7 @@ const StakingSummary = ({ Participate in protocol governance -
+
@@ -286,7 +299,7 @@ const StakingSummary = ({
-
+ {/*
Historical APY @@ -304,7 +317,7 @@ const StakingSummary = ({ 0%
-
+
*/}
@@ -343,7 +356,7 @@ const StakingSummary = ({ Total Value Accrued - {formatUSD(totalValue)} + {formatUSD(totalValueUSD)}
@@ -381,7 +394,7 @@ const StakingSummary = ({ {/*
*/} -
+
@@ -392,7 +405,7 @@ const StakingSummary = ({
-
+ {/*
Historical APY @@ -410,7 +423,7 @@ const StakingSummary = ({ {apyDisplay}
-
+
*/} {/*
@@ -474,7 +487,7 @@ const StakingSummary = ({ Total Value Accrued - {formatUSD(totalValue)} + {formatUSD(totalValueUSD)} Current market prices From c00982b551584e19fce5a7e66748d53bb0b60e0d Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 17:10:24 +0000 Subject: [PATCH 12/14] style: make deposit button wider --- src/components/tst-staking/StakingIncrease.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/tst-staking/StakingIncrease.jsx b/src/components/tst-staking/StakingIncrease.jsx index 6af51b0..e42473c 100644 --- a/src/components/tst-staking/StakingIncrease.jsx +++ b/src/components/tst-staking/StakingIncrease.jsx @@ -229,6 +229,7 @@ const StakingIncrease = () => { loading={isPending} disabled={isPending || tstStakeAmount <= 0 } onClick={handleLetsStake} + className="w-full lg:w-1/2" > Deposit From 957398fd9275a6d874a0eba55283b12e3a5dab77 Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 17:11:21 +0000 Subject: [PATCH 13/14] style: reduce spacing --- src/components/tst-staking/StakingSummary.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx index 3b9e2d0..a299936 100644 --- a/src/components/tst-staking/StakingSummary.jsx +++ b/src/components/tst-staking/StakingSummary.jsx @@ -288,7 +288,7 @@ const StakingSummary = ({ Participate in protocol governance -
+
@@ -320,7 +320,7 @@ const StakingSummary = ({
*/}
-
+
From 6902be2247ecc4916940b4be351a66b82e1dd84e Mon Sep 17 00:00:00 2001 From: Zak Date: Fri, 8 Nov 2024 17:12:11 +0000 Subject: [PATCH 14/14] style: reduce spacing --- src/components/tst-staking/StakingSummary.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/tst-staking/StakingSummary.jsx b/src/components/tst-staking/StakingSummary.jsx index a299936..6382851 100644 --- a/src/components/tst-staking/StakingSummary.jsx +++ b/src/components/tst-staking/StakingSummary.jsx @@ -393,7 +393,7 @@ const StakingSummary = ({ Participate in protocol governance - {/*
*/} + {/*
*/}