Exemple #1
0
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        user_deposit_address: UserDepositAddress,
        contract_manager: ContractManager,
        proxy_manager: "ProxyManager",
    ) -> None:
        if not is_binary_address(user_deposit_address):
            raise ValueError("Expected binary address format for token nework")

        check_address_has_code(
            client=jsonrpc_client,
            address=Address(user_deposit_address),
            contract_name=CONTRACT_USER_DEPOSIT,
            expected_code=decode_hex(
                contract_manager.get_runtime_hexcode(CONTRACT_USER_DEPOSIT)),
        )

        self.client = jsonrpc_client

        self.address = user_deposit_address
        self.node_address = self.client.address
        self.contract_manager = contract_manager
        self.gas_measurements = gas_measurements(
            self.contract_manager.contracts_version)

        self.proxy_manager = proxy_manager

        self.proxy = jsonrpc_client.new_contract_proxy(
            abi=self.contract_manager.get_contract_abi(CONTRACT_USER_DEPOSIT),
            contract_address=Address(user_deposit_address),
        )

        self.deposit_lock = RLock()
Exemple #2
0
def test_custom_token(custom_token: Contract, web3: Web3,
                      contracts_manager: ContractManager) -> None:
    """See custom_token.address contains the expected code"""
    blockchain_bytecode = web3.eth.get_code(custom_token.address)
    compiled_bytecode = contracts_manager.get_runtime_hexcode(
        CONTRACT_CUSTOM_TOKEN)
    assert blockchain_bytecode.hex() == compiled_bytecode
Exemple #3
0
def test_human_standard_token(human_standard_token: Contract, web3: Web3,
                              contracts_manager: ContractManager) -> None:
    """See human_standard_token.address contains the expected code"""
    blockchain_bytecode = web3.eth.get_code(human_standard_token.address)
    compiled_bytecode = contracts_manager.get_runtime_hexcode(
        CONTRACT_HUMAN_STANDARD_TOKEN)
    assert blockchain_bytecode.hex() == compiled_bytecode
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        monitoring_service_address: MonitoringServiceAddress,
        contract_manager: ContractManager,
        block_identifier: BlockIdentifier,
    ):
        if not is_binary_address(monitoring_service_address):
            raise ValueError("Expected binary address for monitoring service")

        check_address_has_code_handle_pruned_block(
            client=jsonrpc_client,
            address=Address(monitoring_service_address),
            contract_name=CONTRACT_MONITORING_SERVICE,
            expected_code=decode_hex(
                contract_manager.get_runtime_hexcode(CONTRACT_MONITORING_SERVICE)
            ),
            given_block_identifier=block_identifier,
        )

        proxy = jsonrpc_client.new_contract_proxy(
            abi=contract_manager.get_contract_abi(CONTRACT_MONITORING_SERVICE),
            contract_address=Address(monitoring_service_address),
        )

        self.address = monitoring_service_address
        self.client = jsonrpc_client
        self.contract_manager = contract_manager
        self.node_address = self.client.address
        self.proxy = proxy
Exemple #5
0
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        service_registry_address: Address,
        contract_manager: ContractManager,
    ):
        if not is_binary_address(service_registry_address):
            raise ValueError("Expected binary address for service registry")

        self.contract_manager = contract_manager
        check_address_has_code(
            client=jsonrpc_client,
            address=service_registry_address,
            contract_name=CONTRACT_SERVICE_REGISTRY,
            expected_code=decode_hex(
                contract_manager.get_runtime_hexcode(
                    CONTRACT_SERVICE_REGISTRY)),
        )

        proxy = jsonrpc_client.new_contract_proxy(
            abi=self.contract_manager.get_contract_abi(
                CONTRACT_SERVICE_REGISTRY),
            contract_address=service_registry_address,
        )

        self.address = service_registry_address
        self.proxy = proxy
        self.client = jsonrpc_client
        self.node_address = self.client.address
Exemple #6
0
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        one_to_n_address: OneToNAddress,
        contract_manager: ContractManager,
        block_identifier: BlockIdentifier,
    ):
        if not is_binary_address(one_to_n_address):
            raise ValueError("Expected binary address for monitoring service")

        self.contract_manager = contract_manager
        check_address_has_code_handle_pruned_block(
            client=jsonrpc_client,
            address=Address(one_to_n_address),
            contract_name=CONTRACT_ONE_TO_N,
            expected_code=decode_hex(
                contract_manager.get_runtime_hexcode(CONTRACT_ONE_TO_N)),
            given_block_identifier=block_identifier,
        )

        proxy = jsonrpc_client.new_contract_proxy(
            abi=self.contract_manager.get_contract_abi(CONTRACT_ONE_TO_N),
            contract_address=Address(one_to_n_address),
        )

        self.address = one_to_n_address
        self.proxy = proxy
        self.client = jsonrpc_client
        self.node_address = self.client.address
Exemple #7
0
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        user_deposit_address: UserDepositAddress,
        contract_manager: ContractManager,
        proxy_manager: "ProxyManager",
        block_identifier: BlockIdentifier,
    ) -> None:
        if not is_binary_address(user_deposit_address):
            raise ValueError("Expected binary address format for token nework")

        check_address_has_code_handle_pruned_block(
            client=jsonrpc_client,
            address=Address(user_deposit_address),
            contract_name=CONTRACT_USER_DEPOSIT,
            expected_code=decode_hex(
                contract_manager.get_runtime_hexcode(CONTRACT_USER_DEPOSIT)),
            given_block_identifier=block_identifier,
        )

        self.client = jsonrpc_client

        self.address = user_deposit_address
        self.node_address = self.client.address
        self.contract_manager = contract_manager
        self.gas_measurements = gas_measurements(
            self.contract_manager.contracts_version)

        self.proxy_manager = proxy_manager

        self.proxy = jsonrpc_client.new_contract_proxy(
            abi=self.contract_manager.get_contract_abi(CONTRACT_USER_DEPOSIT),
            contract_address=Address(user_deposit_address),
        )

        # Keeps track of the current in-flight deposits, to avoid sending
        # unecessary transactions.
        self._inflight_deposits: Dict[Address, InflightDeposit] = dict()

        # Don't allow concurrent withdraw_plan and withdraw calls.
        # This simplifies the precondition checks.
        self._withdraw_lock = Lock()
Exemple #8
0
    def __init__(
        self,
        jsonrpc_client: JSONRPCClient,
        secret_registry_address: SecretRegistryAddress,
        contract_manager: ContractManager,
        block_identifier: BlockIdentifier,
    ) -> None:
        if not is_binary_address(secret_registry_address):
            raise ValueError(
                "Expected binary address format for secret registry")

        self.contract_manager = contract_manager
        check_address_has_code_handle_pruned_block(
            client=jsonrpc_client,
            address=Address(secret_registry_address),
            contract_name=CONTRACT_SECRET_REGISTRY,
            expected_code=decode_hex(
                contract_manager.get_runtime_hexcode(
                    CONTRACT_SECRET_REGISTRY)),
            given_block_identifier=block_identifier,
        )

        proxy = jsonrpc_client.new_contract_proxy(
            abi=self.contract_manager.get_contract_abi(
                CONTRACT_SECRET_REGISTRY),
            contract_address=Address(secret_registry_address),
        )

        # There should be only one smart contract deployed, to avoid race
        # conditions for on-chain unlocks.

        self.address = secret_registry_address
        self.proxy = proxy
        self.client = jsonrpc_client
        self.node_address = self.client.address

        # The dictionary of open transactions is used to avoid sending a
        # transaction for the same secret more than once. This requires
        # synchronization for the local threads.
        self.open_secret_transactions: Dict[Secret, AsyncResult] = dict()
        self._open_secret_transactions_lock = Semaphore()
class ContractVerifier:
    def __init__(self, web3: Web3, contracts_version: Optional[str] = None):
        self.web3 = web3
        self.contracts_version = contracts_version
        self.precompiled_path = contracts_precompiled_path(
            self.contracts_version)
        self.contract_manager = ContractManager(self.precompiled_path)

    def verify_deployed_contracts_in_filesystem(self) -> None:
        chain_id = ChainID(self.web3.eth.chain_id)

        deployment_data = get_contracts_deployment_info(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
            module=DeploymentModule.RAIDEN,
        )
        deployment_file_path = contracts_deployed_path(
            chain_id=chain_id, version=self.contract_manager.contracts_version)
        if deployment_data is None:
            raise RuntimeError(
                f"Deployment data cannot be found at {deployment_file_path}")

        if self.verify_deployment_data(deployment_data):
            print(
                f"Deployment info from {deployment_file_path} has been verified "
                "and it is CORRECT.")

    def verify_deployed_service_contracts_in_filesystem(
        self,
        token_address: HexAddress,
        user_deposit_whole_balance_limit: int,
        token_network_registry_address: HexAddress,
    ) -> None:
        chain_id = ChainID(self.web3.eth.chain_id)

        deployment_data = get_contracts_deployment_info(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
            module=DeploymentModule.SERVICES,
        )
        deployment_file_path = contracts_deployed_path(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
            services=True)
        if deployment_data is None:
            raise RuntimeError(
                f"Deployment data cannot be found at {deployment_file_path}")

        if self.verify_service_contracts_deployment_data(
                token_address=token_address,
                user_deposit_whole_balance_limit=
                user_deposit_whole_balance_limit,
                deployed_contracts_info=deployment_data,
                token_network_registry_address=token_network_registry_address,
        ):
            print(
                f"Deployment info from {deployment_file_path} has been verified "
                "and it is CORRECT.")

    def store_and_verify_deployment_info_raiden(
            self, deployed_contracts_info: DeployedContracts) -> None:
        self._store_deployment_info(deployment_info=deployed_contracts_info,
                                    services=False)
        self.verify_deployed_contracts_in_filesystem()

    def store_and_verify_deployment_info_services(
        self,
        deployed_contracts_info: DeployedContracts,
        token_address: HexAddress,
        user_deposit_whole_balance_limit: int,
        token_network_registry_address: HexAddress,
    ) -> None:
        self._store_deployment_info(services=True,
                                    deployment_info=deployed_contracts_info)
        self.verify_deployed_service_contracts_in_filesystem(
            token_address=token_address,
            user_deposit_whole_balance_limit=user_deposit_whole_balance_limit,
            token_network_registry_address=token_network_registry_address,
        )

    def _store_deployment_info(self, services: bool,
                               deployment_info: DeployedContracts) -> None:
        deployment_file_path = contracts_deployed_path(
            chain_id=ChainID(self.web3.eth.chain_id),
            version=self.contracts_version,
            services=services,
        )
        with deployment_file_path.open(mode="w") as target_file:
            target_file.write(json.dumps(deployment_info, indent=2))

        print(
            f'Deployment information for chain id = {deployment_info["chain_id"]} '
            f" has been updated at {deployment_file_path}.")

    def verify_deployment_data(self,
                               deployment_data: DeployedContracts) -> bool:
        chain_id = self.web3.eth.chain_id

        if self.contract_manager.contracts_version != deployment_data[
                "contracts_version"]:
            raise RuntimeError("Version string mismatch.")
        if chain_id != deployment_data["chain_id"]:
            raise RuntimeError("chain id mismatch.")

        secret_registry, _ = self._verify_deployed_contract(
            deployment_data=deployment_data,
            contract_name=CONTRACT_SECRET_REGISTRY)

        token_network_registry, constructor_arguments = self._verify_deployed_contract(
            deployment_data=deployment_data,
            contract_name=CONTRACT_TOKEN_NETWORK_REGISTRY)

        # We need to also check the constructor parameters against the chain
        if (to_checksum_address(token_network_registry.functions.
                                secret_registry_address().call()) !=
                secret_registry.address):
            raise RuntimeError(
                "secret_registry_address onchain has an unexpected value.")
        if len(constructor_arguments) != 5:
            raise RuntimeError(
                "TokenNetworkRegistry received a wrong number of constructor arguments."
            )
        if secret_registry.address != constructor_arguments[0]:
            raise RuntimeError(
                "TokenNetworkRegistry's constructor received a different SecretRegistry address."
            )
        if token_network_registry.functions.chain_id().call(
        ) != constructor_arguments[1]:
            raise RuntimeError("TokenNetwork remembers a wrong chain_id.")
        assert (token_network_registry.functions.settlement_timeout_min().call(
        ) == constructor_arguments[2])
        assert (token_network_registry.functions.settlement_timeout_max().call(
        ) == constructor_arguments[3])

        return True

    def _verify_deployed_contract(
            self, deployment_data: DeployedContracts,
            contract_name: str) -> Tuple[Contract, List[Any]]:
        """Verify deployment info against the chain

        Verifies:
        - the runtime bytecode - precompiled data against the chain
        - information stored in deployment_*.json against the chain,
        except for the constructor arguments, which have to be checked
        separately.

        Returns: (onchain_instance, constructor_arguments)
        """
        contract_instance = self.contract_instance_from_deployment_data(
            deployment_data, contract_name)
        contracts = deployment_data["contracts"]

        # Check blockchain transaction hash & block information
        receipt = self.web3.eth.getTransactionReceipt(
            contracts[contract_name]["transaction_hash"])
        if receipt["blockNumber"] != contracts[contract_name]["block_number"]:
            raise RuntimeError(
                f'We have block_number {contracts[contract_name]["block_number"]} in the '
                f'deployment info, but {receipt["blockNumber"]} in the transaction receipt '
                "from web3.")
        if receipt["gasUsed"] != contracts[contract_name]["gas_cost"]:
            raise RuntimeError(
                f'We have gasUsed {contracts[contract_name]["gas_cost"]} in the deployment info, '
                f'but {receipt["gasUsed"]} in the transaction receipt from web3.'
            )
        if receipt["contractAddress"] != contracts[contract_name]["address"]:
            raise RuntimeError(
                f'We have contractAddress {contracts[contract_name]["address"]} in the deployment'
                f' info but {receipt["contractAddress"]} in the transaction receipt from web3.'
            )

        # Check that the deployed bytecode matches the precompiled data
        blockchain_bytecode = self.web3.eth.get_code(
            contract_instance.address).hex()
        compiled_bytecode = self.contract_manager.get_runtime_hexcode(
            contract_name)

        if contract_name == CONTRACT_TOKEN_NETWORK_REGISTRY:
            # We need to link the libs into the contract bytecode.
            # As this is run in the tests in fake file systems, do poor mans linking here
            compiled_bytecode = link_bytecode(
                unlinked_bytecode=compiled_bytecode,
                library_identifier=LIBRARY_TOKEN_NETWORK_UTILS_LINK_KEY,
                library_address=contracts[LIBRARY_TOKEN_NETWORK_UTILS]
                ["address"],
            )

        if blockchain_bytecode == compiled_bytecode:
            print(f"{contract_name} at {contract_instance.address} "
                  f"matches the compiled data from contracts.json")
        else:
            raise RuntimeError(
                f"{contract_name} at {contract_instance.address} has wrong code"
            )

        return contract_instance, contracts[contract_name][
            "constructor_arguments"]

    def contract_instance_from_deployment_data(
            self, deployment_data: DeployedContracts,
            contract_name: str) -> Contract:
        contracts = deployment_data["contracts"]
        contract_address = contracts[contract_name]["address"]
        contract_instance = self.web3.eth.contract(
            abi=self.contract_manager.get_contract_abi(contract_name),
            address=contract_address)
        return contract_instance

    def verify_service_contracts_deployment_data(
        self,
        token_address: HexAddress,
        user_deposit_whole_balance_limit: int,
        token_network_registry_address: HexAddress,
        deployed_contracts_info: DeployedContracts,
    ) -> bool:
        chain_id = self.web3.eth.chain_id
        assert deployed_contracts_info is not None

        if self.contract_manager.contracts_version != deployed_contracts_info[
                "contracts_version"]:
            raise RuntimeError("Version string mismatch")
        if chain_id != deployed_contracts_info["chain_id"]:
            raise RuntimeError("chain_id mismatch")

        (
            service_registry,
            service_registry_constructor_arguments,
        ) = self._verify_deployed_contract(
            deployment_data=deployed_contracts_info,
            contract_name=CONTRACT_SERVICE_REGISTRY)
        (
            user_deposit,
            user_deposit_constructor_arguments,
        ) = self._verify_deployed_contract(
            deployment_data=deployed_contracts_info,
            contract_name=CONTRACT_USER_DEPOSIT)
        one_to_n, one_to_n_constructor_arguments = self._verify_deployed_contract(
            deployment_data=deployed_contracts_info,
            contract_name=CONTRACT_ONE_TO_N)
        monitoring_service, ms_constructor_arguments = self._verify_deployed_contract(
            deployed_contracts_info, CONTRACT_MONITORING_SERVICE)
        _verify_service_registry_deployment(
            service_registry=service_registry,
            constructor_arguments=service_registry_constructor_arguments,
            token_address=token_address,
        )
        _verify_user_deposit_deployment(
            user_deposit=user_deposit,
            constructor_arguments=user_deposit_constructor_arguments,
            token_address=token_address,
            user_deposit_whole_balance_limit=user_deposit_whole_balance_limit,
            one_to_n_address=one_to_n.address,
            monitoring_service_address=monitoring_service.address,
        )
        _verify_monitoring_service_deployment(
            monitoring_service=monitoring_service,
            constructor_arguments=ms_constructor_arguments,
            token_address=token_address,
            service_registry_address=service_registry.address,
            user_deposit_address=user_deposit.address,
            token_network_registry_address=token_network_registry_address,
        )
        _verify_one_to_n_deployment(
            one_to_n=one_to_n,
            constructor_arguments=one_to_n_constructor_arguments,
            user_deposit_address=user_deposit.address,
            chain_id=chain_id,
            service_registry_address=service_registry.address,
        )
        return True
Exemple #10
0
class ContractVerifier:
    def __init__(self, web3: Web3, contracts_version: Optional[str] = None):
        self.web3 = web3
        self.contracts_version = contracts_version
        self.precompiled_path = contracts_precompiled_path(
            self.contracts_version)
        self.contract_manager = ContractManager(self.precompiled_path)

    def verify_deployed_contracts_in_filesystem(self) -> None:
        chain_id = int(self.web3.version.network)

        deployment_data = get_contracts_deployment_info(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
            module=DeploymentModule.RAIDEN,
        )
        deployment_file_path = contracts_deployed_path(
            chain_id=chain_id, version=self.contract_manager.contracts_version)
        if deployment_data is None:
            raise RuntimeError(
                f"Deployment data cannot be found at {deployment_file_path}")

        if self.verify_deployment_data(deployment_data):
            print(
                f"Deployment info from {deployment_file_path} has been verified"
                "and it is CORRECT.")

    def verify_deployed_service_contracts_in_filesystem(
            self, token_address: HexAddress,
            user_deposit_whole_balance_limit: int) -> None:
        chain_id = int(self.web3.version.network)

        deployment_data = get_contracts_deployment_info(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
            module=DeploymentModule.SERVICES,
        )
        deployment_file_path = contracts_deployed_path(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
            services=True)
        if deployment_data is None:
            raise RuntimeError(
                f"Deployment data cannot be found at {deployment_file_path}")

        if self.verify_service_contracts_deployment_data(
                token_address=token_address,
                user_deposit_whole_balance_limit=
                user_deposit_whole_balance_limit,
                deployed_contracts_info=deployment_data,
        ):
            print(
                f"Deployment info from {deployment_file_path} has been verified "
                "and it is CORRECT.")

    def store_and_verify_deployment_info_raiden(
            self, deployed_contracts_info: DeployedContracts) -> None:
        self._store_deployment_info(deployment_info=deployed_contracts_info,
                                    services=False)
        self.verify_deployed_contracts_in_filesystem()

    def store_and_verify_deployment_info_services(
        self,
        deployed_contracts_info: DeployedContracts,
        token_address: HexAddress,
        user_deposit_whole_balance_limit: int,
    ) -> None:
        self._store_deployment_info(services=True,
                                    deployment_info=deployed_contracts_info)
        self.verify_deployed_service_contracts_in_filesystem(
            token_address=token_address,
            user_deposit_whole_balance_limit=user_deposit_whole_balance_limit,
        )

    def _store_deployment_info(self, services: bool,
                               deployment_info: DeployedContracts) -> None:
        deployment_file_path = contracts_deployed_path(
            chain_id=int(self.web3.version.network),
            version=self.contracts_version,
            services=services,
        )
        with deployment_file_path.open(mode="w") as target_file:
            target_file.write(json.dumps(deployment_info))

        print(
            f'Deployment information for chain id = {deployment_info["chain_id"]} '
            f" has been updated at {deployment_file_path}.")

    def verify_deployment_data(self,
                               deployment_data: DeployedContracts) -> bool:
        chain_id = int(self.web3.version.network)
        assert deployment_data is not None

        if self.contract_manager.version_string != deployment_data[
                "contracts_version"]:
            raise RuntimeError("Version string mismatch.")
        if chain_id != deployment_data["chain_id"]:
            raise RuntimeError("chain id mismatch.")

        self._verify_deployed_contract(
            deployment_data=deployment_data,
            contract_name=CONTRACT_ENDPOINT_REGISTRY)

        secret_registry, _ = self._verify_deployed_contract(
            deployment_data=deployment_data,
            contract_name=CONTRACT_SECRET_REGISTRY)

        token_network_registry, constructor_arguments = self._verify_deployed_contract(
            deployment_data=deployment_data,
            contract_name=CONTRACT_TOKEN_NETWORK_REGISTRY)

        # We need to also check the constructor parameters against the chain
        assert (to_checksum_address(
            token_network_registry.functions.secret_registry_address().call())
                == secret_registry.address)
        assert secret_registry.address == constructor_arguments[0]
        assert token_network_registry.functions.chain_id().call(
        ) == constructor_arguments[1]
        assert (token_network_registry.functions.settlement_timeout_min().call(
        ) == constructor_arguments[2])
        assert (token_network_registry.functions.settlement_timeout_max().call(
        ) == constructor_arguments[3])

        return True

    def _verify_deployed_contract(self, deployment_data: DeployedContracts,
                                  contract_name: str) -> Contract:
        """ Verify deployment info against the chain

        Verifies:
        - the runtime bytecode - precompiled data against the chain
        - information stored in deployment_*.json against the chain,
        except for the constructor arguments, which have to be checked
        separately.

        Returns: (onchain_instance, constructor_arguments)
        """
        contracts = deployment_data["contracts"]

        contract_address = contracts[contract_name]["address"]
        contract_instance = self.web3.eth.contract(
            abi=self.contract_manager.get_contract_abi(contract_name),
            address=contract_address)

        # Check blockchain transaction hash & block information
        receipt = self.web3.eth.getTransactionReceipt(
            contracts[contract_name]["transaction_hash"])
        if receipt["blockNumber"] != contracts[contract_name]["block_number"]:
            raise RuntimeError(
                f'We have block_number {contracts[contract_name]["block_number"]} in the '
                f'deployment info, but {receipt["blockNumber"]} in the transaction receipt'
                "from web3.")
        if receipt["gasUsed"] != contracts[contract_name]["gas_cost"]:
            raise RuntimeError(
                f'We have gasUsed {contracts[contract_name]["gas_cost"]} in the deployment info, '
                f'but {receipt["gasUsed"]} in the transaction receipt from web3.'
            )
        if receipt["contractAddress"] != contracts[contract_name]["address"]:
            raise RuntimeError(
                f'We have contractAddress {contracts[contract_name]["address"]} in the deployment'
                f' info but {receipt["contractAddress"]} in the transaction receipt from web3.'
            )

        # Check that the deployed bytecode matches the precompiled data
        blockchain_bytecode = self.web3.eth.getCode(contract_address).hex()
        compiled_bytecode = self.contract_manager.get_runtime_hexcode(
            contract_name)
        if blockchain_bytecode == compiled_bytecode:
            print(f"{contract_name} at {contract_address} "
                  f"matches the compiled data from contracts.json")
        else:
            raise RuntimeError(
                f"{contract_name} at {contract_address} has wrong code")

        # Check the contract version
        version = contract_instance.functions.contract_version().call()

        # It's an assert because the caller of this function should have checked this.
        assert version == deployment_data["contracts_version"], (
            f'got {version} expected {deployment_data["contracts_version"]}. '
            "contract_manager has contracts_version"
            f"{self.contract_manager.contracts_version}")

        return contract_instance, contracts[contract_name][
            "constructor_arguments"]

    def verify_service_contracts_deployment_data(
        self,
        token_address: HexAddress,
        user_deposit_whole_balance_limit: int,
        deployed_contracts_info: DeployedContracts,
    ) -> bool:
        chain_id = int(self.web3.version.network)
        assert deployed_contracts_info is not None

        if self.contract_manager.version_string != deployed_contracts_info[
                "contracts_version"]:
            raise RuntimeError("Version string mismatch")
        if chain_id != deployed_contracts_info["chain_id"]:
            raise RuntimeError("chain_id mismatch")

        service_registry, service_registry_constructor_arguments = self._verify_deployed_contract(
            deployment_data=deployed_contracts_info,
            contract_name=CONTRACT_SERVICE_REGISTRY)
        user_deposit, user_deposit_constructor_arguments = self._verify_deployed_contract(
            deployment_data=deployed_contracts_info,
            contract_name=CONTRACT_USER_DEPOSIT)
        one_to_n, one_to_n_constructor_arguments = self._verify_deployed_contract(
            deployment_data=deployed_contracts_info,
            contract_name=CONTRACT_ONE_TO_N)
        monitoring_service, ms_constructor_arguments = self._verify_deployed_contract(
            deployed_contracts_info, CONTRACT_MONITORING_SERVICE)
        _verify_service_registry_deployment(
            service_registry=service_registry,
            constructor_arguments=service_registry_constructor_arguments,
            token_address=token_address,
        )
        _verify_user_deposit_deployment(
            user_deposit=user_deposit,
            constructor_arguments=user_deposit_constructor_arguments,
            token_address=token_address,
            user_deposit_whole_balance_limit=user_deposit_whole_balance_limit,
            one_to_n_address=one_to_n.address,
            monitoring_service_address=monitoring_service.address,
        )
        _verify_monitoring_service_deployment(
            monitoring_service=monitoring_service,
            constructor_arguments=ms_constructor_arguments,
            token_address=token_address,
            service_registry_address=service_registry.address,
            user_deposit_address=user_deposit.address,
        )
        _verify_one_to_n_deployment(
            one_to_n=one_to_n,
            constructor_arguments=one_to_n_constructor_arguments,
            user_deposit_address=user_deposit.address,
            chain_id=chain_id,
        )
        return True