-
Notifications
You must be signed in to change notification settings - Fork 465
[3.0] Exchange Rich Reverts (once more, with feeling!) #1761
[3.0] Exchange Rich Reverts (once more, with feeling!) #1761
Conversation
Fix compilation issues in `exchange`.
Add rich reverts chai helper tests to `dev-utils`
Rename `StandardError` to `StringRevertError`. Rename `RichRevertAbi` to `RevertErrorAbi`. Make `RevertError` extend `Error` so it can be thrown. Add `RevertError` tests.
Tweak `RevertError` coercion in chai helper. Add more `RevertError` chai helper tests.
…and throw `RevertError`s. Remove no longer necessary dependency on `ethers.js` in `@0x/base-contract`.
…de not passing all arguments to previous handler. In `@0x/dev-utils` add more `RevertError` chai helper tests for backwards compatibility with `rejectedWith`. In `@0x/dev-utils` instead of overriding `rejectedWith`, add a new method `revertWith`. In `@0x/dev-utils` clean up the code for the `RevertError` chai helper.
…te file from `chai_setup.ts`. In `@0x/dev-utils`: Add chai support for ganache and geth transaction reverts.
Approved the Typescript code only. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is sooooo nice and super clean. There are a few nits before merging, but great work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks awesome and I'm excited to use it! Good to merge after addressing @abandeali1's comments.
…ector` in `RichErrors.StandardError`
…in `MixinAssetProxyDispatcher.sol`
…eRevertErrors.SignatureError`. In `@0x/contracts-exchange`: Add `signerAddress` and `signature` to `SignatureError` reverts.
…ertErrors`. In `@0x/contracts-exchange`: Add `TransactionSignatureError`, supplanting `TransactionErrorCodes.BAD_SIGNATURE`, and associated test.
17cc83d
to
cb010eb
Compare
// | | 68 | n | Left-aligned message bytes | | ||
|
||
// Get the size of the string data/payload. | ||
let revertDataSize := sub(returndatasize(), 36) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Omitting the first 36 bytes works if we assume that the revert data is always a string, but what if we move to rich revert reasons for asset proxies too? In that case, it's probably better to just include all of the return data and decode client side based off of the function selector.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented here.
} | ||
return isValid; | ||
// Static call the verification function. | ||
(bool didSucceed, bytes memory returnData) = walletAddress.staticcall(callData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that you can just do IValidator.isValidSignature(...)
and it will compile with the staticcall
opcode in Solidity ^0.5.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but don't we want to catch the revert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can return the revert data, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-Authored-By: dorothy-zbornak <[email protected]>
…Error` to `ExchangeRevertErrors`. Update `AssetProxyTransferError` to accept arbitrary `errorData` bytes instead of a `revertReason` string.
…eValidatorError` rich reverts. In `@0x/contracts-exchange`: Change `AssetProxyTransferError` to accept a `revertData` bytes instead of a `revertReason` string. In `@0x/contracts-exchange`: Aadd `contracts/test/TestRevertReceiver.sol` for testing that validator/wallet reverts are properly wrapped.
…t to `== 1` instead of `!= 0`.
Description
This is a complete overhaul and more holistic implementation of my initial proof-of-concept #1688. Kindly refer to that PR for background on the issue, encoding details, and to mock my rookie naiveté.
Summary
This PR introduces the tools for raising, consuming, and testing rich revert errors from smart contracts. It introduces a new idiom for testing contract reverts (rich or plain) via Chai extensions. It also upgrades all errors thrown by the Exchange contract into said rich reverts.
Notable Changes
Smart Contracts
contracts/utils
which exposes arrevert()
function.rich reverts.
Tooling
RevertError
base class in@0x/utils
:StringRevertError
) and rich reverts.TransactionExecutionError
s which carry an ABI-encoded payload of the original error.Error
for backwards compatiblity with existing tests.RevertError
types for the Exchange in@0x/order-utils.ExchangeRevertErrors
.@0x/dev-utils
:equal()
to andbecome()
to support comparisons betweenRevertError
types.revertWith()
, for testing both transaction and call promises that should revert. It's also backwards compatible with regular string reverts, such as those in@0x/types.RevertReason
.expectContractCallFailedAsync()
andexpectTransactionFailedAsync()
functions from@0x/contracts-test-utils
with a nice Chai expression:return expect(tx).to.revertWith(...)
.@0x/contracts-test-utils
and others now inherit theirchaiSetup
from@0x/dev-utils.chaiSetup
so the new Chai extensions are available just about everywhere.@0x/base-contract
to automatically decode and throwRevertError
s.Testing instructions
Affected contract tests have been updated/converted to handle rich reverts conform to the new testing idiom. Specifically, these packages are:
@0x/contracts-exchange
@0x/contracts-extensions
Tests for
RevertError
s and the new Chai extensions have been added to:@0x/utils
@0x/dev-utils
Types of changes
Checklist:
[WIP]
if necessary.Addresses 0xProject/ZEIPs/issues/32