-
Notifications
You must be signed in to change notification settings - Fork 465
Conversation
8169d02
to
f9814b0
Compare
@@ -22,9 +22,6 @@ pragma solidity ^0.5.9; | |||
contract LibExchangeSelectors { |
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 think we can probably ditch this file, right?
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.
+1 the current approach is error-prone and not worth the small gas optimization over .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.
Removed it entirely from the Exchange contracts. Coordinator and DevUtils still use it quite heavily, so I added it to the backlog.
f9814b0
to
7bc7090
Compare
I really like the idea of consolidating integration tests into a single package. We'd get an overview of protocol-wide test coverage without having to sift through all of our packages. |
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.
Lots of great stuff in this PR (~‾▿‾)~
@@ -22,9 +22,6 @@ pragma solidity ^0.5.9; | |||
contract LibExchangeSelectors { |
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.
+1 the current approach is error-prone and not worth the small gas optimization over .selector
.
/// Because this function uses the `nonReentrant` modifier, if | ||
/// the function being called is also guarded by the `nonReentrant` modifier, | ||
/// it will revert when it returns. | ||
function testReentrantFunction(bytes calldata fnCallData) |
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.
Is this only called by isReentrant
? If so, why not apply the nonReentrant
modifier directly to isReentrant
?
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.
Mostly for UX reasons. Because our reentrancy guard is lazy, only second to the last non-reentrant call will revert. If I made isReentrant()
nonReentrant
, I wouldn't be able to capture and compare the revert data within the contract and provide a nice boolean result.
@@ -0,0 +1,1129 @@ | |||
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs'; |
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.
Readability lvl 💯
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.
+1
7bc7090
to
5e9fe4f
Compare
`@0x/contracts-exchange`: Add more `wrapper_unit_tests` tests.
…computed for `wrapper_unit_tests`.
…match v2.1. `@0x/contracts-exchange`: Add EOA tests to `signature_validator`.
`@0x/contracts-exchange`: Remove old reentrancy tests. `@0x/contracts-exchange`: Remove `ReentrantERC20Token` contract.
`@0x/contracts-coordinator`: Add `MixinCoordinatorApprovalVerifier.sol` to `.solhintignore` because of `abi.decode` issues.
`MarketXOrders' functions.
`@0x/contracts-test-utils`: Remove unecessary wait timeout in `LogDecoder`.
`@0x/contracts-exchange`: Remove references to `marketXOrdersNoThrow`.
`@0x/contracts-exchange`: Update reentrancy tests. `@0x/contracts-exchange`: Add all mutator functions to `ExchangeFunctions` type. `@0x/contracts-tes-utils`: Remove unused import.
… constant in `TestValidatorWallet.sol`. `@0x/contracts-exchange`: Remove references to `LibExchangeSelectors` in the Exchange.
5e9fe4f
to
ca33090
Compare
@@ -0,0 +1,2 @@ | |||
# solhint can't parse `abi.decode` syntax. | |||
contracts/src/MixinCoordinatorApprovalVerifier.sol |
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.
Can we just disable that specific block of code? The rest of the contract is still being linted correctly right?
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 tried but solhint throws a parser error when it hits that contract. I'm a little confused about why this just started happening and with only certain forms of abi.decode()
. I don't think it's just my setup because the same thing happened on CI (that's how I first noticed it).
|
||
import { constants as TestConstants } from './utils/constants'; | ||
|
||
blockchainTests.resets('Reentrancy Tests', env => { |
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.
Nice! Having this all in one place is so much cleaner.
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.
➕
@@ -0,0 +1,1129 @@ | |||
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs'; |
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.
+1
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 good! This is much cleaner than reentrancy previously was. I had a few nits, but it looks good to go once those are addressed.
{} | ||
|
||
/// @dev Calls a public function to check if it is reentrant. | ||
function isReentrant(bytes calldata fnCallData) |
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 think that it would make sense to start compiling a list of functions that need this modifier so that we can manually check during code reviews. That would also make it really easy when we start using static analysis.
@@ -1,388 +0,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.
🔥 So glad we're getting rid of this contract
|
||
import { constants as TestConstants } from './utils/constants'; | ||
|
||
blockchainTests.resets('Reentrancy Tests', env => { |
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.
➕
…rom many `MixinSignatureValidator` functions.
… return incorrect data.
…alidOrderSignature()` semantics.
Description
This PR introduces a couple things:
Exchange Wrapper Unit Tests
You'll find many new unit tests for Exchange wrapper functions in wrapper_unit_tests.ts.
This is accomplished by overriding a few Exchange internal functions in TestWrappersFunctions.sol so we test only the logic of the wrapper functions themselves.
Automatic Reentrancy Guard Testing
You'll find some lovely tests in reentrancy_tests.ts that automatically 🤖 checks if public Exchange functions are secured by the
nonReentrant
modifier. This voodoo is accomplished by the ReentrancyTester.sol contract.By default, it will check all mutator public functions that are not whitelisted in test/utils/constants.ts, and it'll even check that those whitelisted functions are actually reentrant. This makes it much harder to accidentally expose a reentrant public function.
I've also removed a lot of the legacy reentrancy tests scattered around the tests because I feel like the new tests cover them. This is might be controversial. 😇
Other goodies:
marketBuyOrders
andmarketSellOrders
have been removed and theirnoThrow
variants have replaced them.MixinSignatureValidator
will now throw anInvalidSigner
if thesignerAddress == 0
. This is to prevent people from using0x0
as asignerAddress
and passing bad signature data toecrecover()
, which will happily return0x0
.fillOrderNoThrow
🎉Wallet
signature type (which we still support in V3) to use the magic bytes pattern from v2.1 of the Exchange.constants.ExchangeFunctions
in@0x/contracts/exchange/test/utils.ts
.abi.decode
syntax:contracts/coordinator/contracts/src/MixinCoordinatorApprovalVerifier.sol
. 😞Some Thoughts
I think it might be cleaner to move ALL integration tests out of the exchange package and into its own package (like a
protocol-tests
package?), when we have more time. There's a lot of integration tests that pull in many external contract packages so things are looking a little spaghetti...Testing instructions
You know the drill.
Types of changes
New feature (non-breaking change which adds functionality)
Breaking change (fix or feature that would cause existing functionality to change)
Checklist:
[WIP]
if necessary.