diff --git a/README.md b/README.md index 5ae85d8..60f5c7f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ [![License: AGPL-3.0-only](https://img.shields.io/badge/License-AGPL--3.0--only-blue)](https://www.gnu.org/licenses/agpl-3.0) +> [!IMPORTANT] +> This [PR](https://github.com/pcaversaccio/safe-tx-hashes-util/pull/20) introduces a _temporary_ patch to use the [Safe Client Gateway API](https://safe-client.safe.global/api) since the [Safe Transaction Service API](https://docs.safe.global/core-api/transaction-service-overview) is currently unavailable. Please checkout the `feat/use-safe-client-gateway` branch until further notice. + ```console |)0/\/'T TR|\_|5T, \/3R1FY! 🫡 ``` @@ -31,20 +34,20 @@ This Bash [script](./safe_hashes.sh) calculates the Safe transaction hashes by r - Base (identifier: `base`, chain ID: `8453`) - Base Sepolia (identifier: `base-sepolia`, chain ID: `84532`) - Blast (identifier: `blast`, chain ID: `81457`) -- BSC (Binance Smart Chain) (identifier: `bsc`, chain ID: `56`) +- BSC (BNB Smart Chain) (identifier: `bsc`, chain ID: `56`) - Celo (identifier: `celo`, chain ID: `42220`) - Ethereum (identifier: `ethereum`, chain ID: `1`) - Gnosis (identifier: `gnosis`, chain ID: `100`) - Gnosis Chiado (identifier: `gnosis-chiado`, chain ID: `10200`) - Linea (identifier: `linea`, chain ID: `59144`) - Mantle (identifier: `mantle`, chain ID: `5000`) -- Optimism (identifier: `optimism`, chain ID: `10`) +- OP (Optimism) (identifier: `optimism`, chain ID: `10`) - Polygon (identifier: `polygon`, chain ID: `137`) - Polygon zkEVM (identifier: `polygon-zkevm`, chain ID: `1101`) - Scroll (identifier: `scroll`, chain ID: `534352`) - Sepolia (identifier: `sepolia`, chain ID: `11155111`) - World Chain (identifier: `worldchain`, chain ID: `480`) -- X Layer (identifier: `xlayer`, chain ID: `195`) +- X Layer (identifier: `xlayer`, chain ID: `196`) - ZKsync Era (identifier: `zksync`, chain ID: `324`) ## Usage @@ -269,10 +272,10 @@ Safe message hash: 0x1866b559f56261ada63528391b93a1fe8e2e33baf7cace94fc6b42202d1 ## Community-Maintained User Interface Implementations > [!IMPORTANT] -> Please be aware that user interface implementations may introduce additional trust assumptions, such as relying on `npm` dependencies that have not undergone thorough review. Always verify and cross-reference with the main [script](./safe_hashes.sh). +> Please be aware that user interface implementations may introduce additional trust assumptions, such as relying on `npm` dependencies that have not undergone thorough review or a deployment process that could be compromised by an attacker. Always verify and cross-reference with the main [script](./safe_hashes.sh). -- [`safehashpreview.com`](https://www.safehashpreview.com): - - Code: [`josepchetrit12/safe-tx-hashes-util`](https://github.com/josepchetrit12/safe-tx-hashes-util) +- [`safeutils.openzeppelin.com`](https://safeutils.openzeppelin.com): + - Code: [`OpenZeppelin/safe-utils`](https://github.com/OpenZeppelin/safe-utils) - Authors: [`josepchetrit12`](https://github.com/josepchetrit12), [`xaler5`](https://github.com/xaler5) [^1]: It is theoretically possible to query transactions prior to the first signature; however, this functionality is not incorporated into the main [script](https://github.com/pcaversaccio/safe-tx-hashes-util/blob/main/safe_hashes.sh). To do so, you would proceed through the [Safe UI](https://app.safe.global) as usual, stopping at the page where the transaction is signed or executed. At this point, the action is recorded in the [Safe Transaction Service API](https://docs.safe.global/core-api/transaction-service-overview), allowing you to retrieve the unsigned transaction by setting `trusted=false` in the [API](https://docs.safe.global/core-api/transaction-service-reference/mainnet#List-a-Safe's-Multisig-Transactions) query within your Bash script. For example, you might use a query such as: `https://safe-transaction-arbitrum.safe.global/api/v1/safes/0xB24A3AA250E209bC95A4a9afFDF10c6D099B3d34/multisig-transactions/?trusted=false&nonce=4`. This decision to not implement this feature avoids potential confusion caused by unsigned transactions in the queue, especially when multiple transactions share the same nonce, making it unclear which one to act upon. If this feature aligns with your needs, feel free to fork the [script](https://github.com/pcaversaccio/safe-tx-hashes-util/blob/main/safe_hashes.sh) and modify it as necessary. diff --git a/safe_hashes.sh b/safe_hashes.sh index 6e11809..ffb31cf 100755 --- a/safe_hashes.sh +++ b/safe_hashes.sh @@ -77,6 +77,66 @@ readonly SAFE_TX_TYPEHASH_OLD="0x14d461bc7412367e924637b363c7bf29b8f47e2f84869f4 # See: https://github.com/safe-global/safe-smart-account/blob/febab5e4e859e6e65914f17efddee415e4992961/contracts/libraries/SignMessageLib.sol#L12-L13. readonly SAFE_MSG_TYPEHASH="0x60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca" +# Set the trusted (i.e. for delegate calls) `MultiSend` addresses: +# MultiSend `v1.1.1` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.1.1/multi_send.json#L7, +# MultiSend `v1.3.0` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/multi_send.json#L7, +# MultiSend `v1.3.0` (eip155): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/multi_send.json#L11, +# MultiSend `v1.3.0` (zksync): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/multi_send.json#L15, +# Multisend `v1.4.1` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.4.1/multi_send.json#L7. +declare -a -r MultiSend=( + "0x8D29bE29923b68abfDD21e541b9374737B49cdAD" # MultiSend `v1.1.1` (canonical). + "0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761" # MultiSend `v1.3.0` (canonical). + "0x998739BFdAAdde7C933B942a68053933098f9EDa" # MultiSend `v1.3.0` (eip155). + "0x0dFcccB95225ffB03c6FBB2559B530C2B7C8A912" # MultiSend `v1.3.0` (zksync). + "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526" # MultiSend `v1.4.1` (canonical). +) + +# Set the trusted (i.e. for delegate calls) `MultiSendCallOnly` addresses: +# MultiSendCallOnly `v1.3.0` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/multi_send_call_only.json#L7, +# MultiSendCallOnly `v1.3.0` (eip155): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/multi_send_call_only.json#L11, +# MultiSendCallOnly `v1.3.0` (zksync): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/multi_send_call_only.json#L15, +# MultiSendCallOnly `v1.4.1` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.4.1/multi_send_call_only.json#L7. +declare -a -r MultiSendCallOnly=( + "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D" # MultiSendCallOnly `v1.3.0` (canonical). + "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B" # MultiSendCallOnly `v1.3.0` (eip155). + "0xf220D3b4DFb23C4ade8C88E526C1353AbAcbC38F" # MultiSendCallOnly `v1.3.0` (zksync). + "0x9641d764fc13c8B624c04430C7356C1C7C8102e2" # MultiSendCallOnly `v1.4.1` (canonical). +) + +# Set the trusted (i.e. for delegate calls) `SafeMigration` addresses: +# SafeMigration `v1.4.1` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.4.1/safe_migration.json#L7. +declare -a -r SafeMigration=( + "0x526643F69b81B008F46d95CD5ced5eC0edFFDaC6" # SafeMigration `v1.4.1` (canonical). +) + +# Set the trusted (i.e. for delegate calls) `SafeToL2Migration` addresses: +# SafeToL2Migration `v1.4.1` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.4.1/safe_to_l2_migration.json#L7. +declare -a -r SafeToL2Migration=( + "0xfF83F6335d8930cBad1c0D439A841f01888D9f69" # SafeToL2Migration `v1.4.1` (canonical). +) + +# Set the trusted (i.e. for delegate calls) `SignMessageLib` addresses: +# SignMessageLib `v1.3.0` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/sign_message_lib.json#L7, +# SignMessageLib `v1.3.0` (eip155): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/sign_message_lib.json#L11, +# SignMessageLib `v1.3.0` (zksync): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.3.0/sign_message_lib.json#L15, +# SignMessageLib `v1.4.1` (canonical): https://github.com/safe-global/safe-deployments/blob/4e25b09f62a4acec92b4ebe6b8ae496b3852d440/src/assets/v1.4.1/sign_message_lib.json#L7. +declare -a -r SignMessageLib=( + "0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2" # SignMessageLib `v1.3.0` (canonical). + "0x98FFBBF51bb33A056B08ddf711f289936AafF717" # SignMessageLib `v1.3.0` (eip155). + "0x357147caf9C0cCa67DfA0CF5369318d8193c8407" # SignMessageLib `v1.3.0` (zksync). + "0xd53cd0aB83D845Ac265BE939c57F53AD838012c9" # SignMessageLib `v1.4.1` (canonical). +) + +# Set the trusted (i.e. for delegate calls) contract addresses. +# See: https://github.com/safe-global/safe-transaction-service/blob/c3b42f0bebff74b99fcdd958aee54b149e27eca5/safe_transaction_service/contracts/management/commands/setup_safe_contracts.py#L10-L16. +declare -A -r TRUSTED_FOR_DELEGATE_CALL=( + ["MultiSend"]="${MultiSend[@]}" + ["MultiSendCallOnly"]="${MultiSendCallOnly[@]}" + ["SafeMigration"]="${SafeMigration[@]}" + ["SafeToL2Migration"]="${SafeToL2Migration[@]}" + ["SignMessageLib"]="${SignMessageLib[@]}" +) + # Define the supported networks from the Safe transaction service. # See https://docs.safe.global/advanced/smart-account-supported-networks?service=Transaction+Service. declare -A -r API_URLS=( @@ -124,7 +184,7 @@ declare -A -r CHAIN_IDS=( ["scroll"]="534352" ["sepolia"]="11155111" ["worldchain"]="480" - ["xlayer"]="195" + ["xlayer"]="196" ["zksync"]="324" ) @@ -425,6 +485,23 @@ validate_nonce() { fi } +# Utility function to warn the user if the transaction includes an untrusted delegate call. +warn_if_delegate_call() { + local operation="$1" + local to="$2" + + # Warn the user if `operation` equals `1`, implying a `delegatecall`, and if the `to` address is untrusted. + # See: https://github.com/safe-global/safe-smart-account/blob/34359e8305d618b7d74e39ed370a6b59ab14f827/contracts/libraries/Enum.sol. + if [[ "$operation" -eq 1 && ! " ${TRUSTED_FOR_DELEGATE_CALL[@]} " =~ " ${to} " ]]; then + echo + cat <