fix: address review findings in sell KRK widget

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-05 12:39:15 +00:00
parent 36c798605f
commit 5b69d9ee3d
2 changed files with 40 additions and 12 deletions

View file

@ -37,7 +37,7 @@
<span class="swap-balance">Balance: {{ formattedKrkBalance }} KRK</span> <span class="swap-balance">Balance: {{ formattedKrkBalance }} KRK</span>
</div> </div>
<div class="swap-input-row"> <div class="swap-input-row">
<input id="local-sell-amount" data-testid="swap-sell-amount-input" :value="sellAmount" @input="sellAmount = ($event.target as HTMLInputElement).value" type="number" min="0" step="1" class="swap-input" :disabled="selling" /> <input id="local-sell-amount" data-testid="swap-sell-amount-input" :value="sellAmount" @input="sellAmount = ($event.target as HTMLInputElement).value" type="number" min="0" step="0.01" class="swap-input" :disabled="selling" />
<button class="max-button" :disabled="selling" @click="setMax">Max</button> <button class="max-button" :disabled="selling" @click="setMax">Max</button>
</div> </div>
</div> </div>
@ -60,8 +60,11 @@ const { swapAmount, swapping, canSwap, buyKrk, sellAmount, selling, sellPhase, k
const mode = ref<'buy' | 'sell'>('buy'); const mode = ref<'buy' | 'sell'>('buy');
const formattedKrkBalance = computed(() => { const formattedKrkBalance = computed(() => {
const val = Number(formatUnits(krkBalance.value, 18)); const s = formatUnits(krkBalance.value, 18);
return val.toLocaleString(undefined, { maximumFractionDigits: 4 }); 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') { function setMode(m: 'buy' | 'sell') {
@ -69,7 +72,8 @@ function setMode(m: 'buy' | 'sell') {
if (m === 'sell') loadKrkBalance(); if (m === 'sell') loadKrkBalance();
} }
function setMax() { async function setMax() {
await loadKrkBalance();
sellAmount.value = formatUnits(krkBalance.value, 18); sellAmount.value = formatUnits(krkBalance.value, 18);
} }

View file

@ -16,13 +16,6 @@ export const WETH_ABI = [
stateMutability: 'payable', stateMutability: 'payable',
type: 'function', type: 'function',
}, },
{
inputs: [{ internalType: 'uint256', name: 'wad', type: 'uint256' }],
name: 'withdraw',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
] as const satisfies Abi; ] as const satisfies Abi;
export const SWAP_ROUTER_ABI = [ export const SWAP_ROUTER_ABI = [
@ -130,7 +123,7 @@ export function useSwapKrk() {
chainId: resolvedChainId.value, chainId: resolvedChainId.value,
}); });
} catch { } 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'); 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'; sellPhase.value = 'approving';
const allowance = await readContract(wagmiConfig, { const allowance = await readContract(wagmiConfig, {
abi: erc20Abi, abi: erc20Abi,
@ -325,12 +347,14 @@ export function useSwapKrk() {
await loadBalance(); await loadBalance();
await loadKrkBalance(); await loadKrkBalance();
sellAmount.value = '';
toast.success('Sell complete. WETH has been added to your wallet.'); toast.success('Sell complete. WETH has been added to your wallet.');
} catch (error: unknown) { } catch (error: unknown) {
toast.error(getErrorMessage(error, 'Sell failed')); toast.error(getErrorMessage(error, 'Sell failed'));
} finally { } finally {
selling.value = false; selling.value = false;
sellPhase.value = 'approving';
} }
} }