apeworx / ape-safe Goto Github PK
View Code? Open in Web Editor NEWSafe (Wallet) account plugin for the Ape Framework
Home Page: https://www.apeworx.io/
License: Apache License 2.0
Safe (Wallet) account plugin for the Ape Framework
Home Page: https://www.apeworx.io/
License: Apache License 2.0
ape supports any message type for signing since ApeWorX/ape#1614
Line 187 in 4c0891b
I wish there was a way for network detection to be smarter in the safe. I purposely named my safes the same alias as the one generated in the UI, like laughing-sepolia-safe
... It'd be cool maybe if could detect sepolia somehow and my default sepolia provider. It feel redundant to have to specify the network. Maybe the network can be included in the safe account data.
Originally posted by @antazoey in #41 (comment)
note: a delegate can submit a tx to SafeAPI even if it has zero signatures.
things related to "delegate" in Safe's tx svc api here: https://github.com/safe-global/safe-eth-py/blob/master/gnosis/safe/api/transaction_service_api.py
any safe signer can manage delegates by submitting a special message to the api.
Also, if submitter=
is a delegate account or alias it should bypass this logic and submit it. I check elsewhere if they're a signer only for signature aggregation.
Originally posted by @banteg in #11 (comment)
safe supports a range of signature schemes. it would be useful to have abstractions for all of them that allow verifying if they are valid. some of the types require calling on-chain methods.
https://docs.safe.global/learn/safe-core/safe-core-protocol/signatures
none
safe owners can manage delegates. delegates can submit transactions to the safe api. they sign them as ususal, but once accepted, these transactions will have 0 confirmations. delegating tx creation is useful for different automation.
create_delegate_message_hash
get_delegates
add_delegate
remove_delegate
none
ape
and plugin versions:$ ape --version
0.7.9
$ ape plugins list
Installed Plugins
alchemy 0.7.1
arbitrum 0.7.2
etherscan 0.7.1
foundry 0.7.3
infura 0.7.1
ledger 0.7.0
optimism 0.7.2
safe 0.7.0b1
tokens 0.7.1
$ ape safe pending approve X --network ethereum:mainnet --safe mine
SignableMessage(version="E", header="thereum Signed Message:
32", body="0xc878....cf40")
Sign: [y/N]: y
Enter passphrase to unlock 'hot' []:
Leave 'hot' unlocked? [y/N]: y
SUCCESS: Signatures added to transaction 'X' using accounts '0x....'.
Submit transaction 'X' [y/N]: y
0. cold
1. hot
Or 'TEST::account_idx', where `account_idx` is in [0..{len_test_accounts}]
Select a submitter: dev
Traceback (most recent call last):
File "bin/ape", line 8, in <module>
sys.exit(cli())
^^^^^
File "site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "ape/_cli.py", line 79, in invoke
return super().invoke(ctx)
^^^^^^^^^^^^^^^^^^^
File "site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "ape/cli/commands.py", line 96, in invoke
return self._invoke(ctx, provider=provider)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "ape/cli/commands.py", line 133, in _invoke
return ctx.invoke(self.callback or (lambda: None), **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/click/decorators.py", line 92, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/ape_safe/_cli/pending.py", line 219, in approve
txn.confirmations = {**txn.confirmations, **signatures_added}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'list' object is not a mapping
Fill this in if you have ideas on how the bug could be fixed.
ape
and plugin versions:$ ape --version
0.7.23
$ ape plugins list
Installed Plugins
alchemy 0.7.3
etherscan 0.7.4
foundry 0.7.5
optimism 0.7.3
safe 0.7.0b2
solidity 0.7.3
The safe api changed for fetching transactions, i believe v1/safes/{address}/transactions/
no longer works and is now
https://safe-transaction-optimism.safe.global/
/v1/safes/{address}/all-transactions/
ape-safe/ape_safe/client/__init__.py
Line 84 in eddc804
Please include information like:
txn = multisend.MultiSend()
txn(sender=self.safe,gas=0,submit_transaction=False,nonce=nonce)
Trying to push
Traceback (most recent call last):
File "/home/thesis/repos/gnosis_perp_ape/main.py", line 58, in <module>
self.setup_gnosis_perp_parameter_change(args.p)
File "/home/thesis/repos/gnosis_perp_ape/utils/controller.py", line 75, in setup_gnosis_perp_parameter_change
self.post_gnosis_transaction(contractName='perp_settings',functionName=functionName,args=stagedParams)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/thesis/repos/gnosis_perp_ape/utils/gnosis_safe.py", line 24, in wrapper
return func(self,*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/thesis/repos/gnosis_perp_ape/utils/gnosis_safe.py", line 64, in post_gnosis_transaction
nonce = self.get_next_safe_nonce()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/thesis/repos/gnosis_perp_ape/utils/gnosis_safe.py", line 24, in wrapper
return func(self,*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/thesis/repos/gnosis_perp_ape/utils/gnosis_safe.py", line 60, in get_next_safe_nonce
return self.safe.new_nonce
^^^^^^^^^^^^^^^^^^^
File "/home/thesis/miniconda3/envs/gnosis_perp_ape/lib/python3.12/site-packages/ape_safe/accounts.py", line 322, in new_nonce
if latest_tx := next(self.client.get_transactions(confirmed=False), None):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/thesis/miniconda3/envs/gnosis_perp_ape/lib/python3.12/site-packages/ape_safe/client/base.py", line 81, in get_transactions
for txn in self._all_transactions():
File "/home/thesis/miniconda3/envs/gnosis_perp_ape/lib/python3.12/site-packages/ape_safe/client/__init__.py", line 86, in _all_transactions
response = self._get(url)
^^^^^^^^^^^^^^
File "/home/thesis/miniconda3/envs/gnosis_perp_ape/lib/python3.12/site-packages/ape_safe/client/base.py", line 128, in _get
return self._request("GET", url)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/thesis/miniconda3/envs/gnosis_perp_ape/lib/python3.12/site-packages/ape_safe/client/base.py", line 153, in _request
raise ClientResponseError(api_url, response)
ape_safe.exceptions.ClientResponseError: Exception when calling 'https://safe-transaction-optimism.safe.global/api/v1/safes/xxxxxxxxxxxxxxxxxxxxx/transactions/':
<!doctype html>
<html lang="en">
<head>
<title>Not Found</title>
</head>
<body>
<h1>Not Found</h1><p>The requested resource was not found on this server.</p>
</body>
</html>
Need to update the api
This is a very complex plugin, so it's worth adding additional color to README on usage at a high level, maybe 1-2 user guides for using it in different scenarios (perhaps for Personal use and for Collective use), another user guide on the CLI extension, and autodocs for the various classes (similar to ape)
For some dang reason, I get a random ContractNotFoundError
with ape-safe installed and running tests on ape-foundry using the polygon-fork
networks. Uninstalling ape-safe fixes my problem.
The current docs are copies of the old brownie safe
package
Update the docs using modern examples for all of the examples in the legacy docs
Also publish docs for this using our docs template
ape-safe/ape_safe/multisend.py
Lines 31 to 66 in 4c0891b
there are only two addresses ever. any address will do, and we can just use the first address that has code. see how it's done here:
another important thing is we should switch to multisend call only version because it prevents the user from accidentally corrupting safe storage with a delegatecall.
a safe actually contains a bit more functionality like eip-1271 signature support behind fallback handler. it would be useful to extend the contract type with abis from it.
the fallback handler can be read from slot keccak("fallback_manager.handler.address")
of a safe.
still encountering problems when trying to submit a multisend tx. they are mostly coming from gas estimation:
prepare_transaction
tries to estimate gas from a safe address- it fails when the safe has no ether to cover the gas costs, but in reality safe itself never pays for gas
- it fails because it tries to estimate a
call
to the multisend contract, while it only supportsdelegatecall
we need to somehow override the tx handler or find a way to pass additional metadata to skip some checks
Originally posted by @banteg in #11 (comment)
ape
and plugin versions:$ ape --version
0.7.7
$ ape plugins list
Installed Plugins
alchemy 0.7.1
arbitrum 0.7.1
etherscan 0.7.0
foundry 0.7.1
optimism 0.7.2
safe 0.7.0b1
solidity 0.7.1
Running the below to add a safe
(gnosis_test_ape) thesis@ks:~/repos/gnosis_test_ape$ ape safe add 0xBFd8c1f83C5389a64166F01fea0D56d982F627Ac "arbitrum-test" --network arbitrum:mainnet:alchemy
returns an error
ERROR: (ApeAttributeError) 'GnosisSafeProxy' has no attribute 'VERSION'.
Please include information like:
Fill this in if you have ideas on how the bug could be fixed.
Currently, we just support v1.3.0 in our test suite, we should ensure that our plugin works for v1.4.1, and potentially releases older than v1.3.0 (by first checking for usage of those older versions)
Add each version as a dependency here:
https://github.com/ApeWorX/ape-safe/blob/main/ape-config.yaml#L13
Then update the new versions here:
https://github.com/ApeWorX/ape-safe/blob/main/tests/conftest.py#L40
May need some Ape core updates for working with multiple versions of the same dependencies
My goal is to avoid having to unnecessarily declare the safe when I only am using 1 safe.
You get this error when you don't tell ape-safe to use the one and only safe:
Error: Missing argument '{ape-safe-test}'. Choose from:
ape-safe-test
ape safe pending --network ethereum:goerli
uses the safe rather than forcing me to do:
ape safe pending --network ethereum:goerli <SAFE-NAME>
Include links to any open issues that must be resolved before this feature can be implemented.
ape
and plugin versions:$ ape --version
0.7.9
$ ape plugins list
Installed Plugins
alchemy 0.7.1
arbitrum 0.7.2
etherscan 0.7.1
foundry 0.7.3
infura 0.7.1
ledger 0.7.0
optimism 0.7.2
safe 0.7.0b1
tokens 0.7.1
I am trying to execute a transaction directly on a public network using the Safe plugin (but aiming to publish to the Safe API only)
File "site-packages/ape_ethereum/provider.py", line 249, in estimate_gas_cost
return self.web3.eth.estimate_gas(txn_params, block_identifier=block_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/web3/eth/eth.py", line 312, in estimate_gas
return self._estimate_gas(transaction, block_identifier)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/web3/module.py", line 75, in caller
result = w3.manager.request_blocking(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/web3/manager.py", line 326, in request_blocking
return self.formatted_response(
^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/web3/manager.py", line 289, in formatted_response
raise ValueError(error)
ValueError: {'code': -32000, 'message': 'insufficient funds for transfer'}
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "script.py", line 38, in foo
contract.methodName(sender=safe, submit_transaction=False)
File "site-packages/ape/contracts/base.py", line 356, in __call__
return contract_transaction(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/ape/contracts/base.py", line 290, in __call__
return kwargs["sender"].call(txn, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "python3.11/contextlib.py", line 81, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "site-packages/ape_safe/accounts.py", line 531, in call
return super().call(txn, **call_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/ape/api/accounts.py", line 125, in call
txn = self.prepare_transaction(txn)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/ape_safe/accounts.py", line 462, in prepare_transaction
return self.provider.prepare_transaction(txn)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/ape_ethereum/provider.py", line 861, in prepare_transaction
gas = self.estimate_gas_cost(txn)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "site-packages/ape_ethereum/provider.py", line 259, in estimate_gas_cost
raise TransactionError(
ape.exceptions.TransactionError: Gas estimation failed: 'insufficient funds for transfer'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.
I believe the root cause to be that the Safe I am using to execute has zero balance, leading web3py to fail when calling eth_estimateGas
. Some effort to bypass this behavior or override the balance of the contract could help assist in properly determining the gas cost it would take.
Not sure if this a good idea, but sometimes when you are having to play with a transaction to get it working, you might need to submit it multiple times with different gas values (such as if the gas price keeps rising or something), it would be great in this scenario not to have to call sign_transaction
multiple times with the safe, since the request will be the same.
One potential solution is to "cache" the signatures for a given SafeTx
hash, since those signatures are likely to continue being valid. You might also want to submit it to the Safe API if it fails the first time, so you can come back and execute it later.
No UX changes, it just caches by SafeTxID
under the hood
n/a
it would be nice to be able to save/load prepared safe txs. maybe we could use an existing format used in the official tx builder app.
none
operation
denotes a call type (0=call, 1=delegatecall). the transaction would fail if we encode the wrong operation types. multisend specifically requires to be only called as a delegatecall.
users can currently work around this by passing a kwarg like txn(sender=safe, operation=1)
, but this is not very convenient and it should be fixed either in the library of ape api to allow passing it over.
ape-safe/ape_safe/multisend.py
Line 250 in 4c0891b
ape
and plugin versions:(venv) user@Users-Laptop safe % ape --version
0.6.15
(venv) user@Users-Laptop safe % ape plugins list
No plugins installed. Use '--all' to see available plugins.
Error when attempting to install ape-safe via pip install and ape plugin install
(venv) user@Users-Laptop safe % ape plugins install safe
INFO: Installing safe...
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [86 lines of output]
Error compiling Cython file:
------------------------------------------------------------
...
cdef readonly object func
cdef readonly tuple args
cdef readonly dict keywords
cdef public object __doc__
cdef public object __name__
cdef public object __module__
^
------------------------------------------------------------
cytoolz/functoolz.pxd:18:23: '__module__' redeclared
Error compiling Cython file:
------------------------------------------------------------
...
cdef readonly object func
cdef readonly tuple args
cdef readonly dict keywords
cdef public object __doc__
cdef public object __name__
cdef public object __module__
^
------------------------------------------------------------
cytoolz/functoolz.pxd:18:9: Compiler crash in AnalyseDeclarationsTransform
File 'ModuleNode.py', line 203, in analyse_declarations: ModuleNode(functoolz.pxd:1:0,
full_module_name = 'cytoolz.functoolz',
is_pxd = True)
File 'Nodes.py', line 393, in analyse_declarations: StatListNode(functoolz.pxd:1:0)
File 'Nodes.py', line 5497, in analyse_declarations: CClassDefNode(functoolz.pxd:10:5,
as_name = 'curry',
class_name = 'curry',
in_pxd = True,
module_name = '',
punycode_class_name = 'curry',
visibility = 'private')
File 'Nodes.py', line 393, in analyse_declarations: StatListNode(functoolz.pxd:11:4)
File 'Nodes.py', line 1528, in analyse_declarations: CVarDefNode(functoolz.pxd:18:9,
in_pxd = True,
modifiers = [...]/0,
visibility = 'public')
Compiler crash traceback from this point on:
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/Cython/Compiler/Nodes.py", line 1528, in analyse_declarations
self.entry = dest_scope.declare_var(
^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/Cython/Compiler/Symtab.py", line 2389, in declare_var
entry = self.declare(name, cname, type, pos, visibility)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/Cython/Compiler/Symtab.py", line 550, in declare
entries[name].already_declared_here()
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/Cython/Compiler/Symtab.py", line 262, in already_declared_here
error(self.pos, "Previous declaration is here")
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/Cython/Compiler/Errors.py", line 178, in error
raise InternalError(message)
InternalError: Internal compiler error: Previous declaration is here
[1/5] Cythonizing cytoolz/dicttoolz.pyx
[2/5] Cythonizing cytoolz/functoolz.pyx
Traceback (most recent call last):
File "/Users/user/.local/pipx/shared/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
main()
File "/Users/user/.local/pipx/shared/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/.local/pipx/shared/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel
return hook(config_settings)
^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 355, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=['wheel'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 325, in _get_build_requires
self.run_setup()
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 507, in run_setup
super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script)
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/setuptools/build_meta.py", line 341, in run_setup
exec(code, locals())
File "<string>", line 85, in <module>
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/Cython/Build/Dependencies.py", line 1134, in cythonize
cythonize_one(*args)
File "/private/var/folders/3_/z8rn91w566l816hsprr2k4w80000gn/T/pip-build-env-e05_0hgb/overlay/lib/python3.11/site-packages/Cython/Build/Dependencies.py", line 1301, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: cytoolz/functoolz.pyx
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed to install plugin 'safe.
Fill this in if you have ideas on how the bug could be fixed.
Safe has a multi-chain proxy service that works across all of their backends, it would be easier to support this via client then to add (and test) one-per-network
https://safe-client.safe.global/api
Include links to any open issues that must be resolved before this feature can be implemented.
ape
and plugin versions:$ ape --version
# ...copy and paste result of above command here...
0.7.1
$ ape plugins list
# ...copy and paste result of above command here...
Installed Plugins
alchemy 0.7.1
etherscan 0.7.0
foundry 0.7.1
optimism 0.7.1
safe 0.7.0b0
solidity 0.7.1
The bytecode of the multicall contract 0x998739BFdAAdde7C933B942a68053933098f9EDa
is not a unique identifier for the contract, optimism does not match with what is saved under the repo. This results in UnsupportedChainError: Multicall not supported on this chain.
when trying to run a multicall on optimism.
Please include information like:
with networks.optimism.mainnet.use_default_provider():
contract = Contract(address=address,abi=json.loads(abi))
txn = multisend.MultiSend()
txn.add(contract.transfer,"0xxxxxxxxxxxxxxxx",1000000,delegatecall=True)
txn(sender=self.safe)
UnsupportedChainError: Multicall not supported on this chain.
I would remove the check here in favor of printing an output to the user in case the chain is not endorsed. Endorsed chain ids are already pre-specified here.
safe transaction service has recently added support for aggregating signatures for off-chain messages.
the flow for them is similar to transactions, except they never get executed and instead are passed to other contracts, that check isValidSignature
. for example, this enables sending cowswap orders in a completely off-chain manner.
we could support them via AccountAPI.sign_message
see here for an example/reference:
https://gist.github.com/banteg/68ad51b133d447aa4a165bea0c7b91a1
see here for the client api:
https://safe-transaction-mainnet.safe.global/
depends on ApeWorX/ape#1508
Safe has a differnet version of the contract for L2 networks:
https://github.com/safe-global/safe-smart-account/blob/main/contracts/SafeL2.sol
Need updates to the relevant features of our plugin to ensure that it functions properly with all the core features that we have
n/a
ape
and plugin versions:$ ape plugins list
alchemy 0.7.1
etherscan 0.7.0
foundry 0.7.1
optimism 0.7.1
safe 0.7.0b0
solidity 0.7.1
Please include information like:
with networks.optimism.mainnet.use_default_provider():
contract = Contract(address=address,abi=json.loads(abi))
txn = multisend.MultiSend()
txn.add(contract.transfer,"0xxxxxxxxxxxxxxxx",1000000,delegatecall=True)
txn(sender=self.safe)
The error props up in provider.py
under the estimate_gas_cost
where estimation fails, most likely it's related to txn_params
being improperly configured for that gas estimation.
Traceback (most recent call last):
File ~/miniconda3/envs/monitor/lib/python3.9/site-packages/ape_ethereum/provider.py:240 in estimate_gas_cost
return self.web3.eth.estimate_gas(txn_params, block_identifier=block_id)
File ~/miniconda3/envs/monitor/lib/python3.9/site-packages/web3/eth/eth.py:311 in estimate_gas
return self._estimate_gas(transaction, block_identifier)
File ~/miniconda3/envs/monitor/lib/python3.9/site-packages/web3/module.py:75 in caller
result = w3.manager.request_blocking(
File ~/miniconda3/envs/monitor/lib/python3.9/site-packages/web3/manager.py:326 in request_blocking
return self.formatted_response(
File ~/miniconda3/envs/monitor/lib/python3.9/site-packages/web3/manager.py:287 in formatted_response
apply_error_formatters(error_formatters, response)
File ~/miniconda3/envs/monitor/lib/python3.9/site-packages/web3/manager.py:104 in apply_error_formatters
formatted_resp = pipe(response, error_formatters)
File cytoolz/functoolz.pyx:680 in cytoolz.functoolz.pipe
File cytoolz/functoolz.pyx:655 in cytoolz.functoolz.c_pipe
File ~/miniconda3/envs/monitor/lib/python3.9/site-packages/web3/_utils/contract_error_handling.py:161 in raise_contract_logic_error_on_revert
raise ContractLogicError(message, data=data)
ContractLogicError: execution reverted: MultiSend should only be called via delegatecall
I changed switched the to
in the tx_params variable, to the address of the contract being interacted with in the individual send, rather then the multisend and it seems to have not reverted in the multicall.
tx_params is as follows:
{'chainId': 10, 'to': '0x998739BFdAAdde7C933B942a68053933098f9EDa', 'from': 'MY_SAFE_ADDRESS', 'value': 0, 'data': '0x8d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000079014200000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000242e1a7d4d000000000000000000000000000000000000000000000000000000000000006400000000000000', 'type': '0x02', 'maxFeePerGas': 5373609, 'maxPriorityFeePerGas': 1000000, 'accessList': []}
Fill this in if you have ideas on how the bug could be fixed.
Can't compile the safe-contracts dependency until this is fixed: ApeWorX/ape#1221
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.