Skip to content

Commit 5874155

Browse files
sirtimidclaude
andcommitted
fix(evm-wallet): address code review findings for plugin and scripts
- Validate decimal places in encodeEthToTerms instead of silent truncation - Add try-catch for getTokenMetadata in swap token resolution - Recognize native tokens (BNB, MATIC/POL) across supported chains - Reject zero-value hex amounts in wallet_send Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e4c453c commit 5874155

4 files changed

Lines changed: 25 additions & 6 deletions

File tree

packages/evm-wallet-experiment/openclaw-plugin/tools/eth.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ export function registerEthTools(
125125
// Convert decimal ETH string to hex wei.
126126
let hexValue: string;
127127
if (HEX_VALUE_RE.test(params.value)) {
128+
if (BigInt(params.value) <= 0n) {
129+
return makeError('Amount must be greater than zero.');
130+
}
128131
hexValue = params.value;
129132
} else {
130133
try {

packages/evm-wallet-experiment/openclaw-plugin/tools/swap.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { WalletCaller } from '../daemon.ts';
22
import type { OpenClawPluginApi } from '../types.ts';
33
import {
44
NATIVE_ETH,
5+
NATIVE_TOKEN_SYMBOLS,
56
errorMessage,
67
formatTxResult,
78
makeError,
@@ -25,8 +26,8 @@ async function resolveSwapToken(
2526
): Promise<
2627
{ address: string; decimals: number; symbol: string } | { error: string }
2728
> {
28-
if (token.toUpperCase() === 'ETH' || token === NATIVE_ETH) {
29-
return { address: NATIVE_ETH, decimals: 18, symbol: 'ETH' };
29+
if (NATIVE_TOKEN_SYMBOLS.has(token.toUpperCase()) || token === NATIVE_ETH) {
30+
return { address: NATIVE_ETH, decimals: 18, symbol: token.toUpperCase() };
3031
}
3132

3233
let resolved: { address: string; symbol?: string };
@@ -36,9 +37,16 @@ async function resolveSwapToken(
3637
return { error: errorMessage(error) };
3738
}
3839

39-
const metadata = (await wallet('getTokenMetadata', [
40-
{ token: resolved.address },
41-
])) as Record<string, unknown>;
40+
let metadata: Record<string, unknown>;
41+
try {
42+
metadata = (await wallet('getTokenMetadata', [
43+
{ token: resolved.address },
44+
])) as Record<string, unknown>;
45+
} catch (error: unknown) {
46+
return {
47+
error: `Could not fetch metadata for ${token}: ${errorMessage(error)}`,
48+
};
49+
}
4250

4351
if (typeof metadata?.decimals !== 'number') {
4452
return { error: `Could not determine decimals for ${token}.` };

packages/evm-wallet-experiment/openclaw-plugin/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ export const ETH_ADDRESS_RE = /^0x[\da-f]{40}$/iu;
66
export const HEX_VALUE_RE = /^0x[\da-f]+$/iu;
77
export const NATIVE_ETH = '0x0000000000000000000000000000000000000000';
88

9+
/**
10+
* Native token symbols that map to the zero address across supported chains.
11+
*/
12+
export const NATIVE_TOKEN_SYMBOLS = new Set(['ETH', 'BNB', 'MATIC', 'POL']);
13+
914
const BLOCK_EXPLORER_URLS: Record<number, string> = {
1015
1: 'https://etherscan.io',
1116
10: 'https://optimistic.etherscan.io',

packages/evm-wallet-experiment/scripts/home-interactive.mjs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ function prompt(question) {
249249
*/
250250
function encodeEthToTerms(ethAmount) {
251251
const [whole, frac = ''] = ethAmount.split('.');
252-
const fracPadded = frac.padEnd(18, '0').slice(0, 18);
252+
if (frac.length > 18) {
253+
fail(`Amount "${ethAmount}" has too many decimal places (max 18 for ETH).`);
254+
}
255+
const fracPadded = frac.padEnd(18, '0');
253256
const wei = BigInt(whole || '0') * 10n ** 18n + BigInt(fracPadded);
254257
return `0x${wei.toString(16).padStart(64, '0')}`;
255258
}

0 commit comments

Comments
 (0)