diff --git a/src/views/Lending/Cooler/hooks/useConsolidateCooler.tsx b/src/views/Lending/Cooler/hooks/useConsolidateCooler.tsx index a7b1c7136..1aa5dfb07 100644 --- a/src/views/Lending/Cooler/hooks/useConsolidateCooler.tsx +++ b/src/views/Lending/Cooler/hooks/useConsolidateCooler.tsx @@ -20,26 +20,41 @@ export const useConsolidateCooler = () => { fromClearingHouseAddress, toClearingHouseAddress, loanIds, + newOwner, }: { fromCoolerAddress: string; toCoolerAddress: string; fromClearingHouseAddress: string; toClearingHouseAddress: string; loanIds: number[]; + newOwner?: boolean; }) => { if (!signer) throw new Error(`Please connect a wallet`); const contractAddress = COOLER_CONSOLIDATION_CONTRACT.addresses[networks.MAINNET]; const contract = CoolerConsolidation__factory.connect(contractAddress, signer); - const cooler = await contract.consolidate( - fromClearingHouseAddress, - toClearingHouseAddress, - fromCoolerAddress, - toCoolerAddress, - loanIds, - { - gasLimit: loanIds.length <= 15 ? loanIds.length * 2000000 : 30000000, - }, - ); + + const cooler = newOwner + ? await contract.consolidateWithNewOwner( + fromClearingHouseAddress, + toClearingHouseAddress, + fromCoolerAddress, + toCoolerAddress, + loanIds, + { + gasLimit: loanIds.length <= 15 ? loanIds.length * 2000000 : 30000000, + }, + ) + : await contract.consolidate( + fromClearingHouseAddress, + toClearingHouseAddress, + fromCoolerAddress, + toCoolerAddress, + loanIds, + { + gasLimit: loanIds.length <= 15 ? loanIds.length * 2000000 : 30000000, + }, + ); + const receipt = await cooler.wait(); return receipt; }, diff --git a/src/views/Lending/Cooler/positions/ConsolidateLoan.tsx b/src/views/Lending/Cooler/positions/ConsolidateLoan.tsx index a58f2b277..4c0a1d0d7 100644 --- a/src/views/Lending/Cooler/positions/ConsolidateLoan.tsx +++ b/src/views/Lending/Cooler/positions/ConsolidateLoan.tsx @@ -1,4 +1,9 @@ +import { getAddress } from "@ethersproject/address"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { + Accordion, + AccordionDetails, + AccordionSummary, Box, Divider, FormControl, @@ -9,7 +14,7 @@ import { Tooltip, Typography, } from "@mui/material"; -import { InfoNotification, Modal, PrimaryButton } from "@olympusdao/component-library"; +import { InfoNotification, Input, Modal, PrimaryButton } from "@olympusdao/component-library"; import { BigNumber } from "ethers"; import { formatEther } from "ethers/lib/utils.js"; import { useEffect, useState } from "react"; @@ -26,8 +31,10 @@ import { useConsolidateCooler } from "src/views/Lending/Cooler/hooks/useConsolid import { useCreateCooler } from "src/views/Lending/Cooler/hooks/useCreateCooler"; import { useGetClearingHouse } from "src/views/Lending/Cooler/hooks/useGetClearingHouse"; import { useGetConsolidationAllowances } from "src/views/Lending/Cooler/hooks/useGetConsolidationAllowances"; +import { useGetCoolerForWallet } from "src/views/Lending/Cooler/hooks/useGetCoolerForWallet"; import { useGetCoolerLoans } from "src/views/Lending/Cooler/hooks/useGetCoolerLoans"; import { useGetWalletFundsRequired } from "src/views/Lending/Cooler/hooks/useGetWalletFundsRequired"; +import { useAccount } from "wagmi"; export const ConsolidateLoans = ({ v3CoolerAddress, @@ -57,6 +64,9 @@ export const ConsolidateLoans = ({ const createCooler = useCreateCooler(); const networks = useTestableNetworks(); const [open, setOpen] = useState(false); + const { address } = useAccount(); + const [newOwnerAddress, setNewOwnerAddress] = useState(""); + const [isValidAddress, setIsValidAddress] = useState(true); // Determine which versions are available for consolidation const hasV1Loans = v1Loans && v1Loans.length > 0; @@ -152,20 +162,39 @@ export const ConsolidateLoans = ({ setSelectedVersion(event.target.value as "v1" | "v2" | "v3"); }; + const handleAddressChange = (event: React.ChangeEvent) => { + const inputAddress = event.target.value; + setNewOwnerAddress(inputAddress); + + try { + const checksummedAddress = getAddress(inputAddress.toLowerCase()); + console.log("checksummedAddress", checksummedAddress); + // First check if empty or valid address, then check if it's not the current owner + const isValid = inputAddress === "" || checksummedAddress; + const isNotCurrentOwner = !address || !inputAddress || inputAddress.toLowerCase() !== address.toLowerCase(); + setIsValidAddress(isValid && isNotCurrentOwner); + } catch { + setIsValidAddress(false); + } + }; + const handleConsolidate = () => { if (!coolerAddress || !v3CoolerAddress) return; + coolerMutation.mutate( { fromCoolerAddress: coolerAddress, - toCoolerAddress: v3CoolerAddress, + toCoolerAddress: newOwnerAddress && isValidAddress ? newOwnerCoolerAddress || "" : v3CoolerAddress, fromClearingHouseAddress: selectedClearingHouse.clearingHouseAddress, toClearingHouseAddress: clearingHouseAddresses.v3.clearingHouseAddress, loanIds, + newOwner: Boolean(newOwnerAddress && isValidAddress && newOwnerCoolerAddress), }, { onSuccess: () => { setOpen(false); setSelectedVersion(""); + setNewOwnerAddress(""); }, }, ); @@ -173,6 +202,21 @@ export const ConsolidateLoans = ({ const needsCoolerCreation = !v3CoolerAddress; + const { data: newOwnerCoolerAddress, isFetched: isFetchedNewOwnerCoolerAddress } = useGetCoolerForWallet({ + walletAddress: isValidAddress ? newOwnerAddress : undefined, + factoryAddress: clearingHouseAddresses.v3?.factory, + collateralAddress: clearingHouseAddresses.v3?.collateralAddress, + debtAddress: clearingHouseAddresses.v3?.debtAddress, + clearingHouseVersion: "clearingHouseV3", + }); + + const getButtonText = () => { + if (newOwnerAddress && isValidAddress && newOwnerCoolerAddress) { + return `Transfer & Consolidate Loans`; + } + return `Consolidate Loans`; + }; + if (!showConsolidateButton) return null; return ( @@ -373,6 +417,58 @@ export const ConsolidateLoans = ({ + {selectedVersion && ( + <> + + + + + } + sx={{ + padding: 0, + "& .MuiAccordionSummary-content": { + margin: 0, + }, + }} + > + Transfer Ownership (Optional) + + + + + + + + + )} )} {selectedVersion && !insufficientBalances?.debt && !insufficientBalances?.gohm ? ( @@ -414,10 +510,15 @@ export const ConsolidateLoans = ({ - Consolidate Loans + {getButtonText()}