diff --git a/src/dapp-tests/integration/tests.sh b/src/dapp-tests/integration/tests.sh index 8ebe92349..84b026bf2 100755 --- a/src/dapp-tests/integration/tests.sh +++ b/src/dapp-tests/integration/tests.sh @@ -1,5 +1,7 @@ #! /usr/bin/env bash +set -eo pipefail + # ------------------------------------------------ # CONFIGURATION # ------------------------------------------------ @@ -460,6 +462,55 @@ test_calldata_19() { assert_equals "0xc2985578" "$output" } +test_calldata_20() { + local output + output=$(seth calldata 'foo(bytes32, bytes4, bytes16)' '0x' '0x' '0x') + + assert_equals "0x1765a16e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "$output" +} + +test_sig_1() { + assert_equals "0xd2ce7d65" "$(seth sig 'outboundTransfer(address,address,uint256,uint256,uint256,bytes)')" +} + +test_sig_2() { + assert_equals "0x6a4f4b05" "$(seth sig 'setKeepers(address[],bool[])')" +} + +test_sig_3() { + assert_equals "0xf837dc72" "$(seth sig 'payAll(bytes12,uint128)')" +} + +test_sig_4() { + assert_equals "0xd2ce7d65" "$(seth sig 'outboundTransfer(address,address,uint,uint,uint,bytes memory)')" +} + +test_sig_5() { + assert_equals "0xe548799c" "$(seth sig 'registerCrowdsale(address,address,uint256[8])')" +} + +# tuples currently broken: https://github.com/dapphub/dapptools/issues/861 +todo_sig_6() { + assert_equals "0x5cc5e3d9" "$(seth sig 'createIncentive((address,address,uint256,uint256,address),uint256)')" +} + +# ignored for now due to https://github.com/dapphub/dapptools/issues/861 +todo_sig_fuzz() { + echo + for _ in $(seq "$FUZZ_RUNS"); do + id=$(mod "$(uint256)" 236272) + sig=$(curl -s "https://www.4byte.directory/api/v1/signatures/$id/") + [[ "$sig" == '{"detail":"Not found."}' ]] && continue + text=$(echo "$sig" | jq -r .text_signature) + hex=$(echo "$sig" | jq -r .hex_signature) + echo "checking ($id): $text" + + local actual + actual=$(seth sig "$text") + assert_equals "$hex" "$actual" + done +} + test_keccak_1() { local output output=$(seth keccak 0xcafe) diff --git a/src/hevm/CHANGELOG.md b/src/hevm/CHANGELOG.md index 56d41738a..0a7ef1df9 100644 --- a/src/hevm/CHANGELOG.md +++ b/src/hevm/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Clearer display for the invalid opcode (`0xfe`) in debug view - Better error messages when trying to deploy unlinked bytecode +- `bytesX` arguments to `hevm abiencode` are automatically padded ### Fixed diff --git a/src/hevm/src/EVM/ABI.hs b/src/hevm/src/EVM/ABI.hs index b7809ac21..b459b2073 100644 --- a/src/hevm/src/EVM/ABI.hs +++ b/src/hevm/src/EVM/ABI.hs @@ -483,9 +483,13 @@ instance Read Boolz where readsPrec n (_:t) = readsPrec n t makeAbiValue :: AbiType -> String -> AbiValue -makeAbiValue typ str = case readP_to_S (parseAbiValue typ) str of +makeAbiValue typ str = case readP_to_S (parseAbiValue typ) (padStr str) of [(val,"")] -> val _ -> error $ "could not parse abi argument: " ++ str ++ " : " ++ show typ + where + padStr = case typ of + (AbiBytesType n) -> padRight' (2 * n + 2) -- +2 is for the 0x prefix + _ -> id parseAbiValue :: AbiType -> ReadP AbiValue parseAbiValue (AbiUIntType n) = do W256 w <- readS_to_P reads diff --git a/src/hevm/src/EVM/Types.hs b/src/hevm/src/EVM/Types.hs index dfb2be0a0..fdd2368de 100644 --- a/src/hevm/src/EVM/Types.hs +++ b/src/hevm/src/EVM/Types.hs @@ -463,6 +463,9 @@ padLeft n xs = BS.replicate (n - BS.length xs) 0 <> xs padRight :: Int -> ByteString -> ByteString padRight n xs = xs <> BS.replicate (n - BS.length xs) 0 +padRight' :: Int -> String -> String +padRight' n xs = xs <> replicate (n - length xs) '0' + -- | Right padding / truncating truncpad :: Int -> [SWord 8] -> [SWord 8] truncpad n xs = if m > n then take n xs diff --git a/src/seth/CHANGELOG.md b/src/seth/CHANGELOG.md index 4b2ea6403..7998007e0 100644 --- a/src/seth/CHANGELOG.md +++ b/src/seth/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- `bytesX` arguments to `seth calldata` are automatically padded - `seth 4byte` command returns the response from querying [4byte.directory](https://www.4byte.directory/) for a given function signature - `seth 4byte-decode` command queries 4byte.directory for matching function signatures, uses one to decode the calldata, and prints the decoded calldata - `seth 4byte-event` command returns the response from querying 4byte.directory for a given event topic diff --git a/src/seth/libexec/seth/seth-sig b/src/seth/libexec/seth/seth-sig index 13b535b1d..8d4ab663d 100755 --- a/src/seth/libexec/seth/seth-sig +++ b/src/seth/libexec/seth/seth-sig @@ -8,14 +8,22 @@ set -e # Get ABI from input abi=$(seth --abi-function-json "$1") -inputs=$(echo $abi | jq '.inputs[] | .type') +inputs=$(echo "$abi" | jq '.inputs[] | .type') # Generate dummy args args=() for input in $inputs; do type="${input//\"}" # remove leading and trailing quotes from the JSON - end=${type: -2} # get the last two characters to check for array types - [ $end = "[]" ] && arg="[]" || arg=0 # use [] for array types and 0 otherwise + end=${type: -1} # get the last character to check for array types + if [[ "$end" = "]" ]]; then + arg="[]" + elif [[ "$type" =~ ^byte.*$ ]]; then + arg="0x" + elif [[ "$type" =~ ^string$ ]]; then + arg='""' + else + arg=0 + fi args+=(--arg "$arg") done