Skip to content

Latest commit

 

History

History
107 lines (80 loc) · 4.86 KB

erc20-proxy.md

File metadata and controls

107 lines (80 loc) · 4.86 KB

ERC20Proxy

Transferring ERC-20 tokens

The ERC20Proxy is responsible for transferring ERC-20 tokens. Users must first approve this contract by calling the approve method on the token that will be exchanged. It is recommended that users approve a value of 2^256 -1. This minimizes the amount of times approve must be called, and also increases efficiency for many ERC-20 tokens.

transferFrom

This contract may transfer an ERC-20 token if its transferFrom method is called from an authorized address.

/// @dev Transfers assets. Either succeeds or throws.
/// @param assetData Byte array encoded for the respective asset proxy.
/// @param from Address to transfer asset from.
/// @param to Address to transfer asset to.
/// @param amount Amount of asset to transfer.
function transferFrom(
    bytes assetData,
    address from,
    address to,
    uint256 amount
)
    external;

Logic

Calling ERC20Proxy.transferFrom will perform the following steps:

  1. Decode erc20TokenAddress from assetData
  2. Call ERC20Token(erc20TokenAddress).transferFrom(from, to, amount)
  3. Revert if the call was unsuccessful
  4. Revert if the call was successful but returned 0

Note that this implementation will correctly handle edge cases where the ERC-20 token contract does not return a value or does not throw upon failure.

Errors

The transferFrom method may revert with the following errors:

Error Condition
StandardError("SENDER_NOT_AUTHORIZED") msg.sender has not been authorized
StandardError("TRANSFER_FAILED") The ERC20Token.transferFrom call failed for any reason (likely insufficient balance/allowance)

Encoding assetData

This contract expects ERC-20 assetData to be encoded using ABIv2 with the following function signature. The id of this contract is 0xf47261b0, which can be calculated as the 4 byte function selector of the same signature.

/// @dev Function signature for encoding ERC-20 assetData.
/// @param tokenAddress Address of ERC20Token contract.
function ERC20Token(address tokenAddress)
    external;

In Solidity, this data can be encoded with:

bytes memory data = abi.encodeWithSelector(
    0xf47261b0,
    erc20TokenAddress
);

NOTE: The ERC20Proxy does not enforce strict length checks for assetData, which means that extra data may be appended to this field with any arbitrary encoding. Any extra data will be ignored by the ERC20Proxy but may be used in external contracts interacting with the Exchange contract. Relayers that do not desire this behavior should validate the length of all assetData fields contained in orders before acceptance.

Authorizations

The ERC20Proxy has the following interface for managing which addresses are allowed to call this contract's transferFrom method. These authorization functions can only be called by the contract's owner (currently, the ZeroExGovernor contract).

contract IAuthorizable {

    /// @dev Gets all authorized addresses.
    /// @return Array of authorized addresses.
    function getAuthorizedAddresses()
        external
        view
        returns (address[]);

    /// @dev Authorizes an address.
    /// @param target Address to authorize.
    function addAuthorizedAddress(address target)
        external;

    /// @dev Removes authorizion of an address.
    /// @param target Address to remove authorization from.
    function removeAuthorizedAddress(address target)
        external;

    /// @dev Removes authorizion of an address.
    /// @param target Address to remove authorization from.
    /// @param index Index of target in authorities array.
    function removeAuthorizedAddressAtIndex(
        address target,
        uint256 index
    )
        external;
}

The contracts that are currently authorized to call the ERC20Proxy contract's transferFrom method are: