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/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/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/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/StakingIncrease.jsx b/src/components/tst-staking/StakingIncrease.jsx index e4684db..e42473c 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 - */}
{ loading={isPending} disabled={isPending || tstStakeAmount <= 0 } onClick={handleLetsStake} + className="w-full lg:w-1/2" > Deposit diff --git a/src/components/tst-staking/StakingRewards.jsx b/src/components/tst-staking/StakingRewards.jsx index db0e00f..37120af 100644 --- a/src/components/tst-staking/StakingRewards.jsx +++ b/src/components/tst-staking/StakingRewards.jsx @@ -1,5 +1,3 @@ -import { useState } from "react"; -import { ethers } from "ethers"; import { useReadContracts, } from "wagmi"; @@ -8,32 +6,22 @@ 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, }) => { - const [open, setOpen] = useState(false); const { erc20Abi } = useErc20AbiStore(); - if (poolRewardsLoading) { - return ( - -
- -
-
- ) - } - const { data: rewardDecimals } = useReadContracts({ contracts:collaterals.map((item) =>({ address: item.token, @@ -87,93 +75,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 to dollar value + prices[token] = parseFloat(latestPrice) / 100000000; + } + } + 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} -
+ const latestPrices = handleDailyPrices(); -
- - - - - - - - - {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)} -
- -
- -
- -
-
+ return ( +
+ + +
) }; diff --git a/src/components/tst-staking/StakingRewardsList.jsx b/src/components/tst-staking/StakingRewardsList.jsx new file mode 100644 index 0000000..b012b1f --- /dev/null +++ b/src/components/tst-staking/StakingRewardsList.jsx @@ -0,0 +1,141 @@ +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, + latestPrices, +}) => { + const [open, setOpen] = useState(false); + + if (poolRewardsLoading) { + return ( + +
+ +
+
+ ) + } + + const handleCloseModal = () => { + setOpen(false) + }; + + 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; + 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; + const value = asset?.usdValue || 0; + const rate = asset?.usdRate || 0; + + return( + + + + + + )} + )} + + )} +
AssetAmountDaily Rate Per TST
+ {symbol} + + {ethers.formatUnits(amount, decimals)}
+ + ~${value.toFixed(8)} + +
+ {ethers.formatUnits(dailyReward, decimals)}
+ + ~${rate.toFixed(8)} + +
+ {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..3be2eac --- /dev/null +++ b/src/components/tst-staking/StakingShareModal.jsx @@ -0,0 +1,141 @@ +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..6382851 --- /dev/null +++ b/src/components/tst-staking/StakingSummary.jsx @@ -0,0 +1,557 @@ +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, + rewardsData, + stakedSince, + rawStakedSince, + 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() { + 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 || 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 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 = (totalRateUSD / 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, totalRateUSD, 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(totalValueUSD)} + +
+
+ +
+ + 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(totalValueUSD)} + + + 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/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/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 0d6c71f..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 ? ( <> - + ) : ( <> @@ -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..b0a9d21 100644 --- a/src/components/vault/yield/YieldSummary.jsx +++ b/src/components/vault/yield/YieldSummary.jsx @@ -148,82 +148,81 @@ const YieldSummary = ({
- - Assets in Yield Pools - - {gammaUserLoading ? ( - <> - - - ) : ( - <> - - {formatUSD(metrics.totalBalance)} - - - )} -
-
- - Yield Generated - -
+
+ + Market Movement + + + If held without yield pools + +
+
{gammaUserLoading ? ( <> - + ) : ( <> = 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 ? ( <> - + ) : ( <> = 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)} + + + )} +
-
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/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 diff --git a/src/pages/tst-staking/TstStaking.jsx b/src/pages/tst-staking/TstStaking.jsx index 1185a38..0e2d4c6 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, @@ -9,8 +10,6 @@ import { } from "wagmi"; import { arbitrumSepolia } from "wagmi/chains"; import { - ArrowTrendingUpIcon, - BanknotesIcon, Square3Stack3DIcon, } from '@heroicons/react/24/outline'; @@ -20,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 { @@ -60,7 +56,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 +71,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,54 +124,62 @@ 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. + -
-
+
+ -
- -
-
- -
- {poolRewardsLoading ? ( - -
- -
-
+ {poolRewardsLoading || dailyYieldLoading || priceDataLoading ? ( + <> + +
+ +
+
+ +
+ +
+
+ ) : ( - + <> + + )}
-
- ); };