Contract 0xcadd178eb978b07b19c8c7f04a54fa337d9c4d8c

 

TxHash Block Age From To Value [TxFee]
0x8873217da51bf85ab7ce65022e443d7a386f32b3497f78c487413020efaad3e573731727 days 2 hrs ago0xa4c7c9d95cfcb3bbfca0c0af3302406a520d002e IN  0xcadd178eb978b07b19c8c7f04a54fa337d9c4d8c0 Ether0.000091234
0x9f1f1cf6281388aba5c1589f92c073bc93cf59b3758a71e4100d9b769693ac99722409234 days 21 hrs ago0xa4c7c9d95cfcb3bbfca0c0af3302406a520d002e IN  0xcadd178eb978b07b19c8c7f04a54fa337d9c4d8c0 Ether0.000364936
0x380582eed4d671540866da11fbb747cd579a21617e30d56f171dd6bbad39bc8e722387534 days 22 hrs ago0xa4c7c9d95cfcb3bbfca0c0af3302406a520d002e IN  Contract Creation0 Ether0.008602321
[ Download CSV Export 

Internal Transactions as a result of Contract Execution

Parent TxHash Block Age From To Value

Contract Source Code Verified (Exact Match)

Contract Name:
TokenTransferProxy

Compiler Version
v0.5.1+commit.c8a2cb62

Optimization Enabled:
Yes

Runs (Optimizer):
200

Contract Source Code

pragma solidity 0.5.1;

/**
 * @dev Standard interface for a dex proxy contract.
 */
interface Proxy {

  /**
   * @dev Executes an action.
   * @param _target Target of execution.
   * @param _a Address usually represention from.
   * @param _b Address usually representing to.
   * @param _c Integer usually repersenting amount/value/id.
   */
  function execute(
    address _target,
    address _a,
    address _b,
    uint256 _c
  )
    external;
    
}

/**
 * @title A standard interface for tokens.
 * @dev This interface uses the official ERC-20 specification from
 * https://eips.ethereum.org/EIPS/eip-20 with the additional requirement that
 * the functions specificed as optional have become required.
 */
interface ERC20
{

  /**
   * @dev Returns the name of the token.
   * @return Token name.
   */
  function name()
    external
    view
    returns (string memory _name);

  /**
   * @dev Returns the symbol of the token.
   * @return Token symbol.
   */
  function symbol()
    external
    view
    returns (string memory _symbol);

  /**
   * @dev Returns the number of decimals the token uses.
   * @return Number of decimals.
   */
  function decimals()
    external
    view
    returns (uint8 _decimals);

  /**
   * @dev Returns the total token supply.
   * @return Total supply.
   */
  function totalSupply()
    external
    view
    returns (uint256 _totalSupply);

  /**
   * @dev Returns the account balance of another account with address _owner.
   * @param _owner The address from which the balance will be retrieved.
   * @return Balance of _owner.
   */
  function balanceOf(
    address _owner
  )
    external
    view
    returns (uint256 _balance);

  /**
   * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The
   * function SHOULD throw if the message caller's account balance does not have enough tokens to
   * spend.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   * @return Success of operation.
   */
  function transfer(
    address _to,
    uint256 _value
  )
    external
    returns (bool _success);

  /**
   * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the
   * Transfer event.
   * @param _from The address of the sender.
   * @param _to The address of the recipient.
   * @param _value The amount of token to be transferred.
   * @return Success of operation.
   */
  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  )
    external
    returns (bool _success);

  /**
   * @dev Allows _spender to withdraw from your account multiple times, up to
   * the _value amount. If this function is called again it overwrites the current
   * allowance with _value.
   * @param _spender The address of the account able to transfer the tokens.
   * @param _value The amount of tokens to be approved for transfer.
   * @return Success of operation.
   */
  function approve(
    address _spender,
    uint256 _value
  )
    external
    returns (bool _success);

  /**
   * @dev Returns the amount which _spender is still allowed to withdraw from _owner.
   * @param _owner The address of the account owning tokens.
   * @param _spender The address of the account able to transfer the tokens.
   * @return Remaining allowance.
   */
  function allowance(
    address _owner,
    address _spender
  )
    external
    view
    returns (uint256 _remaining);

  /**
   * @dev Triggers when tokens are transferred, including zero value transfers.
   */
  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 _value
  );

  /**
   * @dev Triggers on any successful call to approve(address _spender, uint256 _value).
   */
  event Approval(
    address indexed _owner,
    address indexed _spender,
    uint256 _value
  );

}

/**
 * @dev Math operations with safety checks that throw on error. This contract is based on the 
 * source code at: 
 * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol.
 */
library SafeMath
{

  /**
   * @dev Error constants.
   */
  string constant OVERFLOW = "008001";
  string constant SUBTRAHEND_GREATER_THEN_MINUEND = "008002";
  string constant DIVISION_BY_ZERO = "008003";

  /**
   * @dev Multiplies two numbers, reverts on overflow.
   * @param _factor1 Factor number.
   * @param _factor2 Factor number.
   * @return The product of the two factors.
   */
  function mul(
    uint256 _factor1,
    uint256 _factor2
  )
    internal
    pure
    returns (uint256 product)
  {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (_factor1 == 0)
    {
      return 0;
    }

    product = _factor1 * _factor2;
    require(product / _factor1 == _factor2, OVERFLOW);
  }

  /**
   * @dev Integer division of two numbers, truncating the quotient, reverts on division by zero.
   * @param _dividend Dividend number.
   * @param _divisor Divisor number.
   * @return The quotient.
   */
  function div(
    uint256 _dividend,
    uint256 _divisor
  )
    internal
    pure
    returns (uint256 quotient)
  {
    // Solidity automatically asserts when dividing by 0, using all gas.
    require(_divisor > 0, DIVISION_BY_ZERO);
    quotient = _dividend / _divisor;
    // assert(_dividend == _divisor * quotient + _dividend % _divisor); // There is no case in which this doesn't hold.
  }

  /**
   * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
   * @param _minuend Minuend number.
   * @param _subtrahend Subtrahend number.
   * @return Difference.
   */
  function sub(
    uint256 _minuend,
    uint256 _subtrahend
  )
    internal
    pure
    returns (uint256 difference)
  {
    require(_subtrahend <= _minuend, SUBTRAHEND_GREATER_THEN_MINUEND);
    difference = _minuend - _subtrahend;
  }

  /**
   * @dev Adds two numbers, reverts on overflow.
   * @param _addend1 Number.
   * @param _addend2 Number.
   * @return Sum.
   */
  function add(
    uint256 _addend1,
    uint256 _addend2
  )
    internal
    pure
    returns (uint256 sum)
  {
    sum = _addend1 + _addend2;
    require(sum >= _addend1, OVERFLOW);
  }

  /**
    * @dev Divides two numbers and returns the remainder (unsigned integer modulo), reverts when
    * dividing by zero.
    * @param _dividend Number.
    * @param _divisor Number.
    * @return Remainder.
    */
  function mod(
    uint256 _dividend,
    uint256 _divisor
  )
    internal
    pure
    returns (uint256 remainder) 
  {
    require(_divisor != 0, DIVISION_BY_ZERO);
    remainder = _dividend % _divisor;
  }

}

/**
 * @title Contract for setting abilities.
 * @dev For optimization purposes the abilities are represented as a bitfield. Maximum number of
 * abilities is therefore 256. This is an example(for simplicity is made for max 8 abilities) of how
 * this works. 
 * 00000001 Ability A - number representation 1
 * 00000010 Ability B - number representation 2
 * 00000100 Ability C - number representation 4
 * 00001000 Ability D - number representation 8
 * 00010000 Ability E - number representation 16
 * etc ... 
 * To grant abilities B and C, we would need a bitfield of 00000110 which is represented by number
 * 6, in other words, the sum of abilities B and C. The same concept works for revoking abilities
 * and checking if someone has multiple abilities.
 */
contract Abilitable
{
  using SafeMath for uint;

  /**
   * @dev Error constants.
   */
  string constant NOT_AUTHORIZED = "017001";
  string constant ONE_ZERO_ABILITY_HAS_TO_EXIST = "017002";
  string constant INVALID_INPUT = "017003";

  /**
   * @dev Ability 1 is a reserved ability. It is an ability to grant or revoke abilities. 
   * There can be minimum of 1 address with ability 1.
   * Other abilities are determined by implementing contract.
   */
  uint8 constant ABILITY_TO_MANAGE_ABILITIES = 1;

  /**
   * @dev Maps address to ability ids.
   */
  mapping(address => uint256) public addressToAbility;

  /**
   * @dev Count of zero ability addresses.
   */
  uint256 private zeroAbilityCount;

  /**
   * @dev Emits when an address is granted an ability.
   * @param _target Address to which we are granting abilities.
   * @param _abilities Number representing bitfield of abilities we are granting.
   */
  event GrantAbilities(
    address indexed _target,
    uint256 indexed _abilities
  );

  /**
   * @dev Emits when an address gets an ability revoked.
   * @param _target Address of which we are revoking an ability.
   * @param _abilities Number representing bitfield of abilities we are revoking.
   */
  event RevokeAbilities(
    address indexed _target,
    uint256 indexed _abilities
  );

  /**
   * @dev Guarantees that msg.sender has certain abilities.
   */
  modifier hasAbilities(
    uint256 _abilities
  ) 
  {
    require(_abilities > 0, INVALID_INPUT);
    require(
      (addressToAbility[msg.sender] & _abilities) == _abilities,
      NOT_AUTHORIZED
    );
    _;
  }

  /**
   * @dev Contract constructor.
   * Sets ABILITY_TO_MANAGE_ABILITIES ability to the sender account.
   */
  constructor()
    public
  {
    addressToAbility[msg.sender] = ABILITY_TO_MANAGE_ABILITIES;
    zeroAbilityCount = 1;
    emit GrantAbilities(msg.sender, ABILITY_TO_MANAGE_ABILITIES);
  }

  /**
   * @dev Grants specific abilities to specified address.
   * @param _target Address to grant abilities to.
   * @param _abilities Number representing bitfield of abilities we are granting.
   */
  function grantAbilities(
    address _target,
    uint256 _abilities
  )
    external
    hasAbilities(ABILITY_TO_MANAGE_ABILITIES)
  {
    addressToAbility[_target] |= _abilities;

    if((_abilities & ABILITY_TO_MANAGE_ABILITIES) == ABILITY_TO_MANAGE_ABILITIES)
    {
      zeroAbilityCount = zeroAbilityCount.add(1);
    }
    emit GrantAbilities(_target, _abilities);
  }

  /**
   * @dev Unassigns specific abilities from specified address.
   * @param _target Address of which we revoke abilites.
   * @param _abilities Number representing bitfield of abilities we are revoking.
   */
  function revokeAbilities(
    address _target,
    uint256 _abilities
  )
    external
    hasAbilities(ABILITY_TO_MANAGE_ABILITIES)
  {
    addressToAbility[_target] &= ~_abilities;
    if((_abilities & 1) == 1)
    {
      require(zeroAbilityCount > 1, ONE_ZERO_ABILITY_HAS_TO_EXIST);
      zeroAbilityCount--;
    }
    emit RevokeAbilities(_target, _abilities);
  }

  /**
   * @dev Check if an address has a specific ability. Throws if checking for 0.
   * @param _target Address for which we want to check if it has a specific abilities.
   * @param _abilities Number representing bitfield of abilities we are checking.
   */
  function isAble(
    address _target,
    uint256 _abilities
  )
    external
    view
    returns (bool)
  {
    require(_abilities > 0, INVALID_INPUT);
    return (addressToAbility[_target] & _abilities) == _abilities;
  }
  
}

/**
 * @title TokenTransferProxy - Transfers tokens on behalf of contracts that have been approved via
 * decentralized governance.
 * @dev Based on:https://github.com/0xProject/contracts/blob/master/contracts/TokenTransferProxy.sol
 */
contract TokenTransferProxy is 
  Proxy,
  Abilitable 
{

  /**
   * @dev List of abilities:
   * 2 - Ability to execute transfer. 
   */
  uint8 constant ABILITY_TO_EXECUTE = 2;

  /**
   * @dev Error constants.
   */
  string constant TRANSFER_FAILED = "012001";

  /**
   * @dev Calls into ERC20 Token contract, invoking transferFrom.
   * @param _target Address of token to transfer.
   * @param _a Address to transfer token from.
   * @param _b Address to transfer token to.
   * @param _c Amount of token to transfer.
   */
  function execute(
    address _target,
    address _a,
    address _b,
    uint256 _c
  )
    public
    hasAbilities(ABILITY_TO_EXECUTE)
  {
    require(
      ERC20(_target).transferFrom(_a, _b, _c),
      TRANSFER_FAILED
    );
  }
  
}

Contract ABI

[{"constant":false,"inputs":[{"name":"_target","type":"address"},{"name":"_abilities","type":"uint256"}],"name":"grantAbilities","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_target","type":"address"},{"name":"_a","type":"address"},{"name":"_b","type":"address"},{"name":"_c","type":"uint256"}],"name":"execute","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"addressToAbility","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_target","type":"address"},{"name":"_abilities","type":"uint256"}],"name":"isAble","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_target","type":"address"},{"name":"_abilities","type":"uint256"}],"name":"revokeAbilities","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_target","type":"address"},{"indexed":true,"name":"_abilities","type":"uint256"}],"name":"GrantAbilities","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_target","type":"address"},{"indexed":true,"name":"_abilities","type":"uint256"}],"name":"RevokeAbilities","type":"event"}]

Contract Creation Code

6080604081815233600081815260208190529182206001908190558080559290917fc4adfc5f00262a1ab9b2241c7e98408a91e58dc5777d786164bba34a7652f62f91a3610875806100526000396000f3fe608060405260043610610066577c010000000000000000000000000000000000000000000000000000000060003504630ab319e8811461006b578063239aee06146100a657806345a32c86146100ef578063ba00a33014610134578063f394b6df14610181575b600080fd5b34801561007757600080fd5b506100a46004803603604081101561008e57600080fd5b50600160a060020a0381351690602001356101ba565b005b3480156100b257600080fd5b506100a4600480360360808110156100c957600080fd5b50600160a060020a0381358116916020810135821691604082013516906060013561034d565b3480156100fb57600080fd5b506101226004803603602081101561011257600080fd5b5035600160a060020a0316610536565b60408051918252519081900360200190f35b34801561014057600080fd5b5061016d6004803603604081101561015757600080fd5b50600160a060020a038135169060200135610548565b604080519115158252519081900360200190f35b34801561018d57600080fd5b506100a4600480360360408110156101a457600080fd5b50600160a060020a0381351690602001356105e2565b604080518082019091526006815260008051602061082a8339815191526020820152600190610237565b838110156101fc5781810151838201526020016101e4565b50505050905090810190601f1680156102295780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b503360009081526020818152604091829020548251808401909352600683527f303137303031000000000000000000000000000000000000000000000000000091830191909152821682146102d15760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156101fc5781810151838201526020016101e4565b50600160a060020a038316600090815260208190526040902080548317905560018083161415610312576001805461030e9163ffffffff61079716565b6001555b6040518290600160a060020a038516907fc4adfc5f00262a1ab9b2241c7e98408a91e58dc5777d786164bba34a7652f62f90600090a3505050565b604080518082018252600680825260008051602061082a8339815191526020928301523360009081528083528390205483518085019094529083527f30313730303100000000000000000000000000000000000000000000000000009183019190915260029190821682146104075760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156101fc5781810151838201526020016101e4565b50604080517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301528581166024830152604482018590529151918716916323b872dd916064808201926020929091908290030181600087803b15801561047c57600080fd5b505af1158015610490573d6000803e3d6000fd5b505050506040513d60208110156104a657600080fd5b505160408051808201909152600681527f3031323030310000000000000000000000000000000000000000000000000000602082015290151561052e5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156101fc5781810151838201526020016101e4565b505050505050565b60006020819052908152604090205481565b604080518082019091526006815260008051602061082a83398151915260208201526000908183116105bf5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156101fc5781810151838201526020016101e4565b5050600160a060020a039190911660009081526020819052604090205481161490565b604080518082018252600680825260008051602061082a8339815191526020928301523360009081528083528390205483518085019094529083527f303137303031000000000000000000000000000000000000000000000000000091830191909152600191908216821461069c5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156101fc5781810151838201526020016101e4565b50600160a060020a0383166000908152602081905260409020805483191690556001808316141561075c576001805460408051808201909152600681527f3031373030320000000000000000000000000000000000000000000000000000602082015291106107505760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156101fc5781810151838201526020016101e4565b50600180546000190190555b6040518290600160a060020a038516907fbb71944f65b9a48cc7d835179fb5e874f29b60aa0195785fb54968d8dddef08a90600090a3505050565b60408051808201909152600681527f3030383030310000000000000000000000000000000000000000000000000000602082015282820190838210156108225760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156101fc5781810151838201526020016101e4565b509291505056fe3031373030330000000000000000000000000000000000000000000000000000a165627a7a7230582059290f6aedf2c4fec74e51a835d9c8e41d6c5eb797cdae73d775cf53e44e1afa0029

Swarm Source

bzzr://59290f6aedf2c4fec74e51a835d9c8e41d6c5eb797cdae73d775cf53e44e1afa
Block Age Transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.