Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor proxyFactory and safe #597

Merged
merged 17 commits into from
Sep 12, 2023
Merged

Refactor proxyFactory and safe #597

merged 17 commits into from
Sep 12, 2023

Conversation

moisses89
Copy link
Member

@moisses89 moisses89 commented Jul 28, 2023

Description

The purpose of this pull request is refactor proxyFactory and safe class to do more easy add new safe contract versions.

Actions

  • split proxy factory tests by version
  • add a contract class with the common methods to deploy and get contract information
  • refactor proxy factory adding heritage with different proxy factory versions.
  • refactor safe class adding heritage with different safe versions.

Safe refactor class

Class diagram
SafeClass drawio

The Safe class get the version from blockchain and decide which class should instantiate taking account the version and return the safe instance with the correct version.
safe = Safe("0x4E24f2497445125C4573f7935ADeDEce154317b8", ethereum_client) # returns instance of SafeV111
safe = Safe("0xfca7Da0a0290D7BcBEcD93bE124756fC9B6F8E6A", ethereum_client) # returns instance of SafeV130

SafeV100 overwrite common method retrieve_all_info because the Safe V1.1.1 contract doesn't have getModulesPaginated.

Considerations

In case that Safe class couldn't get the version from blockchain, it would return the last version class to avoid break some tests. We could improve this raising an exception that is an invalid safe.
In case of version contains wrong version value we are returning SafeV130 to keep going with the unsupported mastercopies.

Issues related

#583
Closes #619

@moisses89 moisses89 force-pushed the refactor_contracts branch 6 times, most recently from 6042993 to 8e85c50 Compare August 23, 2023 14:33
@moisses89 moisses89 marked this pull request as ready for review August 25, 2023 11:49
@moisses89 moisses89 requested a review from a team as a code owner August 25, 2023 11:49
@moisses89 moisses89 requested review from fmrsabino, Uxio0 and iamacook and removed request for a team August 25, 2023 11:49
Copy link
Member

@Uxio0 Uxio0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR is quite good, but I think we can still refactor more common things into the new classes

Also, afterwards we should reevaluate estimations and other methods to know if they are still valid of they need to be adjusted

gnosis/eth/contract_common.py Outdated Show resolved Hide resolved
gnosis/eth/contract_common.py Outdated Show resolved Hide resolved
return EthereumTxSent(tx_hash, tx, contract_address)

@staticmethod
def configure_tx_parameters(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can just accept a dictionary with tx parameters, as Web3 does in every method

gnosis/eth/contract_common.py Outdated Show resolved Hide resolved
gnosis/eth/contract_common.py Outdated Show resolved Hide resolved
logger = logging.getLogger(__name__)


class TestProxyFactoryV130(SafeTestCaseMixin, TestCase):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a lot of tests are common for proxy factories. Why not use a loop and SubTest?

gnosis/safe/safe.py Outdated Show resolved Hide resolved
gnosis/safe/safe.py Outdated Show resolved Hide resolved
class SafeV130(SafeCommon):
@cached_property
def contract(self) -> Contract:
return get_safe_V1_3_0_contract(self.w3, address=self.address)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont redefine contract, define a contract_fn. Also remove contract_fn as an argument for _deploy_master_copy

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add contract_fn = get_safe_V0_0_1_contract for class SafeV001 or the same for other classes is going to fail when we call self.contract_fn because get_safe_V0_0_1_contract is not part of safe class and we are passing the instance.

gnosis/safe/safe.py Outdated Show resolved Hide resolved
@moisses89
Copy link
Member Author

@Uxio0 created following PR to fix the test issues with blockscout #621

- Remove deploy from ContractCommon, use EthereumClient deployandinitialize
- Refactor retrieve_all_info
- Rename `deploy_safe_master_copy` and `deploy_proxy_factory_contract` to `deploy_contract`
Copy link
Member Author

@moisses89 moisses89 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, some comments :)

with open(path) as f:
return json.load(f)


Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coul you add the parameter types of the above methods?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, better late than nothing

if nonce is not None:
tx_params["nonce"] = nonce

if chain_id is not None:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if chain_id should be enough I think the same for above conditions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm not understanding

safe_tx_gas = estimated_tx_gas
base_gas = 0
gas_price = 1
gas_token = gas_token or NULL_ADDRESS
Copy link
Member Author

@moisses89 moisses89 Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be the default value for gas_token NULL_ADDRESS value defined in the method header?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could break some behaviour, also NULL_ADDRESS is our current implementation for Solidity, while someone that's just using Python can say that the gas_token is None, and that should be fair in my opinion. We are just "translating"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can change that but I wouldn't do it in this PR

:param signatures: Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})
:param safe_nonce: Nonce of the safe (to calculate hash)
:param safe_version: Safe version (to calculate hash)
:return:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return: safe transaction

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Uxio0 Uxio0 merged commit bd1f1cd into master Sep 12, 2023
7 checks passed
@Uxio0 Uxio0 deleted the refactor_contracts branch September 12, 2023 14:55
@github-actions github-actions bot locked and limited conversation to collaborators Sep 12, 2023
@Uxio0
Copy link
Member

Uxio0 commented Sep 12, 2023

Thanks @moisses89 for starting this PR and all the contributions

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor safe and proxy factory
2 participants