From a2101ac83f891c70e4b0b3ef36a737b97a085680 Mon Sep 17 00:00:00 2001 From: Alejandro Date: Fri, 15 Mar 2024 13:49:02 -0300 Subject: [PATCH] Validate params in interactive mode --- packages/ethernaut-common/src/type-address.js | 5 ++++- packages/ethernaut-common/src/type-bytes32.js | 4 ++++ packages/ethernaut-common/src/type-ens.js | 4 ++++ packages/ethernaut-common/src/type-int.js | 4 ++++ packages/ethernaut-common/src/type-string.js | 4 ++++ packages/ethernaut-interact-ui/src/index.js | 7 ++++--- packages/ethernaut-interact/src/tasks/token.js | 7 ++++++- .../ethernaut-ui/src/internal/collect-args.js | 15 ++++++++++++--- .../ethernaut-ui/src/internal/make-interactive.js | 2 +- 9 files changed, 43 insertions(+), 9 deletions(-) diff --git a/packages/ethernaut-common/src/type-address.js b/packages/ethernaut-common/src/type-address.js index d22440dd..72502a7d 100644 --- a/packages/ethernaut-common/src/type-address.js +++ b/packages/ethernaut-common/src/type-address.js @@ -16,10 +16,13 @@ module.exports = { `"${argValue}" is not an address`, `Invalid ${argName}`, ) - if (typeof describe === 'function') { throw err } + + return false } + + return true }, } diff --git a/packages/ethernaut-common/src/type-bytes32.js b/packages/ethernaut-common/src/type-bytes32.js index 34c675db..79b398fc 100644 --- a/packages/ethernaut-common/src/type-bytes32.js +++ b/packages/ethernaut-common/src/type-bytes32.js @@ -20,6 +20,10 @@ module.exports = { if (typeof describe === 'function') { throw err } + + return false } + + return true }, } diff --git a/packages/ethernaut-common/src/type-ens.js b/packages/ethernaut-common/src/type-ens.js index 43f3b181..c86fc275 100644 --- a/packages/ethernaut-common/src/type-ens.js +++ b/packages/ethernaut-common/src/type-ens.js @@ -18,6 +18,10 @@ module.exports = { if (typeof describe === 'function') { throw err } + + return false } + + return true }, } diff --git a/packages/ethernaut-common/src/type-int.js b/packages/ethernaut-common/src/type-int.js index db66d99a..f1c74450 100644 --- a/packages/ethernaut-common/src/type-int.js +++ b/packages/ethernaut-common/src/type-int.js @@ -15,6 +15,10 @@ module.exports = { if (typeof describe === 'function') { throw err } + + return false } + + return true }, } diff --git a/packages/ethernaut-common/src/type-string.js b/packages/ethernaut-common/src/type-string.js index f3c674b8..a8cd24fe 100644 --- a/packages/ethernaut-common/src/type-string.js +++ b/packages/ethernaut-common/src/type-string.js @@ -13,6 +13,10 @@ module.exports = { if (typeof describe === 'function') { throw err } + + return false } + + return true }, } diff --git a/packages/ethernaut-interact-ui/src/index.js b/packages/ethernaut-interact-ui/src/index.js index 3c3ba1b8..53d3d12c 100644 --- a/packages/ethernaut-interact-ui/src/index.js +++ b/packages/ethernaut-interact-ui/src/index.js @@ -22,14 +22,15 @@ extendEnvironment((hre) => { contract.paramDefinitions.params.prompt = paramsPrompt const token = hre.scopes.interact.tasks.token - token.paramDefinitions.address.suggest = addressSuggest + token.positionalParamDefinitions.find((p) => p.name === 'address').suggest = + addressSuggest token.paramDefinitions.fn.prompt = fnERC20Prompt token.paramDefinitions.params.prompt = paramsERC20Prompt const logs = hre.scopes.interact.tasks.logs + logs.paramDefinitions.address.suggest = addressSuggest logs.paramDefinitions.abi.prompt = abiPrompt logs.paramDefinitions.abi.suggest = abiSuggest - logs.paramDefinitions.address.suggest = addressSuggest - logs.paramDefinitions.event.prompt = eventPrompt logs.paramDefinitions.params.prompt = paramsLogPrompt + logs.paramDefinitions.event.prompt = eventPrompt }) diff --git a/packages/ethernaut-interact/src/tasks/token.js b/packages/ethernaut-interact/src/tasks/token.js index 462cca64..7840ce97 100644 --- a/packages/ethernaut-interact/src/tasks/token.js +++ b/packages/ethernaut-interact/src/tasks/token.js @@ -4,7 +4,12 @@ const interact = require('../internal/interact') require('../scopes/interact') .task('token', 'Interacts with any ERC20 token') - .addParam('address', 'The address of the token', undefined, types.string) + .addPositionalParam( + 'address', + 'The address of the token', + undefined, + types.address, + ) .addParam('fn', 'The function of the token to call', undefined, types.string) .addOptionalParam( 'value', diff --git a/packages/ethernaut-ui/src/internal/collect-args.js b/packages/ethernaut-ui/src/internal/collect-args.js index db547fc0..da0a74bd 100644 --- a/packages/ethernaut-ui/src/internal/collect-args.js +++ b/packages/ethernaut-ui/src/internal/collect-args.js @@ -15,7 +15,9 @@ module.exports = async function collectArguments(providedArgs, task, hre) { ) const collectedArgs = {} - for (let paramDef of paramDefinitions) { + for (let i = 0; i < paramDefinitions.length; i++) { + const paramDef = paramDefinitions[i] + if (paramDef.originallyOptional) continue const providedArg = providedArgs[paramDef.name] @@ -29,7 +31,14 @@ module.exports = async function collectArguments(providedArgs, task, hre) { argsSoFar, ) if (collectedArg !== undefined) { - debug.log(`Collected ${paramDef.name}" with "${collectedArg}"`, 'ui') + debug.log(`Collected "${paramDef.name}" with "${collectedArg}"`, 'ui') + + const isValid = paramDef.type.validate(paramDef.name, collectedArg) + debug.log(`Validation result for "${paramDef.name}": ${isValid}`, 'ui') + if (!isValid) { + i-- + continue + } collectedArgs[paramDef.name] = collectedArg } @@ -129,5 +138,5 @@ async function rawPrompt(paramDef, suggested) { if (result === 'false') return false if (result === 'true') return true - return result + return result === '' ? undefined : result } diff --git a/packages/ethernaut-ui/src/internal/make-interactive.js b/packages/ethernaut-ui/src/internal/make-interactive.js index 13c1bab6..efb0aac0 100644 --- a/packages/ethernaut-ui/src/internal/make-interactive.js +++ b/packages/ethernaut-ui/src/internal/make-interactive.js @@ -73,7 +73,7 @@ function makeInteractive(task) { return parsedValue }, validate: (argName, argValue) => { - originalType.validate(argName, argValue) + return originalType.validate(argName, argValue) }, }) for (let paramDef of paramDefinitions) {