Пример #1
0
    def __init__(self, w3: Web3, master_copy_address: str,
                 proxy_factory_address: str):
        """
        Init builder for safe creation using create2
        :param w3: Web3 instance
        :param master_copy_address: `Gnosis Safe` master copy address
        :param proxy_factory_address: `Gnosis Proxy Factory` address
        """
        assert Web3.isChecksumAddress(master_copy_address)
        assert Web3.isChecksumAddress(proxy_factory_address)

        self.w3 = w3
        self.master_copy_address = master_copy_address
        self.proxy_factory_address = proxy_factory_address
        self.safe_version = (get_safe_contract(
            w3, master_copy_address).functions.VERSION().call())
        if self.safe_version == "1.3.0":
            self.master_copy_contract = get_safe_V1_3_0_contract(
                w3, master_copy_address)
        elif self.safe_version == "1.1.1":
            self.master_copy_contract = get_safe_V1_1_1_contract(
                w3, master_copy_address)
        elif self.safe_version == "1.0.0":
            self.master_copy_contract = get_safe_V1_0_0_contract(
                w3, master_copy_address)
        else:
            raise ValueError("Safe version must be 1.3.0, 1.1.1 or 1.0.0")
        self.proxy_factory_contract = get_proxy_factory_contract(
            w3, proxy_factory_address)
Пример #2
0
 def get_contract(self) -> Contract:
     v_1_3_0_contract = get_safe_V1_3_0_contract(self.w3,
                                                 address=self.address)
     version = v_1_3_0_contract.functions.VERSION().call()
     if version == "1.3.0":
         return v_1_3_0_contract
     else:
         return get_safe_V1_1_1_contract(self.w3, address=self.address)
Пример #3
0
    def get_supported_abis(self) -> Iterable[ABIFunction]:
        safe_abis = [
            get_safe_V0_0_1_contract(self.dummy_w3).abi,
            get_safe_V1_0_0_contract(self.dummy_w3).abi,
            get_safe_V1_1_1_contract(self.dummy_w3).abi,
            get_safe_V1_3_0_contract(self.dummy_w3).abi,
        ]

        # Order is important. If signature is the same (e.g. renaming of `baseGas`) last elements in the list
        # will take preference
        return safe_abis
Пример #4
0
    def setUpClass(cls):
        super().setUpClass()

        for key, value in _contract_addresses.items():
            if callable(value):
                _contract_addresses[key] = value(
                    cls.ethereum_client,
                    cls.ethereum_test_account).contract_address

        settings.SAFE_DEFAULT_CALLBACK_HANDLER = _contract_addresses[
            "compatibility_fallback_handler"]
        settings.SAFE_MULTISEND_ADDRESS = _contract_addresses["multi_send"]
        settings.SAFE_CONTRACT_ADDRESS = _contract_addresses["safe_v1_3_0"]
        settings.SAFE_V1_1_1_CONTRACT_ADDRESS = _contract_addresses[
            "safe_V1_1_1"]
        settings.SAFE_V1_0_0_CONTRACT_ADDRESS = _contract_addresses[
            "safe_V1_0_0"]
        settings.SAFE_V0_0_1_CONTRACT_ADDRESS = _contract_addresses[
            "safe_V0_0_1"]
        settings.SAFE_PROXY_FACTORY_ADDRESS = _contract_addresses[
            "proxy_factory"]
        settings.SAFE_PROXY_FACTORY_V1_0_0_ADDRESS = _contract_addresses[
            "proxy_factory_V1_0_0"]
        settings.SAFE_VALID_CONTRACT_ADDRESSES = {
            settings.SAFE_CONTRACT_ADDRESS,
            settings.SAFE_V1_1_1_CONTRACT_ADDRESS,
            settings.SAFE_V1_0_0_CONTRACT_ADDRESS,
            settings.SAFE_V0_0_1_CONTRACT_ADDRESS,
        }
        cls.compatibility_fallback_handler = (
            get_compatibility_fallback_handler_V1_3_0_contract(
                cls.w3, _contract_addresses["compatibility_fallback_handler"]))
        cls.safe_contract_address = _contract_addresses["safe_v1_3_0"]
        cls.safe_contract = get_safe_V1_3_0_contract(cls.w3,
                                                     cls.safe_contract_address)
        cls.safe_contract_V1_1_1_address = _contract_addresses["safe_V1_1_1"]
        cls.safe_contract_V1_1_1 = get_safe_V1_1_1_contract(
            cls.w3, cls.safe_contract_V1_1_1_address)
        cls.safe_contract_V1_0_0_address = _contract_addresses["safe_V1_0_0"]
        cls.safe_contract_V1_0_0 = get_safe_V1_0_0_contract(
            cls.w3, cls.safe_contract_V1_0_0_address)
        cls.safe_contract_V0_0_1_address = _contract_addresses["safe_V0_0_1"]
        cls.safe_contract_V0_0_1 = get_safe_V1_0_0_contract(
            cls.w3, cls.safe_contract_V0_0_1_address)
        cls.proxy_factory_contract_address = _contract_addresses[
            "proxy_factory"]
        cls.proxy_factory_contract = get_proxy_factory_contract(
            cls.w3, cls.proxy_factory_contract_address)
        cls.proxy_factory = ProxyFactory(cls.proxy_factory_contract_address,
                                         cls.ethereum_client)
        cls.multi_send_contract = get_multi_send_contract(
            cls.w3, _contract_addresses["multi_send"])
        cls.multi_send = MultiSend(cls.multi_send_contract.address,
                                   cls.ethereum_client)
Пример #5
0
 def is_valid(self, ethereum_client: EthereumClient, *args) -> bool:
     safe_contract = get_safe_V1_1_1_contract(ethereum_client.w3, self.owner)
     # Newest versions of the Safe contract have `isValidSignature` on the compatibility fallback handler
     for block_identifier in ("pending", "latest"):
         try:
             return safe_contract.functions.isValidSignature(
                 self.safe_tx_hash, self.contract_signature
             ).call(block_identifier=block_identifier) in (
                 self.EIP1271_MAGIC_VALUE,
                 self.EIP1271_MAGIC_VALUE_UPDATED,
             )
         except (ValueError, BadFunctionCallOutput, DecodingError):
             # Error using `pending` block identifier or contract does not exist
             logger.warning(
                 "Cannot check EIP1271 signature from contract %s", self.owner
             )
     return False
Пример #6
0
 def __init__(self, address: str, node_url: str):
     self.address = address
     self.node_url = node_url
     self.ethereum_client = EthereumClient(self.node_url)
     self.ens = ENS.fromWeb3(self.ethereum_client.w3)
     self.network: EthereumNetwork = self.ethereum_client.get_network()
     self.etherscan = EtherscanApi.from_ethereum_client(
         self.ethereum_client)
     self.safe_relay_service = RelayServiceApi.from_ethereum_client(
         self.ethereum_client)
     self.safe_tx_service = TransactionServiceApi.from_ethereum_client(
         self.ethereum_client)
     self.safe = Safe(address, self.ethereum_client)
     self.safe_contract = self.safe.get_contract()
     self.safe_contract_1_1_0 = get_safe_V1_1_1_contract(
         self.ethereum_client.w3, address=self.address)
     self.accounts: Set[LocalAccount] = set()
     self.default_sender: Optional[LocalAccount] = None
     self.executed_transactions: List[str] = []
     self._safe_cli_info: Optional[
         SafeCliInfo] = None  # Cache for SafeCliInfo
     self.require_all_signatures = (
         True  # Require all signatures to be present to send a tx
     )
Пример #7
0
    def contract_events(self) -> List[ContractEvent]:
        """
        event SafeMultiSigTransaction(
            address to,
            uint256 value,
            bytes data,
            Enum.Operation operation,
            uint256 safeTxGas,
            uint256 baseGas,
            uint256 gasPrice,
            address gasToken,
            address payable refundReceiver,
            bytes signatures,
            // We combine nonce, sender and threshold into one to avoid stack too deep
            // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding
            bytes additionalInfo  // abi.encode(nonce, msg.sender, threshold);
        );

        event SafeModuleTransaction(
            address module,
            address to,
            uint256 value,
            bytes data,
            Enum.Operation operation,
        );

        event SafeSetup(
            address indexed initiator,
            address[] owners,
            uint256 threshold,
            address initializer,
            address fallbackHandler
        );

        event ApproveHash(
            bytes32 indexed approvedHash,
            address indexed owner
        );

        event SignMsg(
            bytes32 indexed msgHash
        );

        event ExecutionFailure(
            bytes32 txHash, uint256 payment
        );

        event ExecutionSuccess(
            bytes32 txHash, uint256 payment
        );

        event EnabledModule(address module);
        event DisabledModule(address module);
        event ExecutionFromModuleSuccess(address indexed module);
        event ExecutionFromModuleFailure(address indexed module);

        event AddedOwner(address owner);
        event RemovedOwner(address owner);
        event ChangedThreshold(uint256 threshold);

        event SafeReceived(address indexed sender, uint256 value);  // Incoming ether

        event ChangedFallbackHandler(address handler);
        event ChangedGuard(address guard);

        # ProxyFactory
        event ProxyCreation(GnosisSafeProxy proxy, address singleton);

        :return:
        """
        l2_contract = self.ethereum_client.w3.eth.contract(
            abi=gnosis_safe_l2_v1_3_0_abi
        )
        proxy_factory_contract = self.ethereum_client.w3.eth.contract(
            abi=proxy_factory_v1_3_0_abi
        )
        old_contract = get_safe_V1_1_1_contract(self.ethereum_client.w3)
        return [
            l2_contract.events.SafeMultiSigTransaction(),
            l2_contract.events.SafeModuleTransaction(),
            l2_contract.events.SafeSetup(),
            l2_contract.events.ApproveHash(),
            l2_contract.events.SignMsg(),
            l2_contract.events.ExecutionFailure(),
            l2_contract.events.ExecutionSuccess(),
            # Modules
            l2_contract.events.EnabledModule(),
            l2_contract.events.DisabledModule(),
            l2_contract.events.ExecutionFromModuleSuccess(),
            l2_contract.events.ExecutionFromModuleFailure(),
            # Owners
            l2_contract.events.AddedOwner(),
            l2_contract.events.RemovedOwner(),
            l2_contract.events.ChangedThreshold(),
            # Incoming Ether
            l2_contract.events.SafeReceived(),
            # Changed FallbackHandler
            l2_contract.events.ChangedFallbackHandler(),
            # Changed Guard
            l2_contract.events.ChangedGuard(),
            # Change Master Copy
            old_contract.events.ChangedMasterCopy(),
            # Proxy creation
            proxy_factory_contract.events.ProxyCreation(),
        ]