ETH Price: $2,472.11 (+0.94%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x6080604064054632018-09-26 22:21:432230 days ago1538000503IN
 Create: ZeroExV2ExchangeWrapper
0 ETH0.0329578821

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ZeroExV2ExchangeWrapper

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-09-26
*/

pragma solidity 0.4.24;
pragma experimental "v0.5.0";
pragma experimental ABIEncoderV2;

/*

    Copyright 2018 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (_a == 0) {
      return 0;
    }

    c = _a * _b;
    assert(c / _a == _b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
    // assert(_b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = _a / _b;
    // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
    return _a / _b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
    assert(_b <= _a);
    return _a - _b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    c = _a + _b;
    assert(c >= _a);
    return c;
  }
}

// File: contracts/external/0x/v2/libs/LibOrder.sol

contract LibOrder
{
    // A valid order remains fillable until it is expired, fully filled, or cancelled.
    // An order's state is unaffected by external factors, like account balances.
    enum OrderStatus {
        INVALID,                     // Default value
        INVALID_MAKER_ASSET_AMOUNT,  // Order does not have a valid maker asset amount
        INVALID_TAKER_ASSET_AMOUNT,  // Order does not have a valid taker asset amount
        FILLABLE,                    // Order is fillable
        EXPIRED,                     // Order has already expired
        FULLY_FILLED,                // Order is fully filled
        CANCELLED                    // Order has been cancelled
    }

    struct Order {
        address makerAddress;           // Address that created the order.
        address takerAddress;           // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order.
        address feeRecipientAddress;    // Address that will recieve fees when order is filled.
        address senderAddress;          // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.
        uint256 makerAssetAmount;       // Amount of makerAsset being offered by maker. Must be greater than 0.
        uint256 takerAssetAmount;       // Amount of takerAsset being bid on by maker. Must be greater than 0.
        uint256 makerFee;               // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted.
        uint256 takerFee;               // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted.
        uint256 expirationTimeSeconds;  // Timestamp in seconds at which order expires.
        uint256 salt;                   // Arbitrary number to facilitate uniqueness of the order's hash.
        bytes makerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The last byte references the id of this proxy.
        bytes takerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy.
    }

    struct OrderInfo {
        uint8 orderStatus;                    // Status that describes order's validity and fillability.
        bytes32 orderHash;                    // EIP712 hash of the order (see LibOrder.getOrderHash).
        uint256 orderTakerAssetFilledAmount;  // Amount of order that has already been filled.
    }
}

// File: contracts/external/0x/v2/libs/LibFillResults.sol

contract LibFillResults
{
    struct FillResults {
        uint256 makerAssetFilledAmount;  // Total amount of makerAsset(s) filled.
        uint256 takerAssetFilledAmount;  // Total amount of takerAsset(s) filled.
        uint256 makerFeePaid;            // Total amount of ZRX paid by maker(s) to feeRecipient(s).
        uint256 takerFeePaid;            // Total amount of ZRX paid by taker to feeRecipients(s).
    }

    struct MatchedFillResults {
        FillResults left;                    // Amounts filled and fees paid of left order.
        FillResults right;                   // Amounts filled and fees paid of right order.
        uint256 leftMakerAssetSpreadAmount;  // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker.
    }
}

// File: contracts/external/0x/v2/interfaces/IExchangeCore.sol

contract IExchangeCore {

    /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch
    ///      and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).
    /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.
    function cancelOrdersUpTo(uint256 targetOrderEpoch)
        external;

    /// @dev Fills the input order.
    /// @param order Order struct containing order specifications.
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
    /// @param signature Proof that order has been created by maker.
    /// @return Amounts filled and fees paid by maker and taker.
    function fillOrder(
        LibOrder.Order memory order,
        uint256 takerAssetFillAmount,
        bytes memory signature
    )
        public
        returns (LibFillResults.FillResults memory fillResults);

    /// @dev After calling, the order can not be filled anymore.
    /// @param order Order struct containing order specifications.
    function cancelOrder(LibOrder.Order memory order)
        public;

    /// @dev Gets information about an order: status, hash, and amount filled.
    /// @param order Order to gather information on.
    /// @return OrderInfo Information about the order and its state.
    ///                   See LibOrder.OrderInfo for a complete description.
    function getOrderInfo(LibOrder.Order memory order)
        public
        view
        returns (LibOrder.OrderInfo memory orderInfo);
}

// File: contracts/external/0x/v2/interfaces/IMatchOrders.sol

contract IMatchOrders {

    /// @dev Match two complementary orders that have a profitable spread.
    ///      Each order is filled at their respective price point. However, the calculations are
    ///      carried out as though the orders are both being filled at the right order's price point.
    ///      The profit made by the left order goes to the taker (who matched the two orders).
    /// @param leftOrder First order to match.
    /// @param rightOrder Second order to match.
    /// @param leftSignature Proof that order was created by the left maker.
    /// @param rightSignature Proof that order was created by the right maker.
    /// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders.
    function matchOrders(
        LibOrder.Order memory leftOrder,
        LibOrder.Order memory rightOrder,
        bytes memory leftSignature,
        bytes memory rightSignature
    )
        public
        returns (LibFillResults.MatchedFillResults memory matchedFillResults);
}

// File: contracts/external/0x/v2/interfaces/ISignatureValidator.sol

contract ISignatureValidator {

    /// @dev Approves a hash on-chain using any valid signature type.
    ///      After presigning a hash, the preSign signature type will become valid for that hash and signer.
    /// @param signerAddress Address that should have signed the given hash.
    /// @param signature Proof that the hash has been signed by signer.
    function preSign(
        bytes32 hash,
        address signerAddress,
        bytes signature
    )
        external;

    /// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf.
    /// @param validatorAddress Address of Validator contract.
    /// @param approval Approval or disapproval of  Validator contract.
    function setSignatureValidatorApproval(
        address validatorAddress,
        bool approval
    )
        external;

    /// @dev Verifies that a signature is valid.
    /// @param hash Message hash that is signed.
    /// @param signerAddress Address of signer.
    /// @param signature Proof of signing.
    /// @return Validity of order signature.
    function isValidSignature(
        bytes32 hash,
        address signerAddress,
        bytes memory signature
    )
        public
        view
        returns (bool isValid);
}

// File: contracts/external/0x/v2/interfaces/ITransactions.sol

contract ITransactions {

    /// @dev Executes an exchange method call in the context of signer.
    /// @param salt Arbitrary number to ensure uniqueness of transaction hash.
    /// @param signerAddress Address of transaction signer.
    /// @param data AbiV2 encoded calldata.
    /// @param signature Proof of signer transaction by signer.
    function executeTransaction(
        uint256 salt,
        address signerAddress,
        bytes data,
        bytes signature
    )
        external;
}

// File: contracts/external/0x/v2/interfaces/IAssetProxyDispatcher.sol

contract IAssetProxyDispatcher {

    /// @dev Registers an asset proxy to its asset proxy id.
    ///      Once an asset proxy is registered, it cannot be unregistered.
    /// @param assetProxy Address of new asset proxy to register.
    function registerAssetProxy(address assetProxy)
        external;

    /// @dev Gets an asset proxy.
    /// @param assetProxyId Id of the asset proxy.
    /// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.
    function getAssetProxy(bytes4 assetProxyId)
        external
        view
        returns (address);
}

// File: contracts/external/0x/v2/interfaces/IWrapperFunctions.sol

contract IWrapperFunctions {

    /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
    /// @param order LibOrder.Order struct containing order specifications.
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
    /// @param signature Proof that order has been created by maker.
    function fillOrKillOrder(
        LibOrder.Order memory order,
        uint256 takerAssetFillAmount,
        bytes memory signature
    )
        public
        returns (LibFillResults.FillResults memory fillResults);

    /// @dev Fills an order with specified parameters and ECDSA signature.
    ///      Returns false if the transaction would otherwise revert.
    /// @param order LibOrder.Order struct containing order specifications.
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
    /// @param signature Proof that order has been created by maker.
    /// @return Amounts filled and fees paid by maker and taker.
    function fillOrderNoThrow(
        LibOrder.Order memory order,
        uint256 takerAssetFillAmount,
        bytes memory signature
    )
        public
        returns (LibFillResults.FillResults memory fillResults);

    /// @dev Synchronously executes multiple calls of fillOrder.
    /// @param orders Array of order specifications.
    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
    /// @param signatures Proofs that orders have been created by makers.
    /// @return Amounts filled and fees paid by makers and taker.
    function batchFillOrders(
        LibOrder.Order[] memory orders,
        uint256[] memory takerAssetFillAmounts,
        bytes[] memory signatures
    )
        public
        returns (LibFillResults.FillResults memory totalFillResults);

    /// @dev Synchronously executes multiple calls of fillOrKill.
    /// @param orders Array of order specifications.
    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
    /// @param signatures Proofs that orders have been created by makers.
    /// @return Amounts filled and fees paid by makers and taker.
    function batchFillOrKillOrders(
        LibOrder.Order[] memory orders,
        uint256[] memory takerAssetFillAmounts,
        bytes[] memory signatures
    )
        public
        returns (LibFillResults.FillResults memory totalFillResults);

    /// @dev Fills an order with specified parameters and ECDSA signature.
    ///      Returns false if the transaction would otherwise revert.
    /// @param orders Array of order specifications.
    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
    /// @param signatures Proofs that orders have been created by makers.
    /// @return Amounts filled and fees paid by makers and taker.
    function batchFillOrdersNoThrow(
        LibOrder.Order[] memory orders,
        uint256[] memory takerAssetFillAmounts,
        bytes[] memory signatures
    )
        public
        returns (LibFillResults.FillResults memory totalFillResults);

    /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
    /// @param orders Array of order specifications.
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
    /// @param signatures Proofs that orders have been created by makers.
    /// @return Amounts filled and fees paid by makers and taker.
    function marketSellOrders(
        LibOrder.Order[] memory orders,
        uint256 takerAssetFillAmount,
        bytes[] memory signatures
    )
        public
        returns (LibFillResults.FillResults memory totalFillResults);

    /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
    ///      Returns false if the transaction would otherwise revert.
    /// @param orders Array of order specifications.
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
    /// @param signatures Proofs that orders have been signed by makers.
    /// @return Amounts filled and fees paid by makers and taker.
    function marketSellOrdersNoThrow(
        LibOrder.Order[] memory orders,
        uint256 takerAssetFillAmount,
        bytes[] memory signatures
    )
        public
        returns (LibFillResults.FillResults memory totalFillResults);

    /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.
    /// @param orders Array of order specifications.
    /// @param makerAssetFillAmount Desired amount of makerAsset to buy.
    /// @param signatures Proofs that orders have been signed by makers.
    /// @return Amounts filled and fees paid by makers and taker.
    function marketBuyOrders(
        LibOrder.Order[] memory orders,
        uint256 makerAssetFillAmount,
        bytes[] memory signatures
    )
        public
        returns (LibFillResults.FillResults memory totalFillResults);

    /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.
    ///      Returns false if the transaction would otherwise revert.
    /// @param orders Array of order specifications.
    /// @param makerAssetFillAmount Desired amount of makerAsset to buy.
    /// @param signatures Proofs that orders have been signed by makers.
    /// @return Amounts filled and fees paid by makers and taker.
    function marketBuyOrdersNoThrow(
        LibOrder.Order[] memory orders,
        uint256 makerAssetFillAmount,
        bytes[] memory signatures
    )
        public
        returns (LibFillResults.FillResults memory totalFillResults);

    /// @dev Synchronously cancels multiple orders in a single transaction.
    /// @param orders Array of order specifications.
    function batchCancelOrders(LibOrder.Order[] memory orders)
        public;

    /// @dev Fetches information for all passed in orders
    /// @param orders Array of order specifications.
    /// @return Array of OrderInfo instances that correspond to each order.
    function getOrdersInfo(LibOrder.Order[] memory orders)
        public
        view
        returns (LibOrder.OrderInfo[] memory);
}

// File: contracts/external/0x/v2/interfaces/IExchange.sol

contract IExchange is
    IExchangeCore,
    IMatchOrders,
    ISignatureValidator,
    ITransactions,
    IAssetProxyDispatcher,
    IWrapperFunctions
{}

// File: contracts/lib/MathHelpers.sol

/**
 * @title MathHelpers
 * @author dYdX
 *
 * This library helps with common math functions in Solidity
 */
library MathHelpers {
    using SafeMath for uint256;

    /**
     * Calculates partial value given a numerator and denominator.
     *
     * @param  numerator    Numerator
     * @param  denominator  Denominator
     * @param  target       Value to calculate partial of
     * @return              target * numerator / denominator
     */
    function getPartialAmount(
        uint256 numerator,
        uint256 denominator,
        uint256 target
    )
        internal
        pure
        returns (uint256)
    {
        return numerator.mul(target).div(denominator);
    }

    /**
     * Calculates partial value given a numerator and denominator, rounded up.
     *
     * @param  numerator    Numerator
     * @param  denominator  Denominator
     * @param  target       Value to calculate partial of
     * @return              Rounded-up result of target * numerator / denominator
     */
    function getPartialAmountRoundedUp(
        uint256 numerator,
        uint256 denominator,
        uint256 target
    )
        internal
        pure
        returns (uint256)
    {
        return divisionRoundedUp(numerator.mul(target), denominator);
    }

    /**
     * Calculates division given a numerator and denominator, rounded up.
     *
     * @param  numerator    Numerator.
     * @param  denominator  Denominator.
     * @return              Rounded-up result of numerator / denominator
     */
    function divisionRoundedUp(
        uint256 numerator,
        uint256 denominator
    )
        internal
        pure
        returns (uint256)
    {
        assert(denominator != 0); // coverage-enable-line
        if (numerator == 0) {
            return 0;
        }
        return numerator.sub(1).div(denominator).add(1);
    }

    /**
     * Calculates and returns the maximum value for a uint256 in solidity
     *
     * @return  The maximum value for uint256
     */
    function maxUint256(
    )
        internal
        pure
        returns (uint256)
    {
        return 2 ** 256 - 1;
    }

    /**
     * Calculates and returns the maximum value for a uint256 in solidity
     *
     * @return  The maximum value for uint256
     */
    function maxUint32(
    )
        internal
        pure
        returns (uint32)
    {
        return 2 ** 32 - 1;
    }

    /**
     * Returns the number of bits in a uint256. That is, the lowest number, x, such that n >> x == 0
     *
     * @param  n  The uint256 to get the number of bits in
     * @return    The number of bits in n
     */
    function getNumBits(
        uint256 n
    )
        internal
        pure
        returns (uint256)
    {
        uint256 first = 0;
        uint256 last = 256;
        while (first < last) {
            uint256 check = (first + last) / 2;
            if ((n >> check) == 0) {
                last = check;
            } else {
                first = check + 1;
            }
        }
        assert(first <= 256);
        return first;
    }
}

// File: contracts/lib/GeneralERC20.sol

/**
 * @title GeneralERC20
 * @author dYdX
 *
 * Interface for using ERC20 Tokens. We have to use a special interface to call ERC20 functions so
 * that we dont automatically revert when calling non-compliant tokens that have no return value for
 * transfer(), transferFrom(), or approve().
 */
interface GeneralERC20 {
    function totalSupply(
    )
        external
        view
        returns (uint256);

    function balanceOf(
        address who
    )
        external
        view
        returns (uint256);

    function allowance(
        address owner,
        address spender
    )
        external
        view
        returns (uint256);

    function transfer(
        address to,
        uint256 value
    )
        external;


    function transferFrom(
        address from,
        address to,
        uint256 value
    )
        external;

    function approve(
        address spender,
        uint256 value
    )
        external;
}

// File: contracts/lib/TokenInteract.sol

/**
 * @title TokenInteract
 * @author dYdX
 *
 * This library contains functions for interacting with ERC20 tokens
 */
library TokenInteract {
    function balanceOf(
        address token,
        address owner
    )
        internal
        view
        returns (uint256)
    {
        return GeneralERC20(token).balanceOf(owner);
    }

    function allowance(
        address token,
        address owner,
        address spender
    )
        internal
        view
        returns (uint256)
    {
        return GeneralERC20(token).allowance(owner, spender);
    }

    function approve(
        address token,
        address spender,
        uint256 amount
    )
        internal
    {
        GeneralERC20(token).approve(spender, amount);

        require(
            checkSuccess(),
            "TokenInteract#approve: Approval failed"
        );
    }

    function transfer(
        address token,
        address to,
        uint256 amount
    )
        internal
    {
        address from = address(this);
        if (
            amount == 0
            || from == to
        ) {
            return;
        }

        GeneralERC20(token).transfer(to, amount);

        require(
            checkSuccess(),
            "TokenInteract#transfer: Transfer failed"
        );
    }

    function transferFrom(
        address token,
        address from,
        address to,
        uint256 amount
    )
        internal
    {
        if (
            amount == 0
            || from == to
        ) {
            return;
        }

        GeneralERC20(token).transferFrom(from, to, amount);

        require(
            checkSuccess(),
            "TokenInteract#transferFrom: TransferFrom failed"
        );
    }

    // ============ Private Helper-Functions ============

    /**
     * Checks the return value of the previous function up to 32 bytes. Returns true if the previous
     * function returned 0 bytes or 32 bytes that are not all-zero.
     */
    function checkSuccess(
    )
        private
        pure
        returns (bool)
    {
        uint256 returnValue = 0;

        /* solium-disable-next-line security/no-inline-assembly */
        assembly {
            // check number of bytes returned from last function call
            switch returndatasize

            // no bytes returned: assume success
            case 0x0 {
                returnValue := 1
            }

            // 32 bytes returned: check if non-zero
            case 0x20 {
                // copy 32 bytes into scratch space
                returndatacopy(0x0, 0x0, 0x20)

                // load those bytes into returnValue
                returnValue := mload(0x0)
            }

            // not sure what was returned: dont mark as success
            default { }
        }

        return returnValue != 0;
    }
}

// File: contracts/margin/interfaces/ExchangeReader.sol

/**
 * @title ExchangeReader
 * @author dYdX
 *
 * Contract interface that wraps an exchange and provides information about the current state of the
 * exchange or particular orders
 */
interface ExchangeReader {

    // ============ Public Functions ============

    /**
     * Get the maxmimum amount of makerToken for some order
     *
     * @param  makerToken           Address of makerToken, the token to receive
     * @param  takerToken           Address of takerToken, the token to pay
     * @param  orderData            Arbitrary bytes data for any information to pass to the exchange
     * @return                      Maximum amount of makerToken
     */
    function getMaxMakerAmount(
        address makerToken,
        address takerToken,
        bytes orderData
    )
        external
        view
        returns (uint256);
}

// File: contracts/margin/interfaces/ExchangeWrapper.sol

/**
 * @title ExchangeWrapper
 * @author dYdX
 *
 * Contract interface that Exchange Wrapper smart contracts must implement in order to interface
 * with other smart contracts through a common interface.
 */
interface ExchangeWrapper {

    // ============ Public Functions ============

    /**
     * Exchange some amount of takerToken for makerToken.
     *
     * @param  tradeOriginator      Address of the initiator of the trade (however, this value
     *                              cannot always be trusted as it is set at the discretion of the
     *                              msg.sender)
     * @param  receiver             Address to set allowance on once the trade has completed
     * @param  makerToken           Address of makerToken, the token to receive
     * @param  takerToken           Address of takerToken, the token to pay
     * @param  requestedFillAmount  Amount of takerToken being paid
     * @param  orderData            Arbitrary bytes data for any information to pass to the exchange
     * @return                      The amount of makerToken received
     */
    function exchange(
        address tradeOriginator,
        address receiver,
        address makerToken,
        address takerToken,
        uint256 requestedFillAmount,
        bytes orderData
    )
        external
        returns (uint256);

    /**
     * Get amount of takerToken required to buy a certain amount of makerToken for a given trade.
     * Should match the takerToken amount used in exchangeForAmount. If the order cannot provide
     * exactly desiredMakerToken, then it must return the price to buy the minimum amount greater
     * than desiredMakerToken
     *
     * @param  makerToken         Address of makerToken, the token to receive
     * @param  takerToken         Address of takerToken, the token to pay
     * @param  desiredMakerToken  Amount of makerToken requested
     * @param  orderData          Arbitrary bytes data for any information to pass to the exchange
     * @return                    Amount of takerToken the needed to complete the transaction
     */
    function getExchangeCost(
        address makerToken,
        address takerToken,
        uint256 desiredMakerToken,
        bytes orderData
    )
        external
        view
        returns (uint256);
}

// File: contracts/margin/external/exchangewrappers/ZeroExV2ExchangeWrapper.sol

/**
 * @title ZeroExV2ExchangeWrapper
 * @author dYdX
 *
 * dYdX ExchangeWrapper to interface with 0x Version 2
 */
contract ZeroExV2ExchangeWrapper is
    LibFillResults,
    LibOrder,
    ExchangeWrapper,
    ExchangeReader
{
    using SafeMath for uint256;
    using TokenInteract for address;

    // ============ State Variables ============

    // msg.senders that will put the correct tradeOriginator in callerData when doing an exchange
    mapping (address => bool) public TRUSTED_MSG_SENDER;

    // address of the ZeroEx V2 Exchange
    address public ZERO_EX_EXCHANGE;

    // address of the ZeroEx V2 ERC20Proxy
    address public ZERO_EX_TOKEN_PROXY;

    // address of the ZRX token
    address public ZRX;

    // ============ Constructor ============

    constructor(
        address zeroExExchange,
        address zeroExProxy,
        address zrxToken,
        address[] trustedMsgSenders
    )
        public
    {
        ZERO_EX_EXCHANGE = zeroExExchange;
        ZERO_EX_TOKEN_PROXY = zeroExProxy;
        ZRX = zrxToken;

        for (uint256 i = 0; i < trustedMsgSenders.length; i++) {
            TRUSTED_MSG_SENDER[trustedMsgSenders[i]] = true;
        }

        // The ZRX token does not decrement allowance if set to MAX_UINT
        // therefore setting it once to the maximum amount is sufficient
        // NOTE: this is *not* standard behavior for an ERC20, so do not rely on it for other tokens
        ZRX.approve(ZERO_EX_TOKEN_PROXY, MathHelpers.maxUint256());
    }

    // ============ Public Functions ============

    function exchange(
        address tradeOriginator,
        address receiver,
        address makerToken,
        address takerToken,
        uint256 requestedFillAmount,
        bytes orderData
    )
        external
        returns (uint256)
    {
        // prepare the exchange
        Order memory order = parseOrder(orderData, makerToken, takerToken);
        bytes memory signature = parseSignature(orderData);

        // transfer ZRX fee from trader if applicable
        transferTakerFee(
            order,
            tradeOriginator,
            requestedFillAmount
        );

        // make sure that the exchange can take the tokens from this contract
        ensureAllowance(
            takerToken,
            ZERO_EX_TOKEN_PROXY,
            requestedFillAmount
        );

        // do the exchange
        IExchange v2Exchange = IExchange(ZERO_EX_EXCHANGE);
        FillResults memory fill = v2Exchange.fillOrKillOrder(order, requestedFillAmount, signature);

        // validate results
        assert(fill.takerAssetFilledAmount == requestedFillAmount);

        // set allowance
        ensureAllowance(makerToken, receiver, fill.makerAssetFilledAmount);

        return fill.makerAssetFilledAmount;
    }

    function getExchangeCost(
        address makerToken,
        address takerToken,
        uint256 desiredMakerToken,
        bytes orderData
    )
        external
        view
        returns (uint256)
    {
        Order memory order = parseOrder(orderData, makerToken, takerToken);

        return MathHelpers.getPartialAmountRoundedUp(
            order.takerAssetAmount,
            order.makerAssetAmount,
            desiredMakerToken
        );
    }

    function getMaxMakerAmount(
        address makerToken,
        address takerToken,
        bytes orderData
    )
        external
        view
        returns (uint256)
    {
        Order memory order = parseOrder(orderData, makerToken, takerToken);
        IExchange v2Exchange = IExchange(ZERO_EX_EXCHANGE);
        OrderInfo memory orderInfo = v2Exchange.getOrderInfo(order);

        if (orderInfo.orderStatus != uint8(OrderStatus.FILLABLE)) {
            return 0;
        }

        uint256 remainingTakerAssetAmount =
            order.takerAssetAmount.sub(orderInfo.orderTakerAssetFilledAmount);

        return MathHelpers.getPartialAmount(
            remainingTakerAssetAmount,
            order.takerAssetAmount,
            order.makerAssetAmount
        );
    }

    // ============ Private Functions ============

    function ensureAllowance(
        address token,
        address spender,
        uint256 requiredAmount
    )
        private
    {
        if (token.allowance(address(this), spender) >= requiredAmount) {
            return;
        }

        token.approve(
            spender,
            MathHelpers.maxUint256()
        );
    }

    function transferTakerFee(
        Order memory order,
        address tradeOriginator,
        uint256 requestedFillAmount
    )
        private
    {
        uint256 takerFee = MathHelpers.getPartialAmount(
            requestedFillAmount,
            order.takerAssetAmount,
            order.takerFee
        );

        if (takerFee == 0) {
            return;
        }

        require(
            TRUSTED_MSG_SENDER[msg.sender],
            "ZeroExV2ExchangeWrapper#transferTakerFee: Only trusted senders can dictate the fee payer"
        );

        ZRX.transferFrom(
            tradeOriginator,
            address(this),
            takerFee
        );
    }

    function parseSignature(
        bytes orderData
    )
        private
        pure
        returns (bytes memory)
    {
        bytes memory signature = new bytes(66);

        /* solium-disable-next-line security/no-inline-assembly */
        assembly {
            mstore(add(signature, 32), mload(add(orderData, 352)))  // first 32 bytes
            mstore(add(signature, 64), mload(add(orderData, 384)))  // next 32 bytes
            mstore(add(signature, 66), mload(add(orderData, 386)))  // last 2 bytes
        }

        return signature;
    }

    function parseOrder(
        bytes orderData,
        address makerToken,
        address takerToken
    )
        private
        pure
        returns (Order memory)
    {
        Order memory order;

        /* solium-disable-next-line security/no-inline-assembly */
        assembly {
            mstore(order,           mload(add(orderData, 32)))  // makerAddress
            mstore(add(order, 32),  mload(add(orderData, 64)))  // takerAddress
            mstore(add(order, 64),  mload(add(orderData, 96)))  // feeRecipientAddress
            mstore(add(order, 96),  mload(add(orderData, 128))) // senderAddress
            mstore(add(order, 128), mload(add(orderData, 160))) // makerAssetAmount
            mstore(add(order, 160), mload(add(orderData, 192))) // takerAssetAmount
            mstore(add(order, 192), mload(add(orderData, 224))) // makerFee
            mstore(add(order, 224), mload(add(orderData, 256))) // takerFee
            mstore(add(order, 256), mload(add(orderData, 288))) // expirationTimeSeconds
            mstore(add(order, 288), mload(add(orderData, 320))) // salt
        }

        order.makerAssetData = tokenAddressToAssetData(makerToken);
        order.takerAssetData = tokenAddressToAssetData(takerToken);

        return order;
    }

    function tokenAddressToAssetData(
        address tokenAddress
    )
        private
        pure
        returns (bytes)
    {
        bytes memory result = new bytes(36);

        // padded version of bytes4(keccak256("ERC20Token(address)"));
        bytes32 selector = 0xf47261b000000000000000000000000000000000000000000000000000000000;

        /* solium-disable-next-line security/no-inline-assembly */
        assembly {
            // Store the selector and address in the asset data
            // The first 32 bytes of an array are the length (already set above)
            mstore(add(result, 32), selector)
            mstore(add(result, 36), tokenAddress)
        }

        return result;
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"makerToken","type":"address"},{"name":"takerToken","type":"address"},{"name":"desiredMakerToken","type":"uint256"},{"name":"orderData","type":"bytes"}],"name":"getExchangeCost","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"makerToken","type":"address"},{"name":"takerToken","type":"address"},{"name":"orderData","type":"bytes"}],"name":"getMaxMakerAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ZERO_EX_EXCHANGE","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tradeOriginator","type":"address"},{"name":"receiver","type":"address"},{"name":"makerToken","type":"address"},{"name":"takerToken","type":"address"},{"name":"requestedFillAmount","type":"uint256"},{"name":"orderData","type":"bytes"}],"name":"exchange","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ZERO_EX_TOKEN_PROXY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ZRX","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"TRUSTED_MSG_SENDER","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"zeroExExchange","type":"address"},{"name":"zeroExProxy","type":"address"},{"name":"zrxToken","type":"address"},{"name":"trustedMsgSenders","type":"address[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]

60806040523480156200001157600080fd5b506040516200185f3803806200185f8339810180604052620000379190810190620002e1565b60018054600160a060020a03808716600160a060020a03199283161790925560028054868416908316179055600380549285169290911691909117905560005b8151811015620000d057600160008084848151811015156200009557fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff191691151591909117905560010162000077565b6002546200011b90600160a060020a0316620000f964010000000062000a146200012682021704565b600354600160a060020a0316919064010000000062000a386200012c82021704565b505050505062000463565b60001990565b6040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a0384169063095ea7b390620001759085908590600401620003d5565b600060405180830381600087803b1580156200019057600080fd5b505af1158015620001a5573d6000803e3d6000fd5b50505050620001c26200020b640100000000026401000000009004565b151562000206576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001fd90620003f4565b60405180910390fd5b505050565b6000803d80156200022557602081146200022f576200023b565b600191506200023b565b60206000803e60005191505b501515919050565b600062000251825162000454565b9392505050565b6000601f820183136200026a57600080fd5b8151620002816200027b8262000433565b6200040c565b91508181835260208401935060208101905083856020840282011115620002a757600080fd5b60005b83811015620002d75781620002c0888262000243565b8452506020928301929190910190600101620002aa565b5050505092915050565b60008060008060808587031215620002f857600080fd5b600062000306878762000243565b9450506020620003198782880162000243565b93505060406200032c8782880162000243565b92505060608501516001604060020a038111156200034957600080fd5b620003578782880162000258565b91505092959194509250565b6200036e8162000454565b82525050565b602681527f546f6b656e496e74657261637423617070726f76653a20417070726f76616c2060208201527f6661696c65640000000000000000000000000000000000000000000000000000604082015260600190565b6200036e8162000460565b60408101620003e5828562000363565b620002516020830184620003ca565b60208082528101620004068162000374565b92915050565b6040518181016001604060020a03811182821017156200042b57600080fd5b604052919050565b60006001604060020a038211156200044a57600080fd5b5060209081020190565b600160a060020a031690565b90565b6113ec80620004736000396000f3006080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633a8fdd7d811461008757806340876f6e146100bd5780635da270fc146100dd5780637d98ebac146100ff578063d1f37d591461011f578063d40fa8bf14610134578063f37a862314610149575b600080fd5b34801561009357600080fd5b506100a76100a2366004610eb8565b610176565b6040516100b491906112fe565b60405180910390f35b3480156100c957600080fd5b506100a76100d8366004610e50565b6101dd565b3480156100e957600080fd5b506100f261032f565b6040516100b49190611211565b34801561010b57600080fd5b506100a761011a366004610dab565b61034b565b34801561012b57600080fd5b506100f26104e9565b34801561014057600080fd5b506100f2610505565b34801561015557600080fd5b50610169610164366004610d85565b610521565b6040516100b4919061127d565b6000610180610b3f565b6101bd84848080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508888610536565b90506101d28160a001518260800151876105d2565b979650505050505050565b60006101e7610b3f565b60006101f1610bf9565b600061023087878080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508a8a610536565b6001546040517fc75e0a8100000000000000000000000000000000000000000000000000000000815291955073ffffffffffffffffffffffffffffffffffffffff169350839063c75e0a819061028a9087906004016112bb565b60606040518083038186803b1580156102a257600080fd5b505afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102da9190810190610f54565b805190925060ff166003146102f25760009450610323565b604082015160a085015161030b9163ffffffff6105f716565b9050610320818560a00151866080015161060e565b94505b50505050949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000610355610b3f565b60606000610361610c19565b61039e87878080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b610536565b93506103d987878080601f01602080910402602001604051908101604052809392919081815260200183838082843750610630945050505050565b92506103e6848d8a61067d565b60025461040b908a9073ffffffffffffffffffffffffffffffffffffffff168a610725565b6001546040517f64a3bc1500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116925082906364a3bc15906104689087908c9088906004016112cc565b608060405180830381600087803b15801561048257600080fd5b505af1158015610496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104ba9190810190610f36565b602081015190915088146104ca57fe5b6104d98a8c8360000151610725565b519b9a5050505050505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60006020819052908152604090205460ff1681565b61053e610b3f565b610546610b3f565b6020850151815260408501516020820152606085015160408201526080850151606082015260a0850151608082015260c085015160a082015260e085015160c082015261010085015160e08201526101208501516101008201526101408501516101208201526105b58461078c565b6101408201526105c48361078c565b610160820152949350505050565b60006105ed6105e7858463ffffffff6107e616565b8461080f565b90505b9392505050565b60008282111561060357fe5b508082035b92915050565b60006105ed83610624868563ffffffff6107e616565b9063ffffffff61084e16565b604080516042808252608082019092526060918291906020820161084080388339505050610160840151602082015261018084015160408201526101829093015160428401525090919050565b6000610692828560a001518660e0015161060e565b90508015156106a05761071f565b3360009081526020819052604090205460ff1615156106f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106eb906112ab565b60405180910390fd5b60035461071f9073ffffffffffffffffffffffffffffffffffffffff1684308463ffffffff61086316565b50505050565b8061074d73ffffffffffffffffffffffffffffffffffffffff8516308563ffffffff61096d16565b1061075757610787565b61078782610763610a14565b73ffffffffffffffffffffffffffffffffffffffff8616919063ffffffff610a3816565b505050565b60408051602480825260608083019093528291600091602082016104808038833950507ff47261b0000000000000000000000000000000000000000000000000000000006020830152506024810194909452509192915050565b60008215156107f757506000610608565b5081810281838281151561080757fe5b041461060857fe5b600081151561081a57fe5b82151561082957506000610608565b6105f0600161084284610624878463ffffffff6105f716565b9063ffffffff610afe16565b6000818381151561085b57fe5b049392505050565b80158061089b57508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b156108a55761071f565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516906323b872dd906108fb9086908690869060040161123a565b600060405180830381600087803b15801561091557600080fd5b505af1158015610929573d6000803e3d6000fd5b50505050610935610b0b565b151561071f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106eb9061128b565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff85169063dd62ed3e906109c4908690869060040161121f565b60206040518083038186803b1580156109dc57600080fd5b505afa1580156109f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105ed9190810190610f72565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063095ea7b390610a8c9085908590600401611262565b600060405180830381600087803b158015610aa657600080fd5b505af1158015610aba573d6000803e3d6000fd5b50505050610ac6610b0b565b1515610787576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106eb9061129b565b8181018281101561060857fe5b6000803d8015610b225760208114610b2b57610b37565b60019150610b37565b60206000803e60005191505b501515919050565b61018060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001606081525090565b604080516060810182526000808252602082018190529181019190915290565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006105f08235611337565b60006105f08251611355565b600080601f83018413610c6c57600080fd5b50813567ffffffffffffffff811115610c8457600080fd5b602083019150836001820283011115610c9c57600080fd5b9250929050565b600060808284031215610cb557600080fd5b610cbf608061130c565b90506000610ccd8484610c4e565b8252506020610cde84848301610c4e565b6020830152506040610cf284828501610c4e565b6040830152506060610d0684828501610c4e565b60608301525092915050565b600060608284031215610d2457600080fd5b610d2e606061130c565b90506000610d3c8484610d79565b8252506020610d4d84848301610c4e565b6020830152506040610d6184828501610c4e565b60408301525092915050565b60006105f08235611355565b60006105f08251611358565b600060208284031215610d9757600080fd5b6000610da38484610c42565b949350505050565b600080600080600080600060c0888a031215610dc657600080fd5b6000610dd28a8a610c42565b9750506020610de38a828b01610c42565b9650506040610df48a828b01610c42565b9550506060610e058a828b01610c42565b9450506080610e168a828b01610d6d565b93505060a088013567ffffffffffffffff811115610e3357600080fd5b610e3f8a828b01610c5a565b925092505092959891949750929550565b60008060008060608587031215610e6657600080fd5b6000610e728787610c42565b9450506020610e8387828801610c42565b935050604085013567ffffffffffffffff811115610ea057600080fd5b610eac87828801610c5a565b95989497509550505050565b600080600080600060808688031215610ed057600080fd5b6000610edc8888610c42565b9550506020610eed88828901610c42565b9450506040610efe88828901610d6d565b935050606086013567ffffffffffffffff811115610f1b57600080fd5b610f2788828901610c5a565b92509250509295509295909350565b600060808284031215610f4857600080fd5b6000610da38484610ca3565b600060608284031215610f6657600080fd5b6000610da38484610d12565b600060208284031215610f8457600080fd5b6000610da38484610c4e565b610f9981611337565b82525050565b610f9981611350565b6000610fb382611333565b808452610fc781602086016020860161135e565b610fd08161138a565b9093016020019392505050565b602f81527f546f6b656e496e746572616374237472616e7366657246726f6d3a205472616e60208201527f7366657246726f6d206661696c65640000000000000000000000000000000000604082015260600190565b602681527f546f6b656e496e74657261637423617070726f76653a20417070726f76616c2060208201527f6661696c65640000000000000000000000000000000000000000000000000000604082015260600190565b605881527f5a65726f4578563245786368616e676557726170706572237472616e7366657260208201527f54616b65724665653a204f6e6c7920747275737465642073656e64657273206360408201527f616e206469637461746520746865206665652070617965720000000000000000606082015260800190565b805160009061018084019061111a8582610f90565b50602083015161112d6020860182610f90565b5060408301516111406040860182610f90565b5060608301516111536060860182610f90565b5060808301516111666080860182611208565b5060a083015161117960a0860182611208565b5060c083015161118c60c0860182611208565b5060e083015161119f60e0860182611208565b506101008301516111b4610100860182611208565b506101208301516111c9610120860182611208565b506101408301518482036101408601526111e38282610fa8565b9150506101608301518482036101608601526111ff8282610fa8565b95945050505050565b610f9981611355565b602081016106088284610f90565b6040810161122d8285610f90565b6105f06020830184610f90565b606081016112488286610f90565b6112556020830185610f90565b610da36040830184611208565b604081016112708285610f90565b6105f06020830184611208565b602081016106088284610f9f565b6020808252810161060881610fdd565b6020808252810161060881611033565b6020808252810161060881611089565b602080825281016105f08184611105565b606080825281016112dd8186611105565b90506112ec6020830185611208565b81810360408301526111ff8184610fa8565b602081016106088284611208565b60405181810167ffffffffffffffff8111828210171561132b57600080fd5b604052919050565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b60ff1690565b60005b83811015611379578181015183820152602001611361565b8381111561071f5750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820e1ee8fa45b2f074f24a7263a7347b75d19fbaa5d37cdf73a82e8b3cd5c13e5436c6578706572696d656e74616cf500370000000000000000000000004f833a24e1f95d70f028921e27040ca56e09ab0b0000000000000000000000002240dab907db71e64d3e0dba4800c83b5c502d4e000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000036bf21c8e661b21e6166e4385f574941fdc6caff

Deployed Bytecode

0x6080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633a8fdd7d811461008757806340876f6e146100bd5780635da270fc146100dd5780637d98ebac146100ff578063d1f37d591461011f578063d40fa8bf14610134578063f37a862314610149575b600080fd5b34801561009357600080fd5b506100a76100a2366004610eb8565b610176565b6040516100b491906112fe565b60405180910390f35b3480156100c957600080fd5b506100a76100d8366004610e50565b6101dd565b3480156100e957600080fd5b506100f261032f565b6040516100b49190611211565b34801561010b57600080fd5b506100a761011a366004610dab565b61034b565b34801561012b57600080fd5b506100f26104e9565b34801561014057600080fd5b506100f2610505565b34801561015557600080fd5b50610169610164366004610d85565b610521565b6040516100b4919061127d565b6000610180610b3f565b6101bd84848080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508888610536565b90506101d28160a001518260800151876105d2565b979650505050505050565b60006101e7610b3f565b60006101f1610bf9565b600061023087878080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508a8a610536565b6001546040517fc75e0a8100000000000000000000000000000000000000000000000000000000815291955073ffffffffffffffffffffffffffffffffffffffff169350839063c75e0a819061028a9087906004016112bb565b60606040518083038186803b1580156102a257600080fd5b505afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102da9190810190610f54565b805190925060ff166003146102f25760009450610323565b604082015160a085015161030b9163ffffffff6105f716565b9050610320818560a00151866080015161060e565b94505b50505050949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000610355610b3f565b60606000610361610c19565b61039e87878080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b610536565b93506103d987878080601f01602080910402602001604051908101604052809392919081815260200183838082843750610630945050505050565b92506103e6848d8a61067d565b60025461040b908a9073ffffffffffffffffffffffffffffffffffffffff168a610725565b6001546040517f64a3bc1500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116925082906364a3bc15906104689087908c9088906004016112cc565b608060405180830381600087803b15801561048257600080fd5b505af1158015610496573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104ba9190810190610f36565b602081015190915088146104ca57fe5b6104d98a8c8360000151610725565b519b9a5050505050505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60006020819052908152604090205460ff1681565b61053e610b3f565b610546610b3f565b6020850151815260408501516020820152606085015160408201526080850151606082015260a0850151608082015260c085015160a082015260e085015160c082015261010085015160e08201526101208501516101008201526101408501516101208201526105b58461078c565b6101408201526105c48361078c565b610160820152949350505050565b60006105ed6105e7858463ffffffff6107e616565b8461080f565b90505b9392505050565b60008282111561060357fe5b508082035b92915050565b60006105ed83610624868563ffffffff6107e616565b9063ffffffff61084e16565b604080516042808252608082019092526060918291906020820161084080388339505050610160840151602082015261018084015160408201526101829093015160428401525090919050565b6000610692828560a001518660e0015161060e565b90508015156106a05761071f565b3360009081526020819052604090205460ff1615156106f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106eb906112ab565b60405180910390fd5b60035461071f9073ffffffffffffffffffffffffffffffffffffffff1684308463ffffffff61086316565b50505050565b8061074d73ffffffffffffffffffffffffffffffffffffffff8516308563ffffffff61096d16565b1061075757610787565b61078782610763610a14565b73ffffffffffffffffffffffffffffffffffffffff8616919063ffffffff610a3816565b505050565b60408051602480825260608083019093528291600091602082016104808038833950507ff47261b0000000000000000000000000000000000000000000000000000000006020830152506024810194909452509192915050565b60008215156107f757506000610608565b5081810281838281151561080757fe5b041461060857fe5b600081151561081a57fe5b82151561082957506000610608565b6105f0600161084284610624878463ffffffff6105f716565b9063ffffffff610afe16565b6000818381151561085b57fe5b049392505050565b80158061089b57508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b156108a55761071f565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516906323b872dd906108fb9086908690869060040161123a565b600060405180830381600087803b15801561091557600080fd5b505af1158015610929573d6000803e3d6000fd5b50505050610935610b0b565b151561071f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106eb9061128b565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff85169063dd62ed3e906109c4908690869060040161121f565b60206040518083038186803b1580156109dc57600080fd5b505afa1580156109f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105ed9190810190610f72565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84169063095ea7b390610a8c9085908590600401611262565b600060405180830381600087803b158015610aa657600080fd5b505af1158015610aba573d6000803e3d6000fd5b50505050610ac6610b0b565b1515610787576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106eb9061129b565b8181018281101561060857fe5b6000803d8015610b225760208114610b2b57610b37565b60019150610b37565b60206000803e60005191505b501515919050565b61018060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160608152602001606081525090565b604080516060810182526000808252602082018190529181019190915290565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006105f08235611337565b60006105f08251611355565b600080601f83018413610c6c57600080fd5b50813567ffffffffffffffff811115610c8457600080fd5b602083019150836001820283011115610c9c57600080fd5b9250929050565b600060808284031215610cb557600080fd5b610cbf608061130c565b90506000610ccd8484610c4e565b8252506020610cde84848301610c4e565b6020830152506040610cf284828501610c4e565b6040830152506060610d0684828501610c4e565b60608301525092915050565b600060608284031215610d2457600080fd5b610d2e606061130c565b90506000610d3c8484610d79565b8252506020610d4d84848301610c4e565b6020830152506040610d6184828501610c4e565b60408301525092915050565b60006105f08235611355565b60006105f08251611358565b600060208284031215610d9757600080fd5b6000610da38484610c42565b949350505050565b600080600080600080600060c0888a031215610dc657600080fd5b6000610dd28a8a610c42565b9750506020610de38a828b01610c42565b9650506040610df48a828b01610c42565b9550506060610e058a828b01610c42565b9450506080610e168a828b01610d6d565b93505060a088013567ffffffffffffffff811115610e3357600080fd5b610e3f8a828b01610c5a565b925092505092959891949750929550565b60008060008060608587031215610e6657600080fd5b6000610e728787610c42565b9450506020610e8387828801610c42565b935050604085013567ffffffffffffffff811115610ea057600080fd5b610eac87828801610c5a565b95989497509550505050565b600080600080600060808688031215610ed057600080fd5b6000610edc8888610c42565b9550506020610eed88828901610c42565b9450506040610efe88828901610d6d565b935050606086013567ffffffffffffffff811115610f1b57600080fd5b610f2788828901610c5a565b92509250509295509295909350565b600060808284031215610f4857600080fd5b6000610da38484610ca3565b600060608284031215610f6657600080fd5b6000610da38484610d12565b600060208284031215610f8457600080fd5b6000610da38484610c4e565b610f9981611337565b82525050565b610f9981611350565b6000610fb382611333565b808452610fc781602086016020860161135e565b610fd08161138a565b9093016020019392505050565b602f81527f546f6b656e496e746572616374237472616e7366657246726f6d3a205472616e60208201527f7366657246726f6d206661696c65640000000000000000000000000000000000604082015260600190565b602681527f546f6b656e496e74657261637423617070726f76653a20417070726f76616c2060208201527f6661696c65640000000000000000000000000000000000000000000000000000604082015260600190565b605881527f5a65726f4578563245786368616e676557726170706572237472616e7366657260208201527f54616b65724665653a204f6e6c7920747275737465642073656e64657273206360408201527f616e206469637461746520746865206665652070617965720000000000000000606082015260800190565b805160009061018084019061111a8582610f90565b50602083015161112d6020860182610f90565b5060408301516111406040860182610f90565b5060608301516111536060860182610f90565b5060808301516111666080860182611208565b5060a083015161117960a0860182611208565b5060c083015161118c60c0860182611208565b5060e083015161119f60e0860182611208565b506101008301516111b4610100860182611208565b506101208301516111c9610120860182611208565b506101408301518482036101408601526111e38282610fa8565b9150506101608301518482036101608601526111ff8282610fa8565b95945050505050565b610f9981611355565b602081016106088284610f90565b6040810161122d8285610f90565b6105f06020830184610f90565b606081016112488286610f90565b6112556020830185610f90565b610da36040830184611208565b604081016112708285610f90565b6105f06020830184611208565b602081016106088284610f9f565b6020808252810161060881610fdd565b6020808252810161060881611033565b6020808252810161060881611089565b602080825281016105f08184611105565b606080825281016112dd8186611105565b90506112ec6020830185611208565b81810360408301526111ff8184610fa8565b602081016106088284611208565b60405181810167ffffffffffffffff8111828210171561132b57600080fd5b604052919050565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b60ff1690565b60005b83811015611379578181015183820152602001611361565b8381111561071f5750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820e1ee8fa45b2f074f24a7263a7347b75d19fbaa5d37cdf73a82e8b3cd5c13e5436c6578706572696d656e74616cf50037

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000004f833a24e1f95d70f028921e27040ca56e09ab0b0000000000000000000000002240dab907db71e64d3e0dba4800c83b5c502d4e000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000036bf21c8e661b21e6166e4385f574941fdc6caff

-----Decoded View---------------
Arg [0] : zeroExExchange (address): 0x4F833a24e1f95D70F028921e27040Ca56E09AB0b
Arg [1] : zeroExProxy (address): 0x2240Dab907db71e64d3E0dbA4800c83B5C502d4E
Arg [2] : zrxToken (address): 0xE41d2489571d322189246DaFA5ebDe1F4699F498
Arg [3] : trustedMsgSenders (address[]): 0x36Bf21C8E661B21E6166E4385F574941fdC6Caff

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000004f833a24e1f95d70f028921e27040ca56e09ab0b
Arg [1] : 0000000000000000000000002240dab907db71e64d3e0dba4800c83b5c502d4e
Arg [2] : 000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 00000000000000000000000036bf21c8e661b21e6166e4385f574941fdc6caff


Swarm Source

bzzr://e1ee8fa45b2f074f24a7263a7347b75d19fbaa5d37cdf73a82e8b3cd5c13e543

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.