From b309d36e5c7017f76f8b51beee10d3ce651bba86 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 26 Apr 2026 23:58:09 +0100 Subject: [PATCH 1/4] add additional check for invalid bech32 encoding --- scripts/action-create-tw.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/scripts/action-create-tw.sh b/scripts/action-create-tw.sh index d253e2c..08e3364 100755 --- a/scripts/action-create-tw.sh +++ b/scripts/action-create-tw.sh @@ -231,6 +231,27 @@ if [ ! -z "$withdrawal_address_input" ]; then fi fi +# Verify bech32 integrity (checksum + address type) of stake address +validate_stake_address() { + local label="$1" + local address="$2" + local info + if ! info=$(cardano-cli address info --address "$address" 2>&1); then + echo -e "${RED}Error: $label is not a valid bech32 address: ${YELLOW}$address${NC}" >&2 + echo -e "${GRAY}cardano-cli rejected it: $info${NC}" >&2 + exit 1 + fi + local addr_type + addr_type=$(echo "$info" | jq -r '.type // ""') + if [ "$addr_type" != "stake" ]; then + echo -e "${RED}Error: $label is bech32-valid but is not a stake address (type=${YELLOW}${addr_type:-unknown}${RED}): ${YELLOW}$address${NC}" >&2 + exit 1 + fi +} + +validate_stake_address "metadata body.onChain.reward_account" "$deposit_return" +validate_stake_address "metadata body.onChain.gov_action.rewards[0].key" "$withdrawal_address" + # use bech32 prefix to determine if addresses are mainnet or testnet is_stake_address_mainnet() { local address="$1" From 3ed88dd8b488f6bea1ace10be5cd450c12ec7965 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 27 Apr 2026 00:06:42 +0100 Subject: [PATCH 2/4] add warning/sanity check for deposit --- scripts/action-create-tw.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/action-create-tw.sh b/scripts/action-create-tw.sh index 08e3364..e137e7c 100755 --- a/scripts/action-create-tw.sh +++ b/scripts/action-create-tw.sh @@ -165,7 +165,7 @@ echo -e "${CYAN}Doing some basic validation and checks on metadata${NC}" check_field() { local field_name="$1" local field_value="$2" - + if [ -z "$field_value" ] || [ "$field_value" = "null" ]; then echo -e "${RED}Error: Required field '$field_name' not found in metadata${NC}" >&2 exit 1 @@ -185,6 +185,13 @@ check_field "reward_account" "$deposit_return" deposit_amount=$(jq -r '.body.onChain.deposit' "$input_file") check_field "deposit" "$deposit_amount" +# Sanity-check the deposit magnitude. The current Cardano governance action +# deposit is 100,000 ADA = 100_000_000_000 lovelace. +EXPECTED_DEPOSIT_LOVELACE="100000000000" +if [ "$deposit_amount" != "$EXPECTED_DEPOSIT_LOVELACE" ]; then + echo -e "${YELLOW}Warning: body.onChain.deposit = ${BRIGHTWHITE}$deposit_amount${YELLOW} lovelace, expected ${BRIGHTWHITE}$EXPECTED_DEPOSIT_LOVELACE${YELLOW} (100,000 ADA, the current governance action deposit). Verify this is intentional before submitting.${NC}" >&2 +fi + withdrawal_list=$(jq -r '.body.onChain.gov_action.rewards' "$input_file") check_field "rewards" "$withdrawal_list" From 56a779e5ab87609cf06b3deb5735287557a909c2 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 27 Apr 2026 00:08:29 +0100 Subject: [PATCH 3/4] add same check to info create --- scripts/action-create-info.sh | 7 +++++++ scripts/action-create-tw.sh | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/action-create-info.sh b/scripts/action-create-info.sh index 3e68094..4e31c2f 100755 --- a/scripts/action-create-info.sh +++ b/scripts/action-create-info.sh @@ -156,6 +156,13 @@ check_field "reward_account" "$deposit_return" deposit=$(jq -r '.body.onChain.deposit' "$input_file") check_field "deposit" "$deposit" +# Sanity-check the deposit magnitude. The current Cardano governance action +# deposit is 100,000 ada = 100_000_000_000 lovelace. +EXPECTED_DEPOSIT_LOVELACE="100000000000" +if [ "$deposit" != "$EXPECTED_DEPOSIT_LOVELACE" ]; then + echo -e "${YELLOW}Warning: body.onChain.deposit = ${BRIGHTWHITE}$deposit${YELLOW} lovelace, expected ${BRIGHTWHITE}$EXPECTED_DEPOSIT_LOVELACE${YELLOW} (100,000 ADA, the current governance action deposit). Verify this is intentional before submitting.${NC}" >&2 +fi + authors=$(jq -r '.authors' "$input_file") check_field "authors" "$authors" witness=$(jq -r '.authors[0].witness' "$input_file") diff --git a/scripts/action-create-tw.sh b/scripts/action-create-tw.sh index e137e7c..826a1a7 100755 --- a/scripts/action-create-tw.sh +++ b/scripts/action-create-tw.sh @@ -186,7 +186,7 @@ deposit_amount=$(jq -r '.body.onChain.deposit' "$input_file") check_field "deposit" "$deposit_amount" # Sanity-check the deposit magnitude. The current Cardano governance action -# deposit is 100,000 ADA = 100_000_000_000 lovelace. +# deposit is 100,000 ada = 100_000_000_000 lovelace. EXPECTED_DEPOSIT_LOVELACE="100000000000" if [ "$deposit_amount" != "$EXPECTED_DEPOSIT_LOVELACE" ]; then echo -e "${YELLOW}Warning: body.onChain.deposit = ${BRIGHTWHITE}$deposit_amount${YELLOW} lovelace, expected ${BRIGHTWHITE}$EXPECTED_DEPOSIT_LOVELACE${YELLOW} (100,000 ADA, the current governance action deposit). Verify this is intentional before submitting.${NC}" >&2 From e69b0b6975f643d5ef5e18e7769f73aa6d719ddc Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 27 Apr 2026 00:13:11 +0100 Subject: [PATCH 4/4] add on-chain check for deposit --- scripts/action-create-info.sh | 22 +++++++++++----------- scripts/action-create-tw.sh | 11 +++++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/scripts/action-create-info.sh b/scripts/action-create-info.sh index 4e31c2f..bc8a72c 100755 --- a/scripts/action-create-info.sh +++ b/scripts/action-create-info.sh @@ -163,6 +163,17 @@ if [ "$deposit" != "$EXPECTED_DEPOSIT_LOVELACE" ]; then echo -e "${YELLOW}Warning: body.onChain.deposit = ${BRIGHTWHITE}$deposit${YELLOW} lovelace, expected ${BRIGHTWHITE}$EXPECTED_DEPOSIT_LOVELACE${YELLOW} (100,000 ADA, the current governance action deposit). Verify this is intentional before submitting.${NC}" >&2 fi +# Authoritative deposit check against the live protocol parameter +echo "Checking that deposit matches the current protocol parameter" +onchain_deposit=$(cardano-cli conway query protocol-parameters | jq -r '.govActionDeposit') +if [ "$deposit" = "$onchain_deposit" ]; then + echo -e "${GREEN}Metadata has expected deposit amount${NC}" +else + echo -e "${RED}Metadata does not have expected deposit amount${NC}" >&2 + echo -e "${RED}Expected: $onchain_deposit found: $deposit${NC}" >&2 + exit 1 +fi + authors=$(jq -r '.authors' "$input_file") check_field "authors" "$authors" witness=$(jq -r '.authors[0].witness' "$input_file") @@ -188,17 +199,6 @@ if [ ! -z "$deposit_return_address_input" ]; then fi fi -if [ ! -z "$deposit" ]; then - echo "Checking that deposit is the smame amount as current protocol parameter" - onchain_deposit=$(cardano-cli conway query protocol-parameters | jq -r '.govActionDeposit') - if [ "$deposit" = "$onchain_deposit" ]; then - echo -e "${GREEN}Metadata has expected deposit amount${NC}" - else - echo -e "${RED}Metadata does not have expected deposit amount${NC}" - echo -e "${RED}Expected: $onchain_deposit found: $deposit${NC}" - exit 1 - fi -fi # use bech32 prefix to determine if addresses are mainnet or testnet is_stake_address_mainnet() { local address="$1" diff --git a/scripts/action-create-tw.sh b/scripts/action-create-tw.sh index 826a1a7..608462c 100755 --- a/scripts/action-create-tw.sh +++ b/scripts/action-create-tw.sh @@ -192,6 +192,17 @@ if [ "$deposit_amount" != "$EXPECTED_DEPOSIT_LOVELACE" ]; then echo -e "${YELLOW}Warning: body.onChain.deposit = ${BRIGHTWHITE}$deposit_amount${YELLOW} lovelace, expected ${BRIGHTWHITE}$EXPECTED_DEPOSIT_LOVELACE${YELLOW} (100,000 ADA, the current governance action deposit). Verify this is intentional before submitting.${NC}" >&2 fi +# Authoritative deposit check against the live protocol parameter +echo "Checking that deposit matches the current protocol parameter" +onchain_deposit=$(cardano-cli conway query protocol-parameters | jq -r '.govActionDeposit') +if [ "$deposit_amount" = "$onchain_deposit" ]; then + echo -e "${GREEN}Metadata has expected deposit amount${NC}" +else + echo -e "${RED}Metadata does not have expected deposit amount${NC}" >&2 + echo -e "${RED}Expected: $onchain_deposit found: $deposit_amount${NC}" >&2 + exit 1 +fi + withdrawal_list=$(jq -r '.body.onChain.gov_action.rewards' "$input_file") check_field "rewards" "$withdrawal_list"