Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions action-scripts/brownie/scripts/script_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from prettytable import MARKDOWN, PrettyTable
from safe_cli.tx_builder.tx_builder_file_decoder import (
encode_contract_method_to_hex_data,
_parse_types_to_encoding_types,
)
import safe_cli.tx_builder.tx_builder_file_decoder as decoder_module
from safe_eth.eth import EthereumClient
Expand Down Expand Up @@ -280,8 +281,31 @@ def run_tenderly_sim(network_id: str, safe_addr: str, transactions: list[dict]):
address=to_checksum_address(tx["to"]), abi=[tx["contractMethod"]]
)

# Store original parse function
# Store original functions
original_parse_func = decoder_module.parse_input_value
original_parse_types_func = decoder_module._parse_types_to_encoding_types

# Fix for safe_cli bug: _parse_types_to_encoding_types doesn't handle tuple[] correctly
def fixed_parse_types_to_encoding_types(contract_fields):
"""Fixed version that correctly handles tuple[] types."""
types = []
for field in contract_fields:
field_type = field["type"]
if field_type.startswith("tuple"):
component_types = ",".join(
component["type"] for component in field["components"]
)
# Preserve array suffix (e.g., "[]" for tuple[])
suffix = field_type[5:] # Everything after "tuple"
types.append(f"({component_types}){suffix}")
else:
types.append(field_type)
return types

# Monkey-patch the type parser
decoder_module._parse_types_to_encoding_types = (
fixed_parse_types_to_encoding_types
)

# Monkey-patch to handle Safe's JSON format with quoted array elements
def enhanced_parse_input_value(field_type, value):
Expand Down Expand Up @@ -373,13 +397,21 @@ def unquote(obj):
fn_name=tx["contractMethod"]["name"], args=[]
)
finally:
# Restore original function
# Restore original functions
decoder_module.parse_input_value = original_parse_func
decoder_module._parse_types_to_encoding_types = (
original_parse_types_func
)

# build multicall data
multisend_call_only = MultiSend.MULTISEND_CALL_ONLY_ADDRESSES[0]
txs = [
MultiSendTx(MultiSendOperation.CALL, to_checksum_address(tx["to"]), int(tx["value"]), tx["data"])
MultiSendTx(
MultiSendOperation.CALL,
to_checksum_address(tx["to"]),
int(tx["value"]),
tx["data"],
)
for tx in transactions
]
data = MultiSend(EthereumClient(web3.provider.endpoint_uri)).build_tx_data(txs)
Expand Down