Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Balance Threshold Filter #1383

Merged
merged 71 commits into from
Dec 18, 2018
Merged

Conversation

hysz
Copy link
Contributor

@hysz hysz commented Dec 5, 2018

Description

This supersedes #1358. This is a more generalized implementation with support for more Exchange functions. Also includes wrappers.

Testing instructions

Types of changes

Checklist:

  • Prefix PR title with [WIP] if necessary.
  • Add tests to cover changes as needed.
  • Update documentation as needed.
  • Add new entries to the relevant CHANGELOG.jsons.

@coveralls
Copy link

coveralls commented Dec 8, 2018

Coverage Status

Coverage remained the same at 85.28% when pulling ca0ab38 on feature/contracts/balanceThresholdFilter into 67df5a4 on development.

@fabioberger
Copy link
Contributor

@hysz once #1413 lands, mind resolving the merge conflicts? Should land soon.

@hysz hysz force-pushed the feature/contracts/balanceThresholdFilter branch from 9c2fed6 to 60fa565 Compare December 11, 2018 22:49
@hysz hysz changed the title WIP Balance Threshold Filter Balance Threshold Filter Dec 12, 2018
Copy link
Member

@abandeali1 abandeali1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will continue this review in a bit!

/// @dev Records addresses to be validated when Exchange transaction is a batch fill variant.
/// This is one of: batchFillOrders, batchFillOrKillOrders, batchFillNoThrow
/// Reference signature<T>: <batchFillVariant>(Order[],uint256[],bytes[])
function recordAddressesForBatchFillVariant() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this includes batchCancel, I'd just name this function recordAddressesForBatchVariant.

/// @dev Records addresses to be validated when Exchange transaction is a fill order variant.
/// This is one of: fillOrder, fillOrKillOrder, fillOrderNoThrow
/// Reference signature<T>: <fillOrderVariant>(Order,uint256,bytes)
function recordAddressesForFillOrderVariant() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to recordAddressesForSingleOrderVariant.

/// @dev Records addresses to be validated when Exchange transaction is a market fill variant.
/// This is one of: marketBuyOrders, marketBuyOrdersNoThrow, marketSellOrders, marketSellOrdersNoThrow
/// Reference signature<T>: <marketFillInvariant>(Order[],uint256,bytes[])
function recordAddressesForMarketFillVariant() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just remove this function and lump it in with the rest of the batch variants.

*/

pragma solidity 0.4.24;
pragma experimental ABIEncoderV2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to remove pragma experimental ABIEncoderV2; throughout all of these contracts.

import "./MixinBalanceThresholdFilterCore.sol";


contract BalanceThresholdFilter is MixinBalanceThresholdFilterCore {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: all of our other contracts put inherited contracts on a newline:

contract BalanceThresholdFilter is
    MixinBalanceThresholdFilterCore
{}

/// @param signerAddress Address of transaction signer.
/// @param signedExchangeTransaction AbiV2 encoded calldata.
/// @param signature Proof of signer transaction by signer.
function executeTransaction(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

external and public functions should live in an interface (which the mixin can inherit)

/// @dev Records addresses to be validated when Exchange transaction is a market fill variant.
/// This is one of: marketBuyOrders, marketBuyOrdersNoThrow, marketSellOrders, marketSellOrdersNoThrow
/// Reference signature<T>: <marketFillInvariant>(Order[],uint256,bytes[])
function recordAddressesForMarketFillVariant() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd merge this with recordAddressesForBatchFillVariant (I'd consider the market fill functions to be a subset of the batch fill functions).

// See ../../utils/ExchangeSelectors/ExchangeSelectors.sol for selectors
// solhint-disable no-empty-blocks
switch exchangeFunctionSelector
case 0x297bb70b00000000000000000000000000000000000000000000000000000000 { recordAddressesForBatchFillVariant() } // batchFillOrders
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add comments above each of these selectors with the function names

/// @param addressToValidate - Address to record for validation.
function recordAddressToValidate(addressToValidate) {
// Compute `addressesToValidate` memory offset
let addressesToValidate_ := mload(0x40)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be cleaner to do this without creating new temporary variables (I find these variable names confusing). All we really need to do is 1. increment length, 2. store new address at free memory ptr, 3. increment free memory ptr.

///// Validate Recorded Addresses /////

// Load from memory the addresses to validate
let addressesToValidate := mload(0x40)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels safer and more descriptive to make this let addressesToValidate := mload(add(validatedAddresses, 0x20)) (only really matters if we're manually incrementing the free memory ptr as suggested above).

mstore(add(freeMemPtr, 0x04), mload(addressToValidate))

// call `THRESHOLD_ASSET.balanceOf`
let success := call(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to make this a staticcall. Thoughts?

0x20 // reserve space for return balance (0x20 bytes)
)
if eq(success, 0) {
// @TODO Revert with `Error("BALANCE_QUERY_FAILED")`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this TODO.

@hysz hysz force-pushed the feature/contracts/balanceThresholdFilter branch 2 times, most recently from fe2efbe to a10418b Compare December 14, 2018 21:54
IThresholdAsset thresholdAsset = THRESHOLD_ASSET;
for (uint256 i = 0; i < addressesToValidate.length; ++i) {
uint256 addressBalance = thresholdAsset.balanceOf(addressesToValidate[i]);
if (addressBalance < balanceThreshold) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this a require statement.

import "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol";


library LibAddressArray {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename this LibAddress and we can add in other helper functions later if necessary?

@hysz hysz force-pushed the feature/contracts/balanceThresholdFilter branch from 20c2bd7 to ca0ab38 Compare December 18, 2018 21:36
@hysz hysz merged commit 38346a9 into development Dec 18, 2018
@hysz hysz deleted the feature/contracts/balanceThresholdFilter branch March 16, 2019 04:35
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants