diff --git a/web-app/src/components/LocalSwapWidget.vue b/web-app/src/components/LocalSwapWidget.vue index ff54491..69c27e2 100644 --- a/web-app/src/components/LocalSwapWidget.vue +++ b/web-app/src/components/LocalSwapWidget.vue @@ -37,7 +37,7 @@ Balance: {{ formattedKrkBalance }} KRK
- +
@@ -60,8 +60,11 @@ const { swapAmount, swapping, canSwap, buyKrk, sellAmount, selling, sellPhase, k const mode = ref<'buy' | 'sell'>('buy'); const formattedKrkBalance = computed(() => { - const val = Number(formatUnits(krkBalance.value, 18)); - return val.toLocaleString(undefined, { maximumFractionDigits: 4 }); + const s = formatUnits(krkBalance.value, 18); + const [whole, frac = ''] = s.split('.'); + const truncFrac = frac.slice(0, 4).replace(/0+$/, ''); + const wholeFormatted = BigInt(whole).toLocaleString(); + return truncFrac ? `${wholeFormatted}.${truncFrac}` : wholeFormatted; }); function setMode(m: 'buy' | 'sell') { @@ -69,7 +72,8 @@ function setMode(m: 'buy' | 'sell') { if (m === 'sell') loadKrkBalance(); } -function setMax() { +async function setMax() { + await loadKrkBalance(); sellAmount.value = formatUnits(krkBalance.value, 18); } diff --git a/web-app/src/composables/useSwapKrk.ts b/web-app/src/composables/useSwapKrk.ts index f3667a0..b46651e 100644 --- a/web-app/src/composables/useSwapKrk.ts +++ b/web-app/src/composables/useSwapKrk.ts @@ -16,13 +16,6 @@ export const WETH_ABI = [ stateMutability: 'payable', type: 'function', }, - { - inputs: [{ internalType: 'uint256', name: 'wad', type: 'uint256' }], - name: 'withdraw', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, ] as const satisfies Abi; export const SWAP_ROUTER_ABI = [ @@ -130,7 +123,7 @@ export function useSwapKrk() { chainId: resolvedChainId.value, }); } catch { - krkBalance.value = 0n; + // Do not overwrite a previously loaded non-zero balance on RPC error } } @@ -286,6 +279,35 @@ export function useSwapKrk() { }); if (amount > balance) throw new Error('Insufficient KRK balance'); + const factoryAddress = await readContract(wagmiConfig, { + abi: SWAP_ROUTER_ABI, + address: router, + functionName: 'factory', + chainId: currentChainId, + }); + const factory = ensureAddress(factoryAddress, 'Uniswap factory'); + + const poolAddress = await readContract(wagmiConfig, { + abi: UNISWAP_FACTORY_ABI, + address: factory, + functionName: 'getPool', + args: [weth, harb, 10_000], + chainId: currentChainId, + }); + if (!poolAddress || poolAddress === zeroAddress) { + throw new Error('No KRK/WETH pool found at 1% fee; deploy and recenter first'); + } + + const poolLiquidity = await readContract(wagmiConfig, { + abi: UNISWAP_POOL_ABI, + address: poolAddress, + functionName: 'liquidity', + chainId: currentChainId, + }); + if (poolLiquidity === 0n) { + throw new Error('KRK/WETH pool has zero liquidity; run recenter before swapping'); + } + sellPhase.value = 'approving'; const allowance = await readContract(wagmiConfig, { abi: erc20Abi, @@ -325,12 +347,14 @@ export function useSwapKrk() { await loadBalance(); await loadKrkBalance(); + sellAmount.value = ''; toast.success('Sell complete. WETH has been added to your wallet.'); } catch (error: unknown) { toast.error(getErrorMessage(error, 'Sell failed')); } finally { selling.value = false; + sellPhase.value = 'approving'; } }