Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Uxio0 committed Oct 11, 2023
1 parent b934f11 commit 89367ab
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 40 deletions.
3 changes: 2 additions & 1 deletion gnosis/eth/ethereum_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
from .exceptions import (
BatchCallFunctionFailed,
ChainIdIsRequired,
ContractAlreadyDeployed,
FromAddressNotFound,
GasLimitExceeded,
InsufficientFunds,
Expand Down Expand Up @@ -1472,7 +1473,7 @@ def deploy_and_initialize_contract(
SAFE_SINGLETON_FACTORY_ADDRESS, salt, data
)
if self.is_contract(contract_address):
raise ValueError(
raise ContractAlreadyDeployed(
f"Contract {contract_address} already deployed"
)

Expand Down
4 changes: 4 additions & 0 deletions gnosis/eth/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class TransactionGasPriceTooLow(EthereumClientException):
pass


class ContractAlreadyDeployed(EthereumClientException):
pass


class InvalidERC20Info(EthereumClientException):
pass

Expand Down
5 changes: 3 additions & 2 deletions gnosis/eth/tests/ethereum_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class EthereumTestCaseMixin:
def setUpClass(cls):
super().setUpClass()

cls.ethereum_test_account = cls.get_ethereum_test_account(cls)
cls.ethereum_test_account = cls.get_ethereum_test_account()
# Caching ethereum_client to prevent initializing again
cls.ethereum_client = _cached_data["ethereum_client"]

Expand All @@ -45,7 +45,8 @@ def setUpClass(cls):
cls.multicall = cls.ethereum_client.multicall
assert cls.multicall, "Multicall must be defined"

def get_ethereum_test_account(self):
@classmethod
def get_ethereum_test_account(cls):
try:
from django.conf import settings

Expand Down
88 changes: 51 additions & 37 deletions gnosis/safe/tests/safe_test_case.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import os
from typing import List, Optional
from typing import Dict, List, Optional

from eth_account import Account
from eth_typing import ChecksumAddress
Expand Down Expand Up @@ -35,9 +35,6 @@
logger = logging.getLogger(__name__)


_contract_addresses = {}


class SafeTestCaseMixin(EthereumTestCaseMixin):
compatibility_fallback_handler: Contract
multi_send: MultiSend
Expand All @@ -64,6 +61,8 @@ class SafeTestCaseMixin(EthereumTestCaseMixin):
"multi_send": MultiSend.deploy_contract,
}

contract_addresses: Dict[str, ChecksumAddress] = {}

@property
def safe_contract(self):
"""
Expand All @@ -75,55 +74,56 @@ def safe_contract(self):
def setUpClass(cls):
super().setUpClass()

cls.deploy_safe_singleton_factory(cls)
cls.deploy_safe_singleton_factory()

if not _contract_addresses:
if not cls.contract_addresses:
# First time mixin is called, deploy Safe contracts
for key, function in cls.contract_deployers.items():
_contract_addresses[key] = function(
cls.contract_addresses[key] = function(
cls.ethereum_client, cls.ethereum_test_account
).contract_address

cls.configure_django_settings(cls)
cls.configure_envvars(cls)
cls.configure_django_settings()
cls.configure_envvars()

cls.compatibility_fallback_handler = (
get_compatibility_fallback_handler_contract(
cls.w3, _contract_addresses["compatibility_fallback_handler"]
cls.w3, cls.contract_addresses["compatibility_fallback_handler"]
)
)
cls.simulate_tx_accessor_V1_4_1 = get_simulate_tx_accessor_V1_4_1_contract(
cls.w3, _contract_addresses["simulate_tx_accessor_V1_4_1"]
cls.w3, cls.contract_addresses["simulate_tx_accessor_V1_4_1"]
)
cls.safe_contract_V1_4_1 = get_safe_V1_4_1_contract(
cls.w3, _contract_addresses["safe_V1_4_1"]
cls.w3, cls.contract_addresses["safe_V1_4_1"]
)
cls.safe_contract_V1_3_0 = get_safe_V1_3_0_contract(
cls.w3, _contract_addresses["safe_V1_3_0"]
cls.w3, cls.contract_addresses["safe_V1_3_0"]
)
cls.safe_contract_V1_1_1 = get_safe_V1_1_1_contract(
cls.w3, _contract_addresses["safe_V1_1_1"]
cls.w3, cls.contract_addresses["safe_V1_1_1"]
)
cls.safe_contract_V1_0_0 = get_safe_V1_0_0_contract(
cls.w3, _contract_addresses["safe_V1_0_0"]
cls.w3, cls.contract_addresses["safe_V1_0_0"]
)
cls.safe_contract_V0_0_1 = get_safe_V1_0_0_contract(
cls.w3, _contract_addresses["safe_V0_0_1"]
cls.w3, cls.contract_addresses["safe_V0_0_1"]
)
cls.proxy_factory_contract = get_proxy_factory_contract(
cls.w3, _contract_addresses["proxy_factory"]
cls.w3, cls.contract_addresses["proxy_factory"]
)
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.w3, cls.contract_addresses["multi_send"]
)
cls.multi_send = MultiSend(
cls.ethereum_client, address=cls.multi_send_contract.address
)

def configure_django_settings(self):
@classmethod
def configure_django_settings(cls):
"""
Configure settings for django based applications
Expand All @@ -133,18 +133,30 @@ def configure_django_settings(self):
try:
from django.conf import settings

settings.SAFE_CONTRACT_ADDRESS = _contract_addresses["safe_V1_4_1"]
settings.SAFE_DEFAULT_CALLBACK_HANDLER = _contract_addresses[
settings.SAFE_CONTRACT_ADDRESS = cls.contract_addresses["safe_V1_4_1"]
settings.SAFE_DEFAULT_CALLBACK_HANDLER = cls.contract_addresses[
"compatibility_fallback_handler"
]
settings.SAFE_MULTISEND_ADDRESS = _contract_addresses["multi_send"]
settings.SAFE_PROXY_FACTORY_ADDRESS = _contract_addresses["proxy_factory"]
settings.SAFE_V0_0_1_CONTRACT_ADDRESS = _contract_addresses["safe_V0_0_1"]
settings.SAFE_V1_0_0_CONTRACT_ADDRESS = _contract_addresses["safe_V1_0_0"]
settings.SAFE_V1_1_1_CONTRACT_ADDRESS = _contract_addresses["safe_V1_1_1"]
settings.SAFE_V1_3_0_CONTRACT_ADDRESS = _contract_addresses["safe_V1_3_0"]
settings.SAFE_V1_4_1_CONTRACT_ADDRESS = _contract_addresses["safe_V1_4_1"]
settings.SAFE_SIMULATE_TX_ACCESSOR = _contract_addresses[
settings.SAFE_MULTISEND_ADDRESS = cls.contract_addresses["multi_send"]
settings.SAFE_PROXY_FACTORY_ADDRESS = cls.contract_addresses[
"proxy_factory"
]
settings.SAFE_V0_0_1_CONTRACT_ADDRESS = cls.contract_addresses[
"safe_V0_0_1"
]
settings.SAFE_V1_0_0_CONTRACT_ADDRESS = cls.contract_addresses[
"safe_V1_0_0"
]
settings.SAFE_V1_1_1_CONTRACT_ADDRESS = cls.contract_addresses[
"safe_V1_1_1"
]
settings.SAFE_V1_3_0_CONTRACT_ADDRESS = cls.contract_addresses[
"safe_V1_3_0"
]
settings.SAFE_V1_4_1_CONTRACT_ADDRESS = cls.contract_addresses[
"safe_V1_4_1"
]
settings.SAFE_SIMULATE_TX_ACCESSOR = cls.contract_addresses[
"simulate_tx_accessor_V1_4_1"
]
settings.SAFE_VALID_CONTRACT_ADDRESSES = {
Expand All @@ -158,17 +170,19 @@ def configure_django_settings(self):
except ModuleNotFoundError:
logger.info("Django library is not installed")

def configure_envvars(self):
@classmethod
def configure_envvars(cls):
"""
Configure environment variables
:return:
"""
os.environ["SAFE_SIMULATE_TX_ACCESSOR_ADDRESS"] = _contract_addresses[
os.environ["SAFE_SIMULATE_TX_ACCESSOR_ADDRESS"] = cls.contract_addresses[
"simulate_tx_accessor_V1_4_1"
]

def deploy_safe_singleton_factory(self) -> bool:
@classmethod
def deploy_safe_singleton_factory(cls) -> bool:
"""
Deploy Safe Singleton Factory for deterministic deployments and speeding up tests,
due to being able to check quickly if contracts are deployed in their expected addresses
Expand All @@ -179,19 +193,19 @@ def deploy_safe_singleton_factory(self) -> bool:
:return: `True` if deployed, `False` otherwise
"""
if self.ethereum_client.is_contract(SAFE_SINGLETON_FACTORY_ADDRESS):
if cls.ethereum_client.is_contract(SAFE_SINGLETON_FACTORY_ADDRESS):
return False

raw_tx = HexBytes(
"0xf8a78085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3820a96a0460c6ea9b8f791e5d9e67fbf2c70aba92bf88591c39ac3747ea1bedc2ef1750ca04b08a4b5cea15a56276513da7a0c0b34f16e89811d5dd911efba5f8625a921cc"
)
send_tx(
self.w3,
cls.w3,
{"to": SAFE_SINGLETON_FACTORY_DEPLOYER_ADDRESS, "value": 10000000000000000},
self.ethereum_test_account,
cls.ethereum_test_account,
)
tx_hash = self.ethereum_client.send_raw_transaction(raw_tx)
tx_receipt = self.ethereum_client.get_transaction_receipt(tx_hash, timeout=30)
tx_hash = cls.ethereum_client.send_raw_transaction(raw_tx)
tx_receipt = cls.ethereum_client.get_transaction_receipt(tx_hash, timeout=30)
assert tx_receipt["status"] == 1
return True

Expand Down

0 comments on commit 89367ab

Please sign in to comment.