diff --git a/app/components/Zap.tsx b/app/components/Zap.tsx index c2be333..85e5462 100644 --- a/app/components/Zap.tsx +++ b/app/components/Zap.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useMemo } from 'react'; +import { useState, useEffect } from 'react'; import { useAccount, useWriteContract, useWaitForTransactionReceipt, useContractRead } from 'wagmi'; import { parseUnits, formatUnits } from 'viem'; import { useDebounce } from 'use-debounce'; @@ -27,6 +27,45 @@ const OUTPUT_TOKENS = [ { address: '0xE9A115b77A1057C918F997c32663FdcE24FB873f', symbol: 'YBS' }, ]; +function useBalances(address: string | undefined) { + const balances = INPUT_TOKENS.map((token) => { + const { data: balance } = useContractRead({ + address: token.address as `0x${string}`, + abi: erc20Abi, + functionName: 'balanceOf', + args: [address as `0x${string}`], + }); + return { address: token.address, balance: balance ? formatUnits(balance, 18) : '0' }; + }); + + return balances.reduce((acc, { address, balance }) => ({ ...acc, [address]: balance }), {}); +} + +function useAllowance(address: string | undefined, inputToken: string, amount: string) { + const [isApproved, setIsApproved] = useState(false); + + const { data: allowance } = useContractRead(address ? { + address: inputToken as `0x${string}`, + abi: inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f' ? abis.YearnBoostedStaker : erc20Abi, + functionName: inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f' ? 'approvedCaller' : 'allowance', + args: inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f' + ? [address, '0x5271058928d31b6204fc95eee15fe9fbbdca681a'] + : [address, inputToken], + } : {}); + + console.log(address, inputToken, allowance) + + useEffect(() => { + if (inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f') { + setIsApproved(allowance === 3); + } else { + setIsApproved(Number(allowance) >= parseUnits(amount || '0', 18)); + } + }, [allowance, inputToken, amount]); + + return isApproved; +} + export default function Zap() { const { address } = useAccount(); const [inputToken, setInputToken] = useState(INPUT_TOKENS[0].address); @@ -34,8 +73,9 @@ export default function Zap() { const [amount, setAmount] = useState(''); const [debouncedAmount] = useDebounce(amount, 500); const [minOut, setMinOut] = useState('0'); - const [isApproved, setIsApproved] = useState(false); - const [balances, setBalances] = useState({}); + + const balances = useBalances(address); + const isApproved = useAllowance(address, inputToken, debouncedAmount); const { data: expectedOut } = useContractRead((!!debouncedAmount && !!inputToken && !!outputToken) ? { address: '0x5271058928d31b6204fc95eee15fe9fbbdca681a', @@ -47,7 +87,8 @@ export default function Zap() { useEffect(() => { if (expectedOut) { const allowableSlippage = 0.01; - setMinOut((Number(expectedOut) * (1 - allowableSlippage)).toString()); + const formattedExpectedOut = formatUnits(expectedOut, 18); + setMinOut((Number(formattedExpectedOut) * (1 - allowableSlippage)).toFixed(18)); } }, [expectedOut]); @@ -57,35 +98,18 @@ export default function Zap() { hash, }); - const { data: approvalStatus } = useContractRead(address ? { - address: inputToken as `0x${string}`, - abi: inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f' ? abis.YearnBoostedStaker : erc20Abi, - functionName: inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f' ? 'approvedCaller' : 'allowance', - args: inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f' - ? [address, '0x5271058928d31b6204fc95eee15fe9fbbdca681a'] - : [address, '0x5271058928d31b6204fc95eee15fe9fbbdca681a'], - } : {}); - - useEffect(() => { - if (inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f') { - setIsApproved(approvalStatus === 3); - } else { - setIsApproved(Number(approvalStatus) >= parseUnits(debouncedAmount, 18)); - } - }, [approvalStatus, inputToken, debouncedAmount]); - const { writeContract: approveContract } = useWriteContract(); - const handleApprove = () => { + const handleApprove = async () => { if (inputToken === '0xE9A115b77A1057C918F997c32663FdcE24FB873f') { - approveContract({ + const tx = await approveContract({ address: inputToken, abi: abis.YearnBoostedStaker, functionName: 'setApprovedCaller', args: ['0x5271058928d31b6204fc95eee15fe9fbbdca681a', 3], }); } else { - approveContract({ + const tx = await approveContract({ address: inputToken as `0x${string}`, abi: erc20Abi, functionName: 'approve', @@ -97,7 +121,7 @@ export default function Zap() { async function submit(e: React.FormEvent) { e.preventDefault(); if (!isApproved) { - handleApprove(); + await handleApprove(); } else { writeContract({ address: '0x5271058928d31b6204fc95eee15fe9fbbdca681a', @@ -120,25 +144,6 @@ export default function Zap() { } }, [inputToken]); - useEffect(() => { - const fetchBalances = async () => { - const balances = await Promise.all(INPUT_TOKENS.map(async (token) => { - const { data: balance } = await useContractRead({ - address: token.address as `0x${string}`, - abi: erc20Abi, - functionName: 'balanceOf', - args: [address as `0x${string}`], - }); - return { address: token.address, balance: balance ? formatUnits(balance, 18) : '0' }; - })); - setBalances(balances.reduce((acc, { address, balance }) => ({ ...acc, [address]: balance }), {})); - }; - - if (address) { - fetchBalances(); - } - }, [address]); - return (

Supercharge your yield with yCRV

@@ -184,7 +189,7 @@ export default function Zap() {