ApeWorX / ape

The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals
https://apeworx.io
Apache License 2.0
868 stars 133 forks source link

Ecosystem.decode_error() (inspired by custom Solidity error types) #690

Closed antazoey closed 1 year ago

antazoey commented 2 years ago

Elevator pitch:

When using solidity error definitions, the revert message (the inputs to the custom error) are not decoded (they are just bytes).

e.g.

ape.exceptions.ContractLogicError: b'\x9b\x0f\x01\xda\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;\x9a\xca\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\x00\x00\x01'

Let's do what we do best and dynamically generate a custom Exception class with the inputs as the properties!

Value:

Solidity projects that use custom errors.

Dependencies:

https://github.com/ApeWorX/ethpm-types/pull/29#pullrequestreview-961074682

Design approach:

Like structs, events, etc, let's create custom ContractLogicError classes that have the inputs as the properties on the class

So in your solidity, if you do:

    error InsufficientFund(uint256 given, uint256 required);

    function fund() public payable isOn {
        if (msg.value > 0) {
            revert InsufficientFund(msg.value, 1);
        }
    }

, you can access the custom error classes on the ContractInstance and they will be the exceptions raised for reverts in that case.

So you can do this in your tests:

with ape.reverts(contract.InsufficientFund) as err:
    ...

assert err.value.foo == 5
assert err.value.bar == 6

NOTE: The original still has to work to as not be breaking:

with ape.reverts(message="revert reason"):

Task list:

Estimated completion date:

Design review:

Do not signoff unless:

(Please leave a comment to sign off)

fubuloubu commented 2 years ago

Everything looks good, approved

Perhaps can use single dispatch to allow both message and exception class to be used in ape.reverts