You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Inconsistent method decoding in data-decoder endpoint across networks
Issue Description
The /api/v1/data-decoder endpoint shows inconsistent behavior when decoding methods across different networks (Base, Polygon, Mainnet). Methods are not being decoded even when:
The contracts are verified and available in the /api/v1/contracts/{address} endpoint
Their ABIs are loaded in the transaction indexer
The contracts are not part of the hardcoded ABIs (/contracts/decoder_abis/)
The endpoint should be able to decode methods from contracts that:
Are verified in the transaction indexer
Have their ABIs loaded and available through the /api/v1/contracts/{address} endpoint
Even if they're not part of the hardcoded ABIs in decoder_abis
Actual Behavior
Only decodes methods that are part of the hardcoded ABIs in decoder_abis
Returns fallback for any method not in these ABIs
Ignores available ABIs from verified contracts in the transaction indexer
This limitation exists across all networks (Base, Polygon, Mainnet)
Suggested Solutions
Technical Analysis of the Transaction Decoder Issue
Class Hierarchy and Initialization
After analyzing the codebase, I've identified the root cause of the issue is in the transaction decoding architecture. There's a class inheritance structure:
Initializes with a method __init__ that loads ABIs into self.fn_selectors_with_abis
Gets supported ABIs from get_supported_abis() which only returns hardcoded Safe contract ABIs
This dictionary maps function selectors (first 4 bytes of calldata) to ABIs
TxDecoder (Middle Class):
Extends SafeTxDecoder
Overrides get_supported_abis() to include additional hardcoded ABIs (ERC20, etc.)
Adds multisend decoding capability
DbTxDecoder (Top Class):
Extends TxDecoder
Overrides get_supported_abis() to include ABIs from the database
Adds a method get_contract_abi() to fetch ABIs for specific contracts
Overrides get_abi_function() to attempt to use contract-specific ABIs when available
The Critical Issue
The problem occurs in the get_abi_function method in DbTxDecoder:
defget_abi_function(self, data: bytes, address: Optional[ChecksumAddress] =None) ->Optional[ABIFunction]:
selector=data[:4]
# Check first that selector is supported in our databaseifselectorinself.fn_selectors_with_abis:
# Try to use specific ABI if address providedifaddress:
contract_selectors_with_abis=self.get_contract_abi(address)
ifcontract_selectors_with_abisandselectorincontract_selectors_with_abis:
# If the selector is available in the abi specific for the address we will use that onereturncontract_selectors_with_abis[selector]
returnself.fn_selectors_with_abis[selector]
The fundamental problem is:
The function first checks if the selector exists in self.fn_selectors_with_abis
This dictionary is populated during initialization with ABIs from get_supported_abis()
Despite DbTxDecoder overriding get_supported_abis() to include database ABIs, it only loads the ABIs present in the database at service startup time
The critical limitation: If a contract ABI is added to the database after the service starts, or if a contract selector wasn't included in the initial loading, it will NEVER be used even if:
The contract is verified in the database
A valid ABI exists for that contract in the database
The API can serve that ABI through /api/v1/contracts/{address}/
Detailed Flow Explanation
When a request hits the /api/v1/data-decoder/ endpoint, DataDecoderView processes it
The view calls get_data_decoded_from_data()
This function gets a DbTxDecoder instance via get_db_tx_decoder()
The decoder attempts to decode the data using get_data_decoded()
Inside this method, it calls decode_transaction_with_types() which uses get_abi_function()
get_abi_function() first checks if the selector exists in the preloaded ABIs before attempting to fetch the contract-specific ABI
If the selector doesn't exist in preloaded ABIs, it returns None and decoding fails, returning a fallback response
The Specific Bug
The implementation creates a "gatekeeper" pattern where get_abi_function() checks if a selector exists in the preloaded pool before attempting to use contract-specific ABIs. This has two key problems:
It doesn't attempt to use contract-specific ABIs unless the selector is already known
It effectively ignores all verified contracts with ABIs in the database that weren't present when the service started
This design prevents the service from utilizing the complete set of ABIs available in the system, particularly for any contract added after service initialization or for any method that isn't part of the common hardcoded ABIs in the /decoder_abis/ directory.
Impact
This limitation affects the usability of the Safe Transaction Service, especially when:
Interacting with newer or custom contracts
Working with contracts that aren't part of the standard protocols in decoder_abis
Trying to decode methods from verified contracts that should be available in the indexer
The text was updated successfully, but these errors were encountered:
Uh oh!
There was an error while loading. Please reload this page.
Inconsistent method decoding in data-decoder endpoint across networks
Issue Description
The
/api/v1/data-decoder
endpoint shows inconsistent behavior when decoding methods across different networks (Base, Polygon, Mainnet). Methods are not being decoded even when:/api/v1/contracts/{address}
endpoint/contracts/decoder_abis/
)Steps to Reproduce
Mainnet
URL: https://safe-transaction-mainnet.safe.global/
Contract:
0xB4EFd85c19999D84251304bDA99E90B92300Bd93
Polygon
URL: https://safe-transaction-polygon.safe.global/
Contract:
0x062FfE63b7A0d7f27A8105e717c6Ea45E5848AD3
Base
URL: https://safe-transaction-base.safe.global/
Contract:
0x2C8bC3198903DE6b61C1E1aA449578863Af3ccE7
Verification Steps
All contracts can be verified to have their ABIs loaded by checking:
None of these methods are present in the hardcoded ABIs in decoder_abis folder:
Expected Behavior
The endpoint should be able to decode methods from contracts that:
Actual Behavior
Suggested Solutions
Technical Analysis of the Transaction Decoder Issue
Class Hierarchy and Initialization
After analyzing the codebase, I've identified the root cause of the issue is in the transaction decoding architecture. There's a class inheritance structure:
Initialization Flow
SafeTxDecoder (Base Class):
__init__
that loads ABIs intoself.fn_selectors_with_abis
get_supported_abis()
which only returns hardcoded Safe contract ABIsTxDecoder (Middle Class):
SafeTxDecoder
get_supported_abis()
to include additional hardcoded ABIs (ERC20, etc.)DbTxDecoder (Top Class):
TxDecoder
get_supported_abis()
to include ABIs from the databaseget_contract_abi()
to fetch ABIs for specific contractsget_abi_function()
to attempt to use contract-specific ABIs when availableThe Critical Issue
The problem occurs in the
get_abi_function
method inDbTxDecoder
:The fundamental problem is:
self.fn_selectors_with_abis
get_supported_abis()
DbTxDecoder
overridingget_supported_abis()
to include database ABIs, it only loads the ABIs present in the database at service startup time/api/v1/contracts/{address}/
Detailed Flow Explanation
/api/v1/data-decoder/
endpoint,DataDecoderView
processes itget_data_decoded_from_data()
DbTxDecoder
instance viaget_db_tx_decoder()
get_data_decoded()
decode_transaction_with_types()
which usesget_abi_function()
get_abi_function()
first checks if the selector exists in the preloaded ABIs before attempting to fetch the contract-specific ABINone
and decoding fails, returning a fallback responseThe Specific Bug
The implementation creates a "gatekeeper" pattern where
get_abi_function()
checks if a selector exists in the preloaded pool before attempting to use contract-specific ABIs. This has two key problems:This design prevents the service from utilizing the complete set of ABIs available in the system, particularly for any contract added after service initialization or for any method that isn't part of the common hardcoded ABIs in the
/decoder_abis/
directory.Impact
This limitation affects the usability of the Safe Transaction Service, especially when:
The text was updated successfully, but these errors were encountered: