adding redeem only function for killed pools)

This commit is contained in:
2025-11-19 15:43:10 -04:00
parent 66d854fb75
commit 107d2ae5c0
2 changed files with 62 additions and 23 deletions

View File

@@ -49,6 +49,17 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
// Fetch all pools using the new hook // Fetch all pools using the new hook
const { poolDetails, loading: poolsLoading } = useGetAllPools(); const { poolDetails, loading: poolsLoading } = useGetAllPools();
// Filter pools based on mode: stake mode shows only working pools, unstake shows all
const filteredPools = useMemo(() => {
if (!poolDetails) return null;
if (mode === 'stake') {
// Stake mode: only show working (non-killed) pools
return poolDetails.filter(pool => !pool.isKilled);
}
// Unstake mode: show all pools (working + killed)
return poolDetails;
}, [poolDetails, mode]);
// Get token details for the user // Get token details for the user
const { tokenDetails, loading: tokensLoading } = useTokenDetails(address); const { tokenDetails, loading: tokensLoading } = useTokenDetails(address);
@@ -190,6 +201,14 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
fetchTokenDetails(); fetchTokenDetails();
}, [publicClient, selectedPool, mode, redeemAll]); }, [publicClient, selectedPool, mode, redeemAll]);
// Auto-enable Redeem All for killed pools in unstake mode
useEffect(() => {
if (mode === 'unstake' && selectedPool?.isKilled) {
setRedeemAll(true);
setSelectedToken(null); // Clear token selection for killed pools
}
}, [mode, selectedPool]);
// Close dropdowns when clicking outside // Close dropdowns when clicking outside
useEffect(() => { useEffect(() => {
const handleClickOutside = (event: MouseEvent) => { const handleClickOutside = (event: MouseEvent) => {
@@ -329,8 +348,8 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
</Button> </Button>
{isPoolDropdownOpen && ( {isPoolDropdownOpen && (
<div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto"> <div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto">
{poolDetails && poolDetails.length > 0 ? ( {filteredPools && filteredPools.length > 0 ? (
poolDetails.map((pool) => ( filteredPools.map((pool) => (
<button <button
key={pool.address} key={pool.address}
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none" className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
@@ -381,7 +400,14 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
> >
{selectedPool ? ( {selectedPool ? (
<div className="flex flex-col items-start"> <div className="flex flex-col items-start">
<div className="flex items-center gap-2">
<span className="font-medium">{selectedPool.symbol}</span> <span className="font-medium">{selectedPool.symbol}</span>
{selectedPool.isKilled && (
<span className="text-xs px-2 py-0.5 bg-orange-500/20 text-orange-600 dark:text-orange-400 border border-orange-500/30 rounded">
Redeem Only
</span>
)}
</div>
<span className="text-xs text-muted-foreground">{selectedPool.name}</span> <span className="text-xs text-muted-foreground">{selectedPool.name}</span>
</div> </div>
) : ( ) : (
@@ -391,8 +417,8 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
</Button> </Button>
{isPoolDropdownOpen && ( {isPoolDropdownOpen && (
<div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto"> <div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto">
{poolDetails && poolDetails.length > 0 ? ( {filteredPools && filteredPools.length > 0 ? (
poolDetails.map((pool) => ( filteredPools.map((pool) => (
<button <button
key={pool.address} key={pool.address}
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none" className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
@@ -402,12 +428,19 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
setSelectedToken(null); setSelectedToken(null);
}} }}
> >
<div className="flex justify-between items-center w-full"> <div className="flex justify-between items-center w-full gap-2">
<div className="flex flex-col"> <div className="flex flex-col flex-1 min-w-0">
<div className="flex items-center gap-2">
<span className="font-medium">{pool.symbol}</span> <span className="font-medium">{pool.symbol}</span>
{pool.isKilled && (
<span className="text-xs px-2 py-0.5 bg-orange-500/20 text-orange-600 dark:text-orange-400 border border-orange-500/30 rounded whitespace-nowrap">
Redeem Only
</span>
)}
</div>
<span className="text-xs text-muted-foreground">{pool.name}</span> <span className="text-xs text-muted-foreground">{pool.name}</span>
</div> </div>
{(pool.price || pool.tvl) && ( {!pool.isKilled && (pool.price || pool.tvl) && (
<div className="flex flex-col items-end"> <div className="flex flex-col items-end">
{pool.price && ( {pool.price && (
<span className="text-sm font-medium text-muted-foreground">{pool.price}</span> <span className="text-sm font-medium text-muted-foreground">{pool.price}</span>
@@ -562,13 +595,15 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
size="sm" size="sm"
className="h-6 px-2 text-xs" className="h-6 px-2 text-xs"
onClick={() => { onClick={() => {
// Prevent toggling off for killed pools
if (selectedPool?.isKilled) return;
setRedeemAll(!redeemAll); setRedeemAll(!redeemAll);
if (!redeemAll && lpBalance !== null) { if (!redeemAll && lpBalance !== null) {
setStakeAmount(formatUnits(lpBalance, 18)); setStakeAmount(formatUnits(lpBalance, 18));
} }
}} }}
disabled={!selectedPool} disabled={!selectedPool || selectedPool?.isKilled}
title="Burn entire LP token and receive all underlying tokens" title={selectedPool?.isKilled ? "Killed pools can only use Redeem All mode" : "Burn entire LP token and receive all underlying tokens"}
> >
{redeemAll ? 'Redeem All: ON' : 'Redeem All'} {redeemAll ? 'Redeem All: ON' : 'Redeem All'}
</Button> </Button>

View File

@@ -379,6 +379,7 @@ export interface PoolDetails {
tokens: readonly `0x${string}`[]; tokens: readonly `0x${string}`[];
price?: string; // Formatted price string price?: string; // Formatted price string
tvl?: string; // Formatted TVL string (e.g., "$1.2M") tvl?: string; // Formatted TVL string (e.g., "$1.2M")
isKilled: boolean; // Whether the pool has been killed
} }
export function useGetAllPools(offset: number = 0, limit: number = 100) { export function useGetAllPools(offset: number = 0, limit: number = 100) {
@@ -457,10 +458,12 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
}).catch(() => false), }).catch(() => false),
]); ]);
// Only add pool if it's working // Fetch pool price and TVL (only for working pools)
let priceStr: string | undefined;
let tvlStr: string | undefined;
if (isWorking) { if (isWorking) {
// Fetch pool price (use first token as quote, index 0) // Fetch pool price (use first token as quote, index 0)
let priceStr: string | undefined;
try { try {
const priceRaw = await publicClient.readContract({ const priceRaw = await publicClient.readContract({
address: partyInfoAddress as `0x${string}`, address: partyInfoAddress as `0x${string}`,
@@ -489,7 +492,6 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
} }
// Calculate TVL (approximate by getting first token balance and doubling it) // Calculate TVL (approximate by getting first token balance and doubling it)
let tvlStr: string | undefined;
try { try {
if (tokens && tokens.length > 0) { if (tokens && tokens.length > 0) {
const firstTokenAddress = tokens[0]; const firstTokenAddress = tokens[0];
@@ -519,7 +521,9 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
console.error(`Error fetching TVL for ${poolAddress}:`, err); console.error(`Error fetching TVL for ${poolAddress}:`, err);
tvlStr = undefined; tvlStr = undefined;
} }
}
// Add all pools (both working and killed)
details.push({ details.push({
address: poolAddress, address: poolAddress,
name: name as string, name: name as string,
@@ -527,8 +531,8 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
tokens: tokens as readonly `0x${string}`[], tokens: tokens as readonly `0x${string}`[],
price: priceStr, price: priceStr,
tvl: tvlStr, tvl: tvlStr,
isKilled: !isWorking,
}); });
}
} catch (err) { } catch (err) {
console.error('Error fetching pool details for', poolAddress, err); console.error('Error fetching pool details for', poolAddress, err);
// Skip pools that fail to load // Skip pools that fail to load