Code Monkey home page Code Monkey logo

safe-eth-py's Introduction

Safe-eth-py (previously known as Gnosis-py)

Github Actions CI build coveralls Python 3.12 Django 5 Pypi package Documentation Status Black

Safe-eth-py includes a set of libraries to work with Ethereum and relevant Ethereum projects:
  • EthereumClient, a wrapper over Web3.py Web3 client including utilities to deal with ERC20/721 tokens and tracing.
  • Gnosis Safe classes and utilities.
  • Price oracles for Uniswap, Kyber...
  • Django serializers, models and utils.

Quick start

Just run pip install safe-eth-py or add it to your requirements.txt

If you want django ethereum utils (models, serializers, filters...) you need to run pip install safe-eth-py[django]

If you have issues building coincurve maybe you are missing some libraries

Contributing to safe-eth-py

Clone the repo, then to set it up:

python -m venv venv
source venv/bin/activate
pip install -r requirements-dev.txt
pre-commit install -f

Add new address for new chains

If you want to add Safe Smart Account support for a new chain you must open a new issue.

Once the issue is created or edited, an automatic validation will be executed and a Pull Request will be created if everything is ok. Finally, the Safe team will review and merge the automatic Pull Request generated from the issue.

Ethereum utils

gnosis.eth

  • class EthereumClient (ethereum_node_url: str): Class to connect and do operations with an ethereum node. Uses web3 and raw rpc calls for things not supported in web3. Only http/https urls are supported for the node url.

EthereumClient has some utils that improve a lot performance using Ethereum nodes, like the possibility of doing batch_calls (a single request making read-only calls to multiple contracts):

from gnosis.eth import EthereumClient
from gnosis.eth.contracts import get_erc721_contract
ethereum_client = EthereumClient(ETHEREUM_NODE_URL)
erc721_contract = get_erc721_contract(self.w3, token_address)
name, symbol = ethereum_client.batch_call([
                    erc721_contract.functions.name(),
                    erc721_contract.functions.symbol(),
                ])

If you want to use the underlying web3.py library:

from gnosis.eth import EthereumClient
ethereum_client = EthereumClient(ETHEREUM_NODE_URL)
ethereum_client.w3.eth.get_block(57)

gnosis.eth.constants

  • NULL_ADDRESS (0x000...0): Solidity address(0).
  • SENTINEL_ADDRESS (0x000...1): Used for Gnosis Safe's linked lists (modules, owners...).
  • Maximum and minimum values for R, S and V in ethereum signatures.

gnosis.eth.oracles

Price oracles for Uniswap, UniswapV2, Kyber, SushiSwap, Aave, Balancer, Curve, Mooniswap, Yearn... Example:

from gnosis.eth import EthereumClient
from gnosis.eth.oracles import UniswapV2Oracle
ethereum_client = EthereumClient(ETHEREUM_NODE_URL)
uniswap_oracle = UniswapV2Oracle(ethereum_client)
gno_token_mainnet_address = '0x6810e776880C02933D47DB1b9fc05908e5386b96'
weth_token_mainnet_address = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
price = uniswap_oracle.get_price(gno_token_mainnet_address, uniswap_oracle.weth_address)

gnosis.eth.utils

Contains utils for ethereum operations:

  • mk_contract_address_2(from_: Union[str, bytes], salt: Union[str, bytes], init_code: [str, bytes]) -> str: Calculates the address of a new contract created using the new CREATE2 opcode.

Ethereum django (REST) utils

Django utils are available under gnosis.eth.django. You can find a set of helpers for working with Ethereum using Django and Django Rest framework.

It includes:

  • gnosis.eth.django.filters: EthereumAddressFilter.
  • gnosis.eth.django.models: Model fields (Ethereum address, Ethereum big integer field).
  • gnosis.eth.django.serializers: Serializer fields (Ethereum address field, hexadecimal field).
  • gnosis.eth.django.validators: Ethereum related validators.
  • gnosis.safe.serializers: Serializers for Gnosis Safe (signature, transaction...).
  • All the tests are written using Django Test suite.

Contributors

See contributors

safe-eth-py's People

Contributors

0xcuonghx avatar banteg avatar bertux avatar datradito avatar davidalbela avatar dependabot[bot] avatar e00dan avatar elviskrop avatar falvaradorodriguez avatar fmrsabino avatar github-actions[bot] avatar gzeoneth avatar hectorgomezv avatar honzadajc avatar luarx avatar majorfi avatar mmv08 avatar moisses89 avatar msvstj avatar nick8319 avatar nitinmittal23 avatar ofek avatar philllau avatar pkakelas avatar rafaeltorres77 avatar rmeissner avatar scream4ik avatar t0mcr8se avatar the-amazing-ultraton avatar uxio0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

safe-eth-py's Issues

Deprecation Warning: signHash

signature_dict = account.signHash(self.safe_tx_hash)

When using this package, I got a warning:

DeprecationWarning: signHash is deprecated in favor of sign_message

coming from a dependency: eth_account/account.py:584:

I looked a bit into what it would take to make the transition here, but one cannot simply interchange the use of account.signHash with account.sign_message, we would need to actually provide also a SignableMessage with attributes:

    version: bytes  # must be length 1
    header: bytes  # aka "version specific data"
    body: bytes  # aka "data to sign"

Not sure exactly what to put here just yet. but its all contained here in eth_account.messages.py

Make Multisend constructor `address` field Optional

Every time I want to use MultiSend, I always have to spend several minutes trying to find the contract address. My process is usually the following:

  1. [Fail] Go to https://github.com/gnosis/safe-contracts and look for a networks.json file.
  2. [Fail] Go to etherscan and search Multisend.
  3. Go to a known safe and find a MultiSend transaction and copy the to address.

There are a few different versions of this contract deployed and I assume it is not being redeployed very often. For convenience, I think that the address field here should be take the following form:

address: Optional[str] = None

followed by

if not address:
    address = "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D"

Also, at the same time, for consistency, the following assertion could be removed if we used ChecksumAddress

assert fast_is_checksum_address(address), ( 
             "%s proxy factory address not valid" % address 
         ) 

class MultiSend:
dummy_w3 = Web3()
def __init__(self, address: str, ethereum_client: EthereumClient):
assert fast_is_checksum_address(address), (
"%s proxy factory address not valid" % address
)
self.address = address
self.ethereum_client = ethereum_client
self.w3 = ethereum_client.w3

Upgrade service to use Ganache v7 and web3 > 5.24.0

What is needed?

  • Upgrade service to use Ganache v7 and web3 > 5.24.0

Background

  • Current version of web3 5.24.0 is outdated
  • We cannot update web3 because it implements EIP1559 by default, and it's not supported by Ganache v6
  • We cannot update to Ganache v7 as it breaks some of our tests

Solution

  • Upgrade to Ganache v7 and make our tests work
  • Upgrade to Web3 last version

Raise new named exceptions for some expected errors

Expected error messages:

  • GETH
    ValueError{'code': -32000, 'message': 'transaction underpriced'}
  • OpenEthereum
    ValueError{'code': -32010, 'message': 'There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.'}

Those error messages are expected when a tx is pending to be mined and a new tx is sent with the same parameters but lower gasPrice.

NOTE:

Thanks a bunch!

Introduce method `SafeTx.api_post_data`

Currently, in order to post Safe transactions to the web interface (with this project as a dependency), we have to manually construct the post_data dictionary out of all the fields already contained in safe_tx. Since a SafeTx already contains the relevant info to build the post_data, it would be nice if there were some exposed method that would return the required format.

For example, the content of this method (taken from safe-cli) which constructs the post data would be nice to include here in this project:

https://github.com/5afe/safe-cli/blob/7a70a18c36b163ee91d5c763208ba1b1c9571317/safe_cli/api/transaction_service_api.py#L198-L222

EtherscanClient and safe-global/safe-infrastructure

My goal is to run the safe-infrastructure service on a custom chain by following the Guide to run our services locally.

Based on this post, I discovered that the PR should be submitted to this repository.

If neither the EtherscanClient nor the BlockscoutClient is added for the custom chain (e.g. Add Evmos Mainnet & Testnet) because its block explorer doesnโ€™t support the format of either the Etherscan API or the Blockscout API, could this cause problems for running the Multi-sig app (i.e. safe-infrastructure)?

Add Gnosis>=0.1.1 dependency to install_requires

My IDE is forcing me to install what is assumed to be a based dependency of this package:

Screenshot 2022-07-04 at 11 54 30 AM

Could be resolved by adding

Gnosis>=0.1.1

to the setup.py file here:

safe-eth-py/setup.py

Lines 11 to 22 in 791ca1e

requirements = [
"cached-property>=1.5; python_version < '3.8'",
"eip712_structs",
"packaging",
"py-evm>=0.5.0a3",
"pysha3>=1.0.0",
"requests>=2",
"typing-extensions>=3.10; python_version < '3.8'",
"web3>=5.23.0",
]
extras_require = {"django": ["django>=2", "django-filter>=2", "djangorestframework>=2"]}

Memory leak in get_contracts function

Describe the bug
gnosis.safe.safe.Safe.get_contract is caching the results with @cache decorator that means that can storage memory without limit.

    @cache
    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)

I noticied it working in safe-global/safe-transaction-service#1008
Expected behavior
Don't storage in local memory without limits.

Possible solutions

  • remove cache decorator
  • configure time to live cache limiting the memory that could reach and defining a time to clean the cache.

Fix readthedocs

Describe the bug
Readthedocs was broken when renaming the package to safe-eth-py

SafeTx excute: Fail with error 'GS001'

Describe the bug
I built the SafeTx object locally, multi-signed and executed, but I have a problem with the tx. the tx hash is here.

To Reproduce
Steps to reproduce the behavior:
execute function "send_multiSig_transaction"

Expected behavior
The query result is a successful hash.

Additional context
python==3.8.5
safe-eth-py==4.1.0

code:

from eth_typing import URI
from gnosis.eth import EthereumClient
from gnosis.safe.safe_tx import SafeTx

def send_multiSig_transaction():
    eth_client = EthereumClient(ethereum_node_url=URI('https://rinkeby.infura.io/v3/60b1533909b84f0e8ac61adbf44f2e38'))
    safe_tx = SafeTx(
        ethereum_client=eth_client,
        safe_address='0xC6bB445360B5122F4ED52F5CF206ff6388201573',
        to='0xf385FFD916ab0fB2DAd83e613d20970515f4844B',
        value=0,  
 data=b'0xa9059cbb0000000000000000000000001ab96c8568c5226efcb95ac5e5437f3ec48ade620000000000000000000000000000000000000000000000000000000000000001',
        operation=0,
        safe_tx_gas=200000,
        base_gas=21000,
        gas_price=1200000000,
        gas_token='0x0000000000000000000000000000000000000000',
        refund_receiver='0x0000000000000000000000000000000000000000',
        # signatures=b'',
        # safe_nonce=0,
        # safe_version='',
        # chain_id=4

    )
    # owner1
    safe_tx.sign('owner1 secret')
    # owner2
    safe_tx.sign('owner2 secret')
    data = safe_tx.execute(tx_sender_private_key='owner2 secret',
                           tx_gas_price=2000000000, tx_gas=200000)
    return data

Building wheel for coincurve (PEP 517) ... error

i tried gnosis 2.5,2.6,latest via pip install gnosis-py, pip install gnosis-py --no-binary :all:, python -m pip install --no-use-pep517 gnosis-py with pip 20. and 18. over the python 3.6, 3.7, 3.8

Bad web3 dependency definition on setup.py

It seems that gnosis as a whole still depends on web3 v4, but if one install the package through pip we get web3 v5. This means that, whenever I try to run importing anything from gnosis.eth, I get:

from web3.utils.threads import Timeout
ModuleNotFoundError: No module named 'web3.utils'

EtherscanClient vs BlockscoutClient format?

Can you please answer the following questions?

  1. What are the purposes of NETWORK_WITH_URL and NETWORK_WITH_API_URL in the EtherscanClient class? Are they required and important? Can I add a custom explorer URL to the list that is not based on Etherscan, which is not an opensource? (i.e. If the format of the custom explorer API does not match that of Etherscanโ€™s API, can I still add it to the list without problem?)

  2. What is the purpose of the BlockscoutClient class? Is it similar to the EtherscanClient class? What happens if someone omits writing either the EtherscanClient or BlockscoutClient classes?

  3. Do the URLs mentioned relate to or depend on infrastructure code?

Installation error while trying to install package - pysha3

Describe the bug
Hello, I am having trouble installing the package into my virtual environment. I am running python 3.10, made sure I installed any libraries in case I was missing any (autoconf build-essential libffi-dev libtool pkg-config python3-dev..)

To Reproduce
Steps to reproduce the behavior:

  1. run python virtual env source .venv/bin/activate
  2. pip install pip install safe-eth-py

Additional context
Ubuntu
Python version 3.10 (also tried with different python versions (3.8, 3.9)

  Building wheel for pysha3 (setup.py) ... error
  error: subprocess-exited-with-error
  
  ร— python setup.py bdist_wheel did not run successfully.
      ...
      Modules/_sha3/sha3module.c:18:10: fatal error: Python.h: No such file or directory
         18 | #include "Python.h"
            |          ^~~~~~~~~~
      compilation terminated.
      error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for pysha3
  Running setup.py clean for pysha3
  Building wheel for pyethash (setup.py) ... error
  error: subprocess-exited-with-error
  
  ร— python setup.py bdist_wheel did not run successfully.
     ....
      src/python/core.c:1:10: fatal error: Python.h: No such file or directory
          1 | #include <Python.h>
            |          ^~~~~~~~~~
      compilation terminated.
      error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for pyethash
  Running setup.py clean for pyethash
Failed to build pysha3 pyethash
Installing collected packages: pysha3, pyethash, mypy-extensions, cached-property, pyparsing, hexbytes, eth-hash, packaging, py-ecc, eth-bloom, eip712-structs, trie, py-evm, safe-eth-py
  Running setup.py install for pysha3 ... error
  error: subprocess-exited-with-error
  
  ร— Running setup.py install for pysha3 did not run successfully.
      Modules/_sha3/sha3module.c:18:10: fatal error: Python.h: No such file or directory
         18 | #include "Python.h"
            |          ^~~~~~~~~~
      compilation terminated.
      error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure
ร— Encountered error while trying to install package.
โ•ฐโ”€> pysha3

Gas limit when using multicall

Describe the bug
multicall sometimes exceeds eth_call gas limit and an out of gas error is raised.

To Reproduce
Do eth_call consuming the maximum gas allowed by the node. Library raises an exception. Example trace from the transaction-service:

2022-05-16 10:23:21,794 [WARNING] [MainProcess] https://safe-transaction.mainnet.gnosis.io/api/v1/safes/{address}/collectibles/ - Exception: NodeConnectionException - Data received {}
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/gnosis/eth/multicall.py", line 227, in _try_aggregate
    result = self.contract.functions.tryAggregate(
  File "/usr/local/lib/python3.10/site-packages/web3/contract.py", line 957, in call
    return call_contract_function(
  File "/usr/local/lib/python3.10/site-packages/web3/contract.py", line 1501, in call_contract_function
    return_data = web3.eth.call(
  File "/usr/local/lib/python3.10/site-packages/web3/module.py", line 57, in caller
    result = w3.manager.request_blocking(method_str,
  File "/usr/local/lib/python3.10/site-packages/web3/manager.py", line 198, in request_blocking
    return self.formatted_response(response,
  File "/usr/local/lib/python3.10/site-packages/web3/manager.py", line 171, in formatted_response
    raise ValueError(response["error"])
ValueError: {'code': -32015, 'message': 'VM execution error.', 'data': 'Out of gas'}

Expected behavior
Reverts to use batch call

Always return the whole list of modules

What is needed?

Calling retrieve_all_info should return the whole list of modules enabled for the safe.

Background

retrieve_all_info calls getModules contract method which, depending on the contract version, will return the whole list of modules or only the first 10.

Related issues

safe-react has a workaround for this

https://github.com/gnosis/safe-react/blob/d07816fcacc52fc3b157ccfd97a08e119f34dbb2/src/logic/safe/utils/modules.ts#L68-L93

but as per @rmeissner request (5afe/safe-react#2122 (comment)), it would be better to have it resolved in gnosis-py and clean up the code on safe-react.

setup_service.py is not finding EthereumNetwork.VELAS_MAINNET on gnosis-py

What is needed?

I request to add Velas network on gnosys-py on this PR:
#220

Background

I'm using an instance of transaction service here:
https://transaction.staging.velasafe.com/
repo: https://github.com/protofire/velas-transaction-service
branch: staging

Related issues

When I try to setup the transaction service, the service worker is not running ok due this error:

Traceback (most recent call last):
File "/app/manage.py", line 30, in
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.10/site-packages/django/core/management/init.py", line 419, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.10/site-packages/django/core/management/init.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.10/site-packages/django/core/management/init.py", line 257, in fetch_command
klass = load_command_class(app_name, subcommand)
File "/usr/local/lib/python3.10/site-packages/django/core/management/init.py", line 39, in load_command_class
module = import_module('%s.management.commands.%s' % (app_name, name))
File "/usr/local/lib/python3.10/importlib/init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 1050, in _gcd_import
File "", line 1027, in _find_and_load
File "", line 1006, in _find_and_load_unlocked
File "", line 688, in _load_unlocked
File "", line 883, in exec_module
File "", line 241, in _call_with_frames_removed
File "/app/safe_transaction_service/history/management/commands/setup_service.py", line 217, in
EthereumNetwork.VELAS_MAINNET: [
File "/usr/local/lib/python3.10/enum.py", line 437, in getattr
raise AttributeError(name) from None
AttributeError: VELAS_MAINNET. Did you mean: 'EVMOS_MAINNET'?

I've the last version of gnosis-py (3.9.2)with the Velas network added there, but it appears that setup_service.py is not finding the correct network, and because of that I can't update the master copies and proxy factory addresses. Do I have to update gnosis-py on other dependency? Thank you.

CC: @Uxio0

eip712_encode_hash encode string bytes and string uint256

What is needed?

String bytes feature

I would like that eip712_encode_hash encode string bytes also like the following example:
"Message": [ {"name": "oneByte", "type": "bytes1"} ] "message": {"oneByte": "0x01"}

Currently this is not possible because eip712_encode_hash is using eth_abi that expects python bytes.

String uint256 feature

I would like that eip712_encode_hash encode string uint also like the following example:
"Message": [ {"name": "stringNum", "type": "uint256"} ] "message": {"stringNum": "1234"}

Possible solution

Check in _encode_field(name, typ, value) if is bytes type the value is an instance of str and in that case convert to bytes bytes.fromhex(string).
Similar solution for uint but converting it from string to python int.

Related issues

Decoding logs should decode logs with `indexed` and not `indexed` data

What is needed?

Decode logs ignoring if parameters are indexed or not

Background

Currently, for web3 to decode a log it needs ABI to be the same, e.g. event Transfer(address indexed from, address indexed to, uint256 value); for ERC20 has the same topic that ERC721 event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);, but web3.py cannot decode ERC721 with ERC20 signature.

Related issues

Gnosis-py doesn't work with eth brownie 1.15

Describe the bug
Trying to use gnosis with brownie 1.15. It's not working.
To Reproduce
Due to a version incompatability between required web3 module versions. This is resolved by #43, which has been pending for 14 days.

Expected behavior
It should be possible to use gnosis-py with brownie 1.15
Additional context
Add any other context about the problem here.

Add/update oracles to retrieve the price

What is needed?

Currently safe-eth-py have several oracles implemented to retrieve the price from them but the last update of them was on October of 2021.
I would like to review the oracles implemented to check if new versions of contracts are deployed eg: UniSwapV3, and research if we can add some more new oracles.

Background

The focus of this issue is add more opportunities to retrieve the price from decentralized options before centralized options.

Related issues

No issues related.

Limit number of payloads in the same batch request

Describe the bug
We are not enforcing any limit of the number of payloads we send to a node JSON RPC. We should limit it, as some node providers have a hard limit of ~500-1000

Expected behavior

  • If a batch request tries to do more than batch_request_limit, chunk the batch request and do subsequent calls to the node.
  • Add an environment parameter ETHEREUM_RPC_BATCH_REQUEST_MAX_SIZE to configure it.

Additional context

  • Ankr has a limit of 1000 elements in a batch.
  • Nodereal has a limit of 500.

Estimation tx gas lower than required

The value of the estimation for some transaction (gnosis chain) is lower than the value required, so we think it's becuase the offset is a bit low. We tried locally to change it from its current value to 23000, and we get the value required in each transaction
Now the result we get is around 89220 but the value required for the transaction is 91064 (which we achieve if we increase the WEB3_ESTIMATION_OFFSET) -

WEB3_ESTIMATION_OFFSET = 20000

Error that we see in our logs :
InvalidGasEstimation: Gas should be at least equal to safe-tx-gas=91064 and base-gas=48528. Current is safe-tx-gas=89950 and base-gas=48528

Why eth-abi2

We (the SnakeCharmers) are curious why eth-abi2 exists and if there's a missing feature in eth-abi that you needed?

Gas estimation using intentional reverts with binary data don't work in Nethermind

Describe the bug
When using a nethermind RPC node, which is one of the supported RPC nodes for Gnosis chain, the gas estimation in Safe.estimate_tx_gas_with_safe that uses intentional reverts with binary data results that include the estimated gas fails. Nethermind returns these reverts in a slightly different format than OpenEthereum.

Specifically this is one such example on Gnosis chain:

request POST 
{
    "jsonrpc": "2.0",
    "method": "eth_call",
    "params": [
        {
            "value": "0x0",
            "from": "0x030e4688f6C8eCf7872a366540D34260623EB578",
            "gasPrice": "0x0",
            "to": "0x030e4688f6C8eCf7872a366540D34260623EB578",
            "data": "0xc4ca3a9c000000000000000000000000e097ec255ea9fe4e199e920e105b0f61d6e09c340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044cd4517eb00000000000000000000000026f2319fbb44772e0ed58fb7c99cf8da59e2b5be00000000000000000000000000000000000000000000000006e8f3c41ff9210000000000000000000000000000000000000000000000000000000000"
        }, "latest"
    ],
    "id": 1
}

Nethermind response is:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32015,
    "message": "VM execution error.",
    "data": "Reverted 0x0000000000000000000000000000000000000000000000000000000000010419"
  },
  "id": 1
}

Open Ethereum response is:

{
    "jsonrpc": "2.0",
    "result": null,
    "error": {
        "code": -32015,
        "message": "VM execution error.",
        "data": "Reverted 0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000010419"
    },
    "id": 1
}

To Reproduce
Set the relay server to a Nethermind RPC URL in Gnosis chain, configured to use a gas token of 0x26F2319Fbb44772e0ED58fB7c99cf8da59e2b5BE (this is DAI.CPXD)
using the API tool perform a
POST /v2/safes/{address}/transactions/estimate
where the body is:

{
  "safe": "0x030e4688f6C8eCf7872a366540D34260623EB578",
  "to": "0xE097ec255eA9fE4e199E920E105b0f61d6e09C34",
  "value": 0,
  "data": "0xcd4517eb00000000000000000000000026f2319fbb44772e0ed58fb7c99cf8da59e2b5be00000000000000000000000000000000000000000000000006e8f3c41ff92100",
  "operation": 0,
  "gasToken": "0x26F2319Fbb44772e0ED58fB7c99cf8da59e2b5BE"
}

and the address of the safe is 0x030e4688f6C8eCf7872a366540D34260623EB578

Expected behavior
This should return the response that looks something like this (depending on how your relay server is configured):

{
    "safeTxGas": "102585",
    "baseGas": "48740",
    "dataGas": "48740",
    "operationalGas": "0",
    "gasPrice": "5000000000",
    "lastUsedNonce": 1,
    "gasToken": "0x26F2319Fbb44772e0ED58fB7c99cf8da59e2b5BE",
    "refundReceiver": "0x846fcb74913277AF31FF535cC88bfcC62f64346A"
}

however because the revert data cannot be parsed this error is returned instead:

{
    "exception": "CannotEstimateGas: Received 0x0000000000000000000000000000000000000000000000000000000000010419 for tx={'value': 0, 'chainId': 100, 'from': '0x030e4688f6C8eCf7872a366540D34260623EB578', 'gas': 0, 'gasPrice': 0, 'to': '0x030e4688f6C8eCf7872a366540D34260623EB578', 'data': '0xc4ca3a9c000000000000000000000000e097ec255ea9fe4e199e920e105b0f61d6e09c340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044cd4517eb00000000000000000000000026f2319fbb44772e0ed58fb7c99cf8da59e2b5be00000000000000000000000000000000000000000000000006e8f3c41ff9210000000000000000000000000000000000000000000000000000000000'}"
}

Add Syscoin Addresses (Tanenbaum, Mainnet & ROLLUX)

What is needed?

Adding in the Syscoin Safe Deployment addresses after deployment has been done.

Relies on :

safe-global/safe-singleton-factory#123
safe-global/safe-singleton-factory#124
safe-global/safe-singleton-factory#125

Background

After deployment has been made, the addresses need to be added here first before changes to safe transaction service can be made.

Related issues

safe-global/safe-singleton-factory#123
safe-global/safe-singleton-factory#124
safe-global/safe-singleton-factory#125

ATT: @develCuy

indexing support geth

What is needed?

I tried to deploy gnosis-safe into private chain that based on ethermint.
But safe-transaction-service can't indexing anything in worker due to trace module not support in geth. So can you support geth EVM or give me some advise for my case? Thanks you :D

estimate_tx_gas failing on xDai with AttributeError: 'str' object has no attribute 'keys'

Describe the bug

The estimation of gas fees for Safe transactions fails on xDai with the following exception: AttributeError: 'str' object has no attribute 'keys'. This error is also occurring in the relayer breaking all estimates.

To Reproduce

Use the following code to reproduce:

from gnosis.eth import EthereumClient
from gnosis.safe import Safe

ethereum_client = EthereumClient('https://xdai.poanetwork.dev')
safe = Safe('0x9a0bbbbd3789f184CA88f2F6A40F42406cb842AC', ethereum_client)
result = safe.estimate_tx_gas('0x333d72F54CF17BA7A1971e7C7E9acB91C8B709d2', 0, '0xa2e62045', 0)
print(result)

Executing this code throws the following exception:

Traceback (most recent call last):
  File "/home/adz/.pyenv/versions/safe-estimate-issue/lib/python3.8/site-packages/gnosis/safe/safe.py", line 436, in estimate_tx_gas_with_safe
    result: HexBytes = self.w3.eth.call(tx, block_identifier=block_identifier)
  File "/home/adz/.pyenv/versions/safe-estimate-issue/lib/python3.8/site-packages/web3/module.py", line 58, in caller
    result = w3.manager.request_blocking(method_str, params, error_formatters)
  File "/home/adz/.pyenv/versions/safe-estimate-issue/lib/python3.8/site-packages/web3/manager.py", line 158, in request_blocking
    raise ValueError(response["error"])
ValueError: {'code': -32015, 'message': 'VM execution error.', 'data': 'revert: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00??'}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 14, in <module>
    result = safe.estimate_tx_gas('0x333d72F54CF17BA7A1971e7C7E9acB91C8B709d2', 0, '0xa2e62045', 0)
  File "/home/adz/.pyenv/versions/safe-estimate-issue/lib/python3.8/site-packages/gnosis/safe/safe.py", line 521, in estimate_tx_gas
    return self.estimate_tx_gas_by_trying(to, value, data, operation) + PROXY_GAS + OLD_CALL_GAS
  File "/home/adz/.pyenv/versions/safe-estimate-issue/lib/python3.8/site-packages/gnosis/safe/safe.py", line 490, in estimate_tx_gas_by_trying
    gas_estimated = self.estimate_tx_gas_with_safe(to, value, data, operation)
  File "/home/adz/.pyenv/versions/safe-estimate-issue/lib/python3.8/site-packages/gnosis/safe/safe.py", line 456, in estimate_tx_gas_with_safe
    key = list(data_dict.keys())[0]
AttributeError: 'str' object has no attribute 'keys'

Expected behavior

The revert is happening as expected but seems to be not parseable in the catch phrase. I assume that the revert message looks slightly different on xDai than on mainnet?

Some more observations

CowSwap oracle doesn't work on gnosis-chain

Describe the bug
CowSwap oracle currently doesn't work on safe-eth-py because the endpoint to get the price was deprecated and removed.
https://github.com/cowprotocol/services/pull/1052/files#diff-ea5f6887f8360abaf702f3dcece07c3b2e87022458254f48bb2fb66adf15b95fL270

To Reproduce
Try to get any price using cowswap oracle.

Expected behavior
Return the price

Possible solution
There is other endpoint that can return the native price:
https://api.cow.fi/xdai/api/v1/token/<token-address>/native_price
For example:
https://api.cow.fi/xdai/api/v1/token/0x177127622c4A00F3d409B75571e12cB3c8973d3c/native_price

safe retrieval fails on nethermind

The implementation of retrieve_all_info makes an Eth RPC call to specific functions to get nonce, threshold, owners, etc.

To do this it provides the safe address as the 'from'. This is not accepted on the Nethermind Eth client.

To reproduce:

Here is an example of posting a call to VERSION() on the Rinkeby network:

nethermind> node.switch('https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')                                                                                           
nethermind>  eth.call({"to": "0xe8b541b0E9a3981E3aC0e324B987940c4eF4069B", "data": "0xffa1ad74", "from": "0xe8b541b0E9a3981E3aC0e324B987940c4eF4069B"}, "latest")                  
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005312e332e30000000000000000000000000000000000000000000000000000000"

'312e332e30' is ASCII for "1.3.0", the contract version.

Trying the same kind of call against a Nethermind client is rejected (see source, line 191) however it works fine when provided any other kind of address, even 0x0.

nethermind> node.switch('https://rpc.testnet.shyft.network/')
nethermind> eth.call({"to": "0xc5847FcB4A4270DC77800a1487Ce29cB9922bD41", "data": "0xffa1ad74", "from": "0xc5847FcB4A4270DC77800a1487Ce29cB9922bD41"}, "latest")                   
VM execution error. | sender has deployed code

nethermind> eth.call({"to": "0xc5847FcB4A4270DC77800a1487Ce29cB9922bD41", "data": "0xffa1ad74", "from": "0x0000000000000000000000000000000000000000"}, "latest")                   
"0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005312e332e30000000000000000000000000000000000000000000000000000000"

DomainSeparator is wrong calculated for version < 1.3.0

Describe the bug
For versions < v1.3.0 the chainId is not included in the domainseparator.
domainSeparator = keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, this));

Expected behavior
DomainSeparator function should return correct hash for old versions.

Refactor retrieve_version and add cached property

What is needed?

Currently retrieve_version method do a call to the RPC to return the version of the safe contract.
An improvement performance of that could be convert this function in a property method of safe or contract and enable in that the cached_property.
The idea is, having an instance of a Safe, get the version like safe.version or safe.contract.version .

Background

This approach was discussed here #422 (comment)

Address given is not a valid Safe address

When I add Safe by script, the tx hash is 0xaa9763e71a8138607a3c823e7e7a10dbcd6e71f4419228233759d2923a993377, then I find I can't add a existing safe on Gnosis Safe Web. what can I do?

Below is my code to create Safe

import time

from eth_account import Account
from eth_typing import URI
from eth_utils import to_checksum_address
from gnosis.eth import EthereumClient
from gnosis.safe.safe_creation_tx import SafeCreationTx
from gnosis.safe.proxy_factory import ProxyFactory

factory_address = to_checksum_address('0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2')
eth_client = EthereumClient(ethereum_node_url=URI('https://rinkeby.infura.io/v3/60b1533909b84f0e8ac61adbf44f2e38'))
pf = ProxyFactory(address=factory_address, ethereum_client=eth_client)

deployer_account =  Account().privateKeyToAccount('xxx')
master_copy = to_checksum_address('0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552')

owner0 = to_checksum_address('0xDbD02Ed54Cb7bbA9122ed83e3ABF454756747043')
owner1 = to_checksum_address('xxx')
owner2 = to_checksum_address('xxx')
safe_creation_tx = SafeCreationTx(
    w3=eth_client.w3,
    owners=[owner0, owner1, owner2],
    threshold=2,
    signature_s=123,
    master_copy=master_copy,
    gas_price=0,
    funder=''
)

initializer = safe_creation_tx.safe_setup_data
salt_nonce = int(time.time() * 1000)
b = \
    pf.deploy_proxy_contract_with_nonce(
    deployer_account=deployer_account,
    master_copy=master_copy,
    initializer=initializer,
    salt_nonce=salt_nonce
)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.