@@ -559,22 +559,33 @@ def str_to_slot(text):
559559 except ApeException :
560560 pass
561561
562- # safe >=1.1.0 provides `masterCopy()`, which is also stored in slot 0
563- # call it and check that target matches
564- try :
565- singleton = ContractCall (MASTER_COPY_ABI , address )(skip_trace = True )
566- slot_0 = self .provider .get_storage (address , 0 )
567- target = self .conversion_manager .convert (slot_0 [- 20 :], AddressType )
568- # NOTE: `target` is set in initialized proxies
569- if target != ZERO_ADDRESS and target == singleton :
570- return ProxyInfo (type = ProxyType .GnosisSafe , target = target , abi = MASTER_COPY_ABI )
571-
572- except ApeException :
573- pass
562+ # Safe >1.0.0 provides `masterCopy()`, which is also stored in slot 0.
563+ # Check the bytecode marker first to avoid an extra call for most non-Safe contracts.
564+ master_copy_selector = self .get_method_selector (MASTER_COPY_ABI ).hex ()
565+ safe_master_copy_markers = (
566+ # Safe v1.1.0 through v1.4.1 compares calldata against a padded PUSH32.
567+ f"7f{ master_copy_selector } { '00' * 28 } " ,
568+ # Optimized builds may reconstruct the same padded selector with PUSH4 + SHL.
569+ "63530ca43760e11b14" ,
570+ # Safe v1.5.0+ compares the first 4 calldata bytes against a PUSH4.
571+ f"63{ master_copy_selector } " ,
572+ )
573+ if any (marker in code for marker in safe_master_copy_markers ):
574+ try :
575+ slot_0 = self .provider .get_storage (address , 0 )
576+ target = self .conversion_manager .convert (slot_0 [- 20 :], AddressType )
577+ # NOTE: `target` is set in initialized proxies
578+ if target != ZERO_ADDRESS and target == ContractCall (MASTER_COPY_ABI , address )(
579+ skip_trace = True
580+ ):
581+ return ProxyInfo (type = ProxyType .GnosisSafe , target = target , abi = MASTER_COPY_ABI )
582+
583+ except ApeException :
584+ pass
574585
575586 # eip-897 delegate proxy, read `proxyType()` and `implementation()`
576587 # perf: only make a call when a proxyType() selector is mentioned in the code
577- eip897_pattern = b"\x63 " + keccak ( text = "proxyType()" )[: 4 ]
588+ eip897_pattern = b"\x63 " + self . get_method_selector ( PROXY_TYPE_ABI )
578589 if eip897_pattern .hex () in code :
579590 try :
580591 proxy_type = ContractCall (PROXY_TYPE_ABI , address )(skip_trace = True )
0 commit comments