diff --git a/.env b/.env new file mode 100644 index 0000000..257408a --- /dev/null +++ b/.env @@ -0,0 +1 @@ +NEXT_PUBLIC_RPC=http://localhost:8545 \ No newline at end of file diff --git a/abis/StakingVault.ts b/abis/StakingVault.ts new file mode 100644 index 0000000..007e642 --- /dev/null +++ b/abis/StakingVault.ts @@ -0,0 +1,463 @@ +export default [ + { + type: 'constructor', + inputs: [ + { name: '_name', type: 'string', internalType: 'string' }, + { name: '_symbol', type: 'string', internalType: 'string' }, + { name: '_underlying', type: 'address', internalType: 'contract IERC20' }, + { name: '_distributionPeriod', type: 'uint256', internalType: 'uint256' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'DISTRIBUTION_PERIOD', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'addRewards', + inputs: [{ name: '_amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'allowance', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'spender', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'approve', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'asset', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'balanceOf', + inputs: [{ name: 'account', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'convertToAssets', + inputs: [{ name: 'shares', type: 'uint256', internalType: 'uint256' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'convertToShares', + inputs: [{ name: 'assets', type: 'uint256', internalType: 'uint256' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'deposit', + inputs: [ + { name: 'assets', type: 'uint256', internalType: 'uint256' }, + { name: 'receiver', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'maxDeposit', + inputs: [{ name: '', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'maxMint', + inputs: [{ name: '', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'maxRedeem', + inputs: [{ name: 'owner', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'maxWithdraw', + inputs: [{ name: 'owner', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'mint', + inputs: [ + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { name: 'receiver', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewDeposit', + inputs: [{ name: 'assets', type: 'uint256', internalType: 'uint256' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewMint', + inputs: [{ name: 'shares', type: 'uint256', internalType: 'uint256' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewRedeem', + inputs: [{ name: 'shares', type: 'uint256', internalType: 'uint256' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewWithdraw', + inputs: [{ name: 'assets', type: 'uint256', internalType: 'uint256' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'redeem', + inputs: [ + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { name: 'receiver', type: 'address', internalType: 'address' }, + { name: 'owner', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'rewardTracker', + inputs: [], + outputs: [ + { name: 'rewardPeriodStart', type: 'uint256', internalType: 'uint256' }, + { name: 'rewardPeriodEnd', type: 'uint256', internalType: 'uint256' }, + { name: 'rewardAmount', type: 'uint256', internalType: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalAssets', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transfer', + inputs: [ + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferFrom', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'withdraw', + inputs: [ + { name: 'assets', type: 'uint256', internalType: 'uint256' }, + { name: 'receiver', type: 'address', internalType: 'address' }, + { name: 'owner', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'Approval', + inputs: [ + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Deposit', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'assets', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'shares', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RewardDistributionUpdated', + inputs: [ + { + name: 'periodStart', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'periodEnd', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { name: 'from', type: 'address', indexed: true, internalType: 'address' }, + { name: 'to', type: 'address', indexed: true, internalType: 'address' }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Withdraw', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'receiver', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'assets', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'shares', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'AddressEmptyCode', + inputs: [{ name: 'target', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'AddressInsufficientBalance', + inputs: [{ name: 'account', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC20InsufficientAllowance', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'allowance', type: 'uint256', internalType: 'uint256' }, + { name: 'needed', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'ERC20InsufficientBalance', + inputs: [ + { name: 'sender', type: 'address', internalType: 'address' }, + { name: 'balance', type: 'uint256', internalType: 'uint256' }, + { name: 'needed', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'ERC20InvalidApprover', + inputs: [{ name: 'approver', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC20InvalidReceiver', + inputs: [{ name: 'receiver', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC20InvalidSender', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC20InvalidSpender', + inputs: [{ name: 'spender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC4626ExceededMaxDeposit', + inputs: [ + { name: 'receiver', type: 'address', internalType: 'address' }, + { name: 'assets', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'ERC4626ExceededMaxMint', + inputs: [ + { name: 'receiver', type: 'address', internalType: 'address' }, + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'ERC4626ExceededMaxRedeem', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'ERC4626ExceededMaxWithdraw', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'assets', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { type: 'error', name: 'FailedInnerCall', inputs: [] }, + { type: 'error', name: 'MathOverflowedMulDiv', inputs: [] }, + { + type: 'error', + name: 'SafeERC20FailedOperation', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, +] as const diff --git a/components/staking/atoms.ts b/components/staking/atoms.ts index f985517..22e44ad 100644 --- a/components/staking/atoms.ts +++ b/components/staking/atoms.ts @@ -1,16 +1,16 @@ import { atom } from 'jotai' import { parseUnits } from 'viem' import { STAKE_TOKEN, TOKEN } from './constants' +import { + balanceAtom, + priceAtom, + stakeBalanceAtom, + stakeRateAtom, +} from '../../views/app/state/atoms' // General state atoms -export const priceAtom = atom(0) -export const stakeRateAtom = atom(0) -export const balanceAtom = atom({ value: 0n, formatted: '0' }) -export const stakeBalanceAtom = atom({ value: 0n, formatted: '0' }) export const isStakingAtom = atom(false) -export const tokenSupplyAtom = atom(0) -export const stakeTokenSupplyAtom = atom(0) -// + // Prevents more than 18 decimals export function safeParseEther(value: string, decimals = 18): bigint { let safeValue = '' diff --git a/components/staking/components/stake/ActionOverview.tsx b/components/staking/components/stake/ActionOverview.tsx index ca57263..e16f9ca 100644 --- a/components/staking/components/stake/ActionOverview.tsx +++ b/components/staking/components/stake/ActionOverview.tsx @@ -2,8 +2,8 @@ import { Box, BoxProps, Spinner, Text } from 'theme-ui' import GasIcon from '../../../zap/components/icons/GasIcon' import { formatCurrency } from '../../../zap/utils' import { useAtomValue } from 'jotai' -import { stakeRateAtom } from '../../atoms' import { STAKE_TOKEN, TOKEN } from '../../constants' +import { stakeRateAtom } from '../../../../views/app/state/atoms' interface IGasEstimate extends BoxProps { total: number @@ -40,7 +40,7 @@ const ExchangeRate = () => { return ( - 1 {STAKE_TOKEN.symbol} = {formatCurrency(rate, 5)} {TOKEN.symbol} + 1 {TOKEN.symbol} = {formatCurrency(rate, 5)} {STAKE_TOKEN.symbol} ) diff --git a/components/staking/components/stake/StakeInput.tsx b/components/staking/components/stake/StakeInput.tsx index 8a2a920..98f2764 100644 --- a/components/staking/components/stake/StakeInput.tsx +++ b/components/staking/components/stake/StakeInput.tsx @@ -8,12 +8,12 @@ import { borderRadius } from '../../../zap/theme' import { formatCurrency } from '../../../zap/utils' import { isStakingAtom, - priceAtom, stakeAmountAtom, tokenInAtom, tokenInBalance, } from '../../atoms' import InputPostfix from './InputPostfix' +import { priceAtom } from '../../../../views/app/state/atoms' const StakeInputField = () => { const [amount, setAmount] = useAtom(stakeAmountAtom) diff --git a/components/staking/components/stake/StakeOutput.tsx b/components/staking/components/stake/StakeOutput.tsx index 299ecae..9c49d60 100644 --- a/components/staking/components/stake/StakeOutput.tsx +++ b/components/staking/components/stake/StakeOutput.tsx @@ -1,7 +1,6 @@ import { useAtomValue } from 'jotai' import { stakeAmountUsdAtom, - stakeBalanceAtom, stakeOutputAtom, tokenOutAtom, tokenOutBalance, diff --git a/components/staking/constants.ts b/components/staking/constants.ts index aae2c41..1bdb253 100644 --- a/components/staking/constants.ts +++ b/components/staking/constants.ts @@ -9,7 +9,7 @@ interface IToken { } export const TOKEN: IToken = { - address: '0x', + address: '0x320623b8E4fF03373931769A31Fc52A4E78B5d70', // TODO: Change symbol: 'dgnETH', name: 'degenETH', decimals: 18, @@ -17,9 +17,9 @@ export const TOKEN: IToken = { } export const STAKE_TOKEN: IToken = { - address: '0x', + address: '0xD73bAb8F06DB28c87932571f87D0D2C0FDF13D94', // TODO: Change symbol: 'sdgnETH', name: 'staked degenETH', - decimals: 18, + decimals: 21, logo: '/svgs/dgneth.svg', } diff --git a/pages/_app.tsx b/pages/_app.tsx index 185966a..c926ad7 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -9,7 +9,7 @@ import { } from '@rainbow-me/rainbowkit' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { ThemeUIProvider } from 'theme-ui' -import { WagmiProvider } from 'wagmi' +import { WagmiProvider, http } from 'wagmi' import { mainnet } from 'wagmi/chains' import { theme } from '../components/zap/theme' @@ -17,9 +17,16 @@ const config = getDefaultConfig({ appName: 'degenETH Interface', projectId: 'YOUR_PROJECT_ID', chains: [mainnet], - ssr: true + transports: process.env.NEXT_PUBLIC_RPC + ? { + [mainnet.id]: http(process.env.NEXT_PUBLIC_RPC), + } + : undefined, + ssr: true, }) +console.log('config', config) + const client = new QueryClient() function MyApp({ Component, pageProps }: AppProps) { diff --git a/views/app/components/Balances.tsx b/views/app/components/Balances.tsx index 5a00b22..bc00c8d 100644 --- a/views/app/components/Balances.tsx +++ b/views/app/components/Balances.tsx @@ -1,16 +1,20 @@ import { useAtomValue } from 'jotai' import { Box, Card, Flex, Text } from 'theme-ui' +import { formatCurrency } from '../../../components/zap/utils' import { balanceAtom, priceAtom, + rTokenTargetPriceAtom, stakeBalanceAtom, -} from '../../../components/staking/atoms' -import { formatCurrency } from '../../../components/zap/utils' + stakeRateAtom, +} from '../state/atoms' const Balances = () => { const balance = useAtomValue(balanceAtom) const stakeBalance = useAtomValue(stakeBalanceAtom) const price = useAtomValue(priceAtom) + const rate = useAtomValue(stakeRateAtom) + const peg = useAtomValue(rTokenTargetPriceAtom) return ( @@ -27,17 +31,19 @@ const Balances = () => { {formatCurrency(+balance.formatted)} - 4.5 ETH + {formatCurrency(+balance.formatted * peg.price)} ETH Staked - $12K + + ${formatCurrency((+stakeBalance.formatted / rate) * price)} + {formatCurrency(+stakeBalance.formatted)} - 13 ETH + {formatCurrency((+stakeBalance.formatted / rate) * peg.price)} ETH diff --git a/views/app/components/StakingAPY.tsx b/views/app/components/StakingAPY.tsx index ddb327a..9d6cff7 100644 --- a/views/app/components/StakingAPY.tsx +++ b/views/app/components/StakingAPY.tsx @@ -6,7 +6,7 @@ const StakingAPY = () => { Staking APY 48% - 320% 30d avg + {/* 320% 30d avg */} ) diff --git a/views/app/index.tsx b/views/app/index.tsx index 683a8fc..491db4a 100644 --- a/views/app/index.tsx +++ b/views/app/index.tsx @@ -14,6 +14,9 @@ import StakingAPY from './components/StakingAPY' import Supply from './components/Supply' import { isStakingAtom } from './state/atoms' import YieldCalculator from './components/YieldCalculator' +import { useReadContract } from 'wagmi' +import StakingVault from '../../abis/StakingVault' +import { formatUnits, parseUnits } from 'viem' const IssuanceContainer = () => ( ( ) +const Test = () => { + const data = useReadContract({ + address: '0xbc71f5687cfd36f64ae6b4549186ee3a6ee259a4', + abi: StakingVault, + functionName: 'previewDeposit', + args: [parseUnits('1', 6)], + }) + + console.log('data', data?.data) + + return null +} + const App: NextPage = () => ( +
diff --git a/views/app/state/Updater.tsx b/views/app/state/Updater.tsx index 770a1eb..aadfdde 100644 --- a/views/app/state/Updater.tsx +++ b/views/app/state/Updater.tsx @@ -1,14 +1,40 @@ import { useSetAtom } from 'jotai' import { useEffect } from 'react' -import { erc20Abi, formatEther } from 'viem' -import { useAccount, useBlockNumber, useReadContracts } from 'wagmi' +import { erc20Abi, formatEther, formatUnits, parseEther } from 'viem' +import { + useAccount, + useBlockNumber, + useReadContract, + useReadContracts, +} from 'wagmi' +import { STAKE_TOKEN, TOKEN } from '../../../components/staking/constants' +import StakingVault from '../../../abis/StakingVault' import { balanceAtom, + basketsNeededAtom, + priceAtom, stakeBalanceAtom, + stakeRateAtom, stakeTokenSupplyAtom, tokenSupplyAtom, -} from '../../../components/staking/atoms' -import { STAKE_TOKEN, TOKEN } from '../../../components/staking/constants' +} from './atoms' +import FacadeRead from '../../../components/zap/abis/FacadeRead' + +const BasketsABI = [ + { + inputs: [], + name: 'basketsNeeded', + outputs: [ + { + internalType: 'uint192', + name: '', + type: 'uint192', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const const Updater = () => { // Setters @@ -16,6 +42,9 @@ const Updater = () => { const setStakeBalance = useSetAtom(stakeBalanceAtom) const setTokenSupply = useSetAtom(tokenSupplyAtom) const setStakeTokenSupply = useSetAtom(stakeTokenSupplyAtom) + const setExchangeRate = useSetAtom(stakeRateAtom) + const setPrice = useSetAtom(priceAtom) + const setBasketsNeeded = useSetAtom(basketsNeededAtom) // Getters const wallet = useAccount() const { data: blockNumber } = useBlockNumber({ watch: true }) @@ -53,6 +82,36 @@ const Updater = () => { ], allowFailure: false, }) + const { data: exchangeRate, refetch: refetchRate } = useReadContract({ + abi: StakingVault, + address: STAKE_TOKEN.address, + functionName: 'convertToShares', + args: [parseEther('1')], + }) + + const { data: price } = useReadContract({ + abi: FacadeRead, + address: '0x2815c24F49D5c5316Ffd0952dB0EFe68b0d5F132', + functionName: 'price', + args: [TOKEN.address], + }) + const { data: basketsNeeded } = useReadContract({ + abi: BasketsABI, + address: TOKEN.address, + functionName: 'basketsNeeded', + }) + + useEffect(() => { + if (price) { + setPrice(+formatEther(price[0] + price[1] / 2n)) + } + }, [price]) + + useEffect(() => { + if (basketsNeeded) { + setBasketsNeeded(Number(formatEther(basketsNeeded))) + } + }, [basketsNeeded]) useEffect(() => { if (balances) { @@ -64,6 +123,8 @@ const Updater = () => { } }, [balances]) + useEffect(() => {}, []) + useEffect(() => { if (supplies) { setTokenSupply(Number(formatEther(supplies[0]))) @@ -71,10 +132,17 @@ const Updater = () => { } }, [supplies]) + useEffect(() => { + if (exchangeRate) { + setExchangeRate(+formatUnits(exchangeRate, STAKE_TOKEN.decimals)) + } + }, [exchangeRate]) + // Refresh data on block useEffect(() => { refetchBalances() refetchSupply() + refetchRate() }, [blockNumber]) return null diff --git a/views/app/state/atoms.ts b/views/app/state/atoms.ts index 747564d..9d370db 100644 --- a/views/app/state/atoms.ts +++ b/views/app/state/atoms.ts @@ -2,3 +2,23 @@ import { atom } from 'jotai' export const isStakingAtom = atom(false) export const priceAtom = atom(0) +export const stakeRateAtom = atom(1) +export const balanceAtom = atom({ value: 0n, formatted: '0' }) +export const stakeBalanceAtom = atom({ value: 0n, formatted: '0' }) +export const tokenSupplyAtom = atom(0) +export const basketsNeededAtom = atom(0) +export const stakeTokenSupplyAtom = atom(0) + +export const rTokenTargetPriceAtom = atom((get) => { + const supply = get(tokenSupplyAtom) + const basketsNeeded = get(basketsNeededAtom) + + if (supply && basketsNeeded) { + let priceInUnit = Math.trunc((basketsNeeded / supply) * 10000) / 10000 + let supplyInUnit = supply * priceInUnit + + return { price: priceInUnit, supply: supplyInUnit } + } + + return { price: 0, supply: 0 } +})