Contract 0x3038045cd883abff0c6eea4b1954843c0fa5a735

 

TxHash Block Age From To Value [TxFee]
0x0248f81a89cb2a69555fb0592c049878fc93878113b2aeef1bc0ffe1d0be1e39724196819 hrs 39 mins ago0xea23ac45b17ff55d45f841aee07c006a62085d7d IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.0023 Ether0.001500629
0xe42a5469693aee44bab198a98a6bd979d9edee3de3bdcf4b664072066c118d7672365922 days 1 hr ago0x5c1e57829b2c6e990b39c070042962888726a462 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.013847962924534 Ether0.00488422
0x90cce59a1d74f29d8d354fa58d8816d79d8712be909d639c08e1581a626929e872250194 days 20 hrs ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.04102098 Ether0.000458886
0xc2e52356d4390f91975721e93509b3db628a021f6c51cfc91254a3fd0d8f149c72117398 days 35 mins ago0x1197b3c48722026b68d5a2e27811073d9fb928db IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.001001 Ether0.0005277189
0x78f9c6758e8f4f53ebc01a3cac10652ee539762593b1309823c89cea09a9d53a72087998 days 17 hrs ago0xd714dd60e22bbb1cbafd0e40de5cfa7bbdd3f3c8 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.001001 Ether0.0002523873
0xb47f350c7e9f4aae65a8fcb31a7dbbec59cdcdadb89bce62177e6595e468500b72076868 days 23 hrs ago0xd714dd60e22bbb1cbafd0e40de5cfa7bbdd3f3c8 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.001001 Ether0.0002982759
0xffc429dca27d0d3385db4c6e4596979d4aaea0624f7eca2d4add16837868c325720316210 days 1 hr ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.0005005 Ether0.0002523873
0x4069954549e6af1b8f23ba5d78ee5f7a03fbc9cd57ace412037e532400f600b0720314210 days 1 hr ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.0002002 Ether0.000275178
0x94bd502d4dadf3b1de5e054b1b6c6a7a66dd3802ef39c859d8163e95ba3a5163720312410 days 1 hr ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.0001001 Ether0.0002751012
0x1e4ee49b1a5eae8f89451d1a0f155836c6358b0f5918af03dd80bc18173c9536720306610 days 2 hrs ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.004004 Ether0.000321041
0xd6965b2c04a51f18347d6b232e753567953eecabcb961ad19d17153dd21a4222720299610 days 2 hrs ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.0002002 Ether0.0004356985
0x617baad02999883f66668fafd4682f84f82fafbdaea46ccf83b38cb3e10c367b720297810 days 2 hrs ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.0001001 Ether0.0002980263
0xf9106d35202fe9fa8e854c86e11178d8f93bd4115d0a91e2f369dcc06327fcaf720292510 days 2 hrs ago0x8ee9be167874be39fe3b41e09a5166ff283fe21a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.003003 Ether0.0002752548
0xf1324521981f7399a307e59d9ea6af0ac4aec88b9f638a6b08e80274d42530b1719351912 days 2 hrs ago0x0acebc5977b6a984959f73a6b8b3c867e57b10e0 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.00000009176 Ether0.001065288
0xfb705bd5641bd1a1043e9a833c0e39e6ffa8fc5e3f8af6e63b36edee32b7084a718030414 days 18 hrs ago0x6c0f58ad4eb24da5769412bf34ddee698c4d185b IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.009364355 Ether0.00976844
0xb7db6755d9d8e79ce7a80f257f537c17ad7b7ccbc134089906eca82a29dcaec0715652119 days 15 hrs ago0x55d0ce5609f193c142e4bd66d76018ea951209d8 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.009571562 Ether0.000488422
0x94682ceb38bd3b66561e1dd6399289e0253869733e2e859519e51d1e33c80ea3709989230 days 22 hrs ago0x3462943f79dce59770faf5fd087ee0e77545dc33 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.68549481 Ether0.0003909424
0x3695dc4d408d79ce19e06cd2216399d784ad001df545465b41b0afb9633a7c1a707265335 days 19 hrs ago0x5c1e57829b2c6e990b39c070042962888726a462 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.008360477741585 Ether0.0003418954
0x637cbbe260d17497511c70421eb5b8212479a6fdf5ee1bad4f37e8198809c1dc704792640 days 5 hrs ago0x04127edb6c658287cb9c92fb5e2c48d67c0d233a IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.0002050048 Ether0.000683074
0xfb2eb40f136b69e23d291d787b44c7a888e1edca5e9cc229fc0d49a0e8c680fa704393040 days 22 hrs ago0x29768c44fee9727586510cff8b6e45ec1206426d IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.031622176591375 Ether0.0002686321
0xfa19b8922c156c4dffa8409065a2ad3f4a3c2091a56d748ef8a04d7e3a0969b7704390240 days 22 hrs ago0x5c1e57829b2c6e990b39c070042962888726a462 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.039493411189142 Ether0.0002961321
0xf875341b5e9ca4d76f5b299910cbcc22b8cec31249629a0b0cccb0dfce7fdcce704253441 days 4 hrs ago0xce314e4bc7202c60c6bf2602d33b3a583ebf19b1 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.074939865 Ether0.000488678
0x6f16e1ced3fb5b22b645c24252d4e044482e80ff980b48f7ba9a4b45602e081a704053741 days 13 hrs ago0xc5993670a568e66f7f9f7933a84a9d36032a6a50 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.05005 Ether0.000229315
0x4bb0d9731899752bc2836f59693a96b58caf728c07d7a8d012e80bd725f9d930703895641 days 19 hrs ago0x5c1e57829b2c6e990b39c070042962888726a462 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.033205068665826 Ether0.0002686321
0xd3f8b63993e1f77edbd305587ba8b068caac03eedb4708e61e7bd8d98254bdeb702497744 days 7 hrs ago0xc2390220fc9b6d014d86d90d873c3edb8c1c4156 IN  0x3038045cd883abff0c6eea4b1954843c0fa5a7350.006478472 Ether0.001220735
[ Download CSV Export 

Latest 25 Internal Transaction, Click here to view more Internal Transactions as a result of Contract Execution

Parent TxHash Block Age From To Value
0x0248f81a89cb2a69555fb0592c049878fc93878113b2aeef1bc0ffe1d0be1e39724196819 hrs 39 mins ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.0023 Ether
0xe42a5469693aee44bab198a98a6bd979d9edee3de3bdcf4b664072066c118d7672365922 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x5c1e57829b2c6e990b39c070042962888726a4620.013834128795739088 Ether
0xe42a5469693aee44bab198a98a6bd979d9edee3de3bdcf4b664072066c118d7672365922 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.000013834128795739 Ether
0x90cce59a1d74f29d8d354fa58d8816d79d8712be909d639c08e1581a626929e872250194 days 20 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350xb189f76323678e094d4996d182a792e52369c0050.04098 Ether
0x90cce59a1d74f29d8d354fa58d8816d79d8712be909d639c08e1581a626929e872250194 days 20 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.00004098 Ether
0xc2e52356d4390f91975721e93509b3db628a021f6c51cfc91254a3fd0d8f149c72117398 days 35 mins ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350xd714dd60e22bbb1cbafd0e40de5cfa7bbdd3f3c80.001 Ether
0xc2e52356d4390f91975721e93509b3db628a021f6c51cfc91254a3fd0d8f149c72117398 days 35 mins ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.000001 Ether
0x78f9c6758e8f4f53ebc01a3cac10652ee539762593b1309823c89cea09a9d53a72087998 days 17 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x1197b3c48722026b68d5a2e27811073d9fb928db0.001 Ether
0x78f9c6758e8f4f53ebc01a3cac10652ee539762593b1309823c89cea09a9d53a72087998 days 17 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.000001 Ether
0xb47f350c7e9f4aae65a8fcb31a7dbbec59cdcdadb89bce62177e6595e468500b72076868 days 23 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350xea23798d5251f06b16c41e3b5fabe586eef85bee0.001 Ether
0xb47f350c7e9f4aae65a8fcb31a7dbbec59cdcdadb89bce62177e6595e468500b72076868 days 23 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.000001 Ether
0xffc429dca27d0d3385db4c6e4596979d4aaea0624f7eca2d4add16837868c325720316210 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x8ee9be167874be39fe3b41e09a5166ff283fe21a0.0005 Ether
0xffc429dca27d0d3385db4c6e4596979d4aaea0624f7eca2d4add16837868c325720316210 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.0000005 Ether
0x4069954549e6af1b8f23ba5d78ee5f7a03fbc9cd57ace412037e532400f600b0720314210 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x8ee9be167874be39fe3b41e09a5166ff283fe21a0.0002 Ether
0x4069954549e6af1b8f23ba5d78ee5f7a03fbc9cd57ace412037e532400f600b0720314210 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.0000002 Ether
0x94bd502d4dadf3b1de5e054b1b6c6a7a66dd3802ef39c859d8163e95ba3a5163720312410 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x8ee9be167874be39fe3b41e09a5166ff283fe21a0.0001 Ether
0x94bd502d4dadf3b1de5e054b1b6c6a7a66dd3802ef39c859d8163e95ba3a5163720312410 days 1 hr ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.0000001 Ether
0x1e4ee49b1a5eae8f89451d1a0f155836c6358b0f5918af03dd80bc18173c9536720306610 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x8ee9be167874be39fe3b41e09a5166ff283fe21a0.004 Ether
0x1e4ee49b1a5eae8f89451d1a0f155836c6358b0f5918af03dd80bc18173c9536720306610 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.000004 Ether
0xd6965b2c04a51f18347d6b232e753567953eecabcb961ad19d17153dd21a4222720299610 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x8ee9be167874be39fe3b41e09a5166ff283fe21a0.0002 Ether
0xd6965b2c04a51f18347d6b232e753567953eecabcb961ad19d17153dd21a4222720299610 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.0000002 Ether
0x617baad02999883f66668fafd4682f84f82fafbdaea46ccf83b38cb3e10c367b720297810 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7f88790d53dcfc2d917f896b80849b9c52f600960.0001 Ether
0x617baad02999883f66668fafd4682f84f82fafbdaea46ccf83b38cb3e10c367b720297810 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.0000001 Ether
0xf9106d35202fe9fa8e854c86e11178d8f93bd4115d0a91e2f369dcc06327fcaf720292510 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7f88790d53dcfc2d917f896b80849b9c52f600960.003 Ether
0xf9106d35202fe9fa8e854c86e11178d8f93bd4115d0a91e2f369dcc06327fcaf720292510 days 2 hrs ago0x3038045cd883abff0c6eea4b1954843c0fa5a7350x7b3c4d90e8af6030d66c07f8f815f9505e379d6f0.000003 Ether
[ Download CSV Export 
Warning: The compiled contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity), NestedArrayFunctionCallDecoder (medium-severity) Solidity Compiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: RequestEthereum
Compiler Version: v0.4.18+commit.9cf6e910
Optimization Enabled: No
Runs (Optimizer):  200


Contract Source Code
pragma solidity 0.4.18;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() public {
    owner = msg.sender;
  }


  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }


  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) onlyOwner public {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}



/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is Ownable {
  event Pause();
  event Unpause();

  bool public paused = false;


  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
    require(!paused);
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
    require(paused);
    _;
  }

  /**
   * @dev called by the owner to pause, triggers stopped state
   */
  function pause() onlyOwner whenNotPaused public {
    paused = true;
    Pause();
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() onlyOwner whenPaused public {
    paused = false;
    Unpause();
  }
}


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a * b;

    assert(a == 0 || c / a == b);
    return c;
  }

  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 c;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }

  function toInt256Safe(uint256 a) internal pure returns (int256) {
    int256 b = int256(a);
    assert(b >= 0);
    return b;
  }
}


/**
 * @title SafeMathInt
 * @dev Math operations with safety checks that throw on error
 * @dev SafeMath adapted for int256
 */
library SafeMathInt {
  function mul(int256 a, int256 b) internal pure returns (int256) {
    // Prevent overflow when multiplying INT256_MIN with -1
    // https://github.com/RequestNetwork/requestNetwork/issues/43
    assert(!(a == - 2**255 && b == -1) && !(b == - 2**255 && a == -1));

    int256 c = a * b;
    assert((b == 0) || (c / b == a));
    return c;
  }

  function div(int256 a, int256 b) internal pure returns (int256) {
    // Prevent overflow when dividing INT256_MIN by -1
    // https://github.com/RequestNetwork/requestNetwork/issues/43
    assert(!(a == - 2**255 && b == -1));

    // assert(b > 0); // Solidity automatically throws when dividing by 0
    int256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  function sub(int256 a, int256 b) internal pure returns (int256) {
    assert((b >= 0 && a - b <= a) || (b < 0 && a - b > a));

    return a - b;
  }

  function add(int256 a, int256 b) internal pure returns (int256) {
    int256 c = a + b;
    assert((b >= 0 && c >= a) || (b < 0 && c < a));
    return c;
  }

  function toUint256Safe(int256 a) internal pure returns (uint256) {
    assert(a>=0);
    return uint256(a);
  }
}

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 * @dev SafeMath adapted for uint8
 */
library SafeMathUint8 {
  function mul(uint8 a, uint8 b) internal pure returns (uint8) {
    uint8 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint8 a, uint8 b) internal pure returns (uint8) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint8 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  function sub(uint8 a, uint8 b) internal pure returns (uint8) {
    assert(b <= a);
    return a - b;
  }

  function add(uint8 a, uint8 b) internal pure returns (uint8) {
    uint8 c = a + b;
    assert(c >= a);
    return c;
  }
}

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 * @dev SafeMath adapted for uint96
 */
library SafeMathUint96 {
  function mul(uint96 a, uint96 b) internal pure returns (uint96) {
    uint96 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint96 a, uint96 b) internal pure returns (uint96) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint96 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  function sub(uint96 a, uint96 b) internal pure returns (uint96) {
    assert(b <= a);
    return a - b;
  }

  function add(uint96 a, uint96 b) internal pure returns (uint96) {
    uint96 c = a + b;
    assert(c >= a);
    return c;
  }
}

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  uint256 public totalSupply;
  function balanceOf(address who) public constant returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}


/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender) public constant returns (uint256);
  function transferFrom(address from, address to, uint256 value) public returns (bool);
  function approve(address spender, uint256 value) public returns (bool);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}


/**
 * @title Administrable
 * @dev Base contract for the administration of Core. Handles whitelisting of currency contracts
 */
contract Administrable is Pausable {

    // mapping of address of trusted contract
    mapping(address => uint8) public trustedCurrencyContracts;

    // Events of the system
    event NewTrustedContract(address newContract);
    event RemoveTrustedContract(address oldContract);

    /**
     * @dev add a trusted currencyContract 
     *
     * @param _newContractAddress The address of the currencyContract
     */
    function adminAddTrustedCurrencyContract(address _newContractAddress)
        external
        onlyOwner
    {
        trustedCurrencyContracts[_newContractAddress] = 1; //Using int instead of boolean in case we need several states in the future.
        NewTrustedContract(_newContractAddress);
    }

    /**
     * @dev remove a trusted currencyContract 
     *
     * @param _oldTrustedContractAddress The address of the currencyContract
     */
    function adminRemoveTrustedCurrencyContract(address _oldTrustedContractAddress)
        external
        onlyOwner
    {
        require(trustedCurrencyContracts[_oldTrustedContractAddress] != 0);
        trustedCurrencyContracts[_oldTrustedContractAddress] = 0;
        RemoveTrustedContract(_oldTrustedContractAddress);
    }

    /**
     * @dev get the status of a trusted currencyContract 
     * @dev Not used today, useful if we have several states in the future.
     *
     * @param _contractAddress The address of the currencyContract
     * @return The status of the currencyContract. If trusted 1, otherwise 0
     */
    function getStatusContract(address _contractAddress)
        view
        external
        returns(uint8) 
    {
        return trustedCurrencyContracts[_contractAddress];
    }

    /**
     * @dev check if a currencyContract is trusted
     *
     * @param _contractAddress The address of the currencyContract
     * @return bool true if contract is trusted
     */
    function isTrustedContract(address _contractAddress)
        public
        view
        returns(bool)
    {
        return trustedCurrencyContracts[_contractAddress] == 1;
    }
}

/**
 * @title RequestCore
 *
 * @dev The Core is the main contract which stores all the requests.
 *
 * @dev The Core philosophy is to be as much flexible as possible to adapt in the future to any new system
 * @dev All the important conditions and an important part of the business logic takes place in the currency contracts.
 * @dev Requests can only be created in the currency contracts
 * @dev Currency contracts have to be allowed by the Core and respect the business logic.
 * @dev Request Network will develop one currency contracts per currency and anyone can creates its own currency contracts.
 */
contract RequestCore is Administrable {
    using SafeMath for uint256;
    using SafeMathUint96 for uint96;
    using SafeMathInt for int256;
    using SafeMathUint8 for uint8;

    enum State { Created, Accepted, Canceled }

    struct Request {
        // ID address of the payer
        address payer;

        // Address of the contract managing the request
        address currencyContract;

        // State of the request
        State state;

        // Main payee
        Payee payee;
    }

    // Structure for the payees. A sub payee is an additional entity which will be paid during the processing of the invoice.
    // ex: can be used for routing taxes or fees at the moment of the payment.
    struct Payee {
        // ID address of the payee
        address addr;

        // amount expected for the payee. 
        // Not uint for evolution (may need negative amounts one day), and simpler operations
        int256 expectedAmount;

        // balance of the payee
        int256 balance;
    }

    // Count of request in the mapping. A maximum of 2^96 requests can be created per Core contract.
    // Integer, incremented for each request of a Core contract, starting from 0
    // RequestId (256bits) = contract address (160bits) + numRequest
    uint96 public numRequests; 
    
    // Mapping of all the Requests. The key is the request ID.
    // not anymore public to avoid "UnimplementedFeatureError: Only in-memory reference type can be stored."
    // https://github.com/ethereum/solidity/issues/3577
    mapping(bytes32 => Request) requests;

    // Mapping of subPayees of the requests. The key is the request ID.
    // This array is outside the Request structure to optimize the gas cost when there is only 1 payee.
    mapping(bytes32 => Payee[256]) public subPayees;

    /*
     *  Events 
     */
    event Created(bytes32 indexed requestId, address indexed payee, address indexed payer, address creator, string data);
    event Accepted(bytes32 indexed requestId);
    event Canceled(bytes32 indexed requestId);

    // Event for Payee & subPayees
    event NewSubPayee(bytes32 indexed requestId, address indexed payee); // Separated from the Created Event to allow a 4th indexed parameter (subpayees)
    event UpdateExpectedAmount(bytes32 indexed requestId, uint8 payeeIndex, int256 deltaAmount);
    event UpdateBalance(bytes32 indexed requestId, uint8 payeeIndex, int256 deltaAmount);

    /*
     * @dev Function used by currency contracts to create a request in the Core
     *
     * @dev _payees and _expectedAmounts must have the same size
     *
     * @param _creator Request creator. The creator is the one who initiated the request (create or sign) and not necessarily the one who broadcasted it
     * @param _payees array of payees address (the index 0 will be the payee the others are subPayees). Size must be smaller than 256.
     * @param _expectedAmounts array of Expected amount to be received by each payees. Must be in same order than the payees. Size must be smaller than 256.
     * @param _payer Entity expected to pay
     * @param _data data of the request
     * @return Returns the id of the request
     */
    function createRequest(
        address     _creator,
        address[]   _payees,
        int256[]    _expectedAmounts,
        address     _payer,
        string      _data)
        external
        whenNotPaused 
        returns (bytes32 requestId) 
    {
        // creator must not be null
        require(_creator!=0); // not as modifier to lighten the stack
        // call must come from a trusted contract
        require(isTrustedContract(msg.sender)); // not as modifier to lighten the stack

        // Generate the requestId
        requestId = generateRequestId();

        address mainPayee;
        int256 mainExpectedAmount;
        // extract the main payee if filled
        if(_payees.length!=0) {
            mainPayee = _payees[0];
            mainExpectedAmount = _expectedAmounts[0];
        }

        // Store the new request
        requests[requestId] = Request(_payer, msg.sender, State.Created, Payee(mainPayee, mainExpectedAmount, 0));

        // Declare the new request
        Created(requestId, mainPayee, _payer, _creator, _data);
        
        // Store and declare the sub payees (needed in internal function to avoid "stack too deep")
        initSubPayees(requestId, _payees, _expectedAmounts);

        return requestId;
    }

    /*
     * @dev Function used by currency contracts to create a request in the Core from bytes
     * @dev Used to avoid receiving a stack too deep error when called from a currency contract with too many parameters.
     * @audit Note that to optimize the stack size and the gas cost we do not extract the params and store them in the stack. As a result there is some code redundancy
     * @param _data bytes containing all the data packed :
            address(creator)
            address(payer)
            uint8(number_of_payees)
            [
                address(main_payee_address)
                int256(main_payee_expected_amount)
                address(second_payee_address)
                int256(second_payee_expected_amount)
                ...
            ]
            uint8(data_string_size)
            size(data)
     * @return Returns the id of the request 
     */ 
    function createRequestFromBytes(bytes _data) 
        external
        whenNotPaused 
        returns (bytes32 requestId) 
    {
        // call must come from a trusted contract
        require(isTrustedContract(msg.sender)); // not as modifier to lighten the stack

        // extract address creator & payer
        address creator = extractAddress(_data, 0);

        address payer = extractAddress(_data, 20);

        // creator must not be null
        require(creator!=0);
        
        // extract the number of payees
        uint8 payeesCount = uint8(_data[40]);

        // get the position of the dataSize in the byte (= number_of_payees * (address_payee_size + int256_payee_size) + address_creator_size + address_payer_size + payees_count_size
        //                                              (= number_of_payees * (20+32) + 20 + 20 + 1 )
        uint256 offsetDataSize = uint256(payeesCount).mul(52).add(41);

        // extract the data size and then the data itself
        uint8 dataSize = uint8(_data[offsetDataSize]);
        string memory dataStr = extractString(_data, dataSize, offsetDataSize.add(1));

        address mainPayee;
        int256 mainExpectedAmount;
        // extract the main payee if possible
        if(payeesCount!=0) {
            mainPayee = extractAddress(_data, 41);
            mainExpectedAmount = int256(extractBytes32(_data, 61));
        }

        // Generate the requestId
        requestId = generateRequestId();

        // Store the new request
        requests[requestId] = Request(payer, msg.sender, State.Created, Payee(mainPayee, mainExpectedAmount, 0));

        // Declare the new request
        Created(requestId, mainPayee, payer, creator, dataStr);

        // Store and declare the sub payees
        for(uint8 i = 1; i < payeesCount; i = i.add(1)) {
            address subPayeeAddress = extractAddress(_data, uint256(i).mul(52).add(41));

            // payees address cannot be 0x0
            require(subPayeeAddress != 0);

            subPayees[requestId][i-1] =  Payee(subPayeeAddress, int256(extractBytes32(_data, uint256(i).mul(52).add(61))), 0);
            NewSubPayee(requestId, subPayeeAddress);
        }

        return requestId;
    }

    /*
     * @dev Function used by currency contracts to accept a request in the Core.
     * @dev callable only by the currency contract of the request
     * @param _requestId Request id
     */ 
    function accept(bytes32 _requestId) 
        external
    {
        Request storage r = requests[_requestId];
        require(r.currencyContract==msg.sender); 
        r.state = State.Accepted;
        Accepted(_requestId);
    }

    /*
     * @dev Function used by currency contracts to cancel a request in the Core. Several reasons can lead to cancel a request, see request life cycle for more info.
     * @dev callable only by the currency contract of the request
     * @param _requestId Request id
     */ 
    function cancel(bytes32 _requestId)
        external
    {
        Request storage r = requests[_requestId];
        require(r.currencyContract==msg.sender);
        r.state = State.Canceled;
        Canceled(_requestId);
    }   

    /*
     * @dev Function used to update the balance
     * @dev callable only by the currency contract of the request
     * @param _requestId Request id
     * @param _payeeIndex index of the payee (0 = main payee)
     * @param _deltaAmount modifier amount
     */ 
    function updateBalance(bytes32 _requestId, uint8 _payeeIndex, int256 _deltaAmount)
        external
    {   
        Request storage r = requests[_requestId];
        require(r.currencyContract==msg.sender);

        if( _payeeIndex == 0 ) {
            // modify the main payee
            r.payee.balance = r.payee.balance.add(_deltaAmount);
        } else {
            // modify the sub payee
            Payee storage sp = subPayees[_requestId][_payeeIndex-1];
            sp.balance = sp.balance.add(_deltaAmount);
        }
        UpdateBalance(_requestId, _payeeIndex, _deltaAmount);
    }

    /*
     * @dev Function update the expectedAmount adding additional or subtract
     * @dev callable only by the currency contract of the request
     * @param _requestId Request id
     * @param _payeeIndex index of the payee (0 = main payee)
     * @param _deltaAmount modifier amount
     */ 
    function updateExpectedAmount(bytes32 _requestId, uint8 _payeeIndex, int256 _deltaAmount)
        external
    {   
        Request storage r = requests[_requestId];
        require(r.currencyContract==msg.sender); 

        if( _payeeIndex == 0 ) {
            // modify the main payee
            r.payee.expectedAmount = r.payee.expectedAmount.add(_deltaAmount);    
        } else {
            // modify the sub payee
            Payee storage sp = subPayees[_requestId][_payeeIndex-1];
            sp.expectedAmount = sp.expectedAmount.add(_deltaAmount);
        }
        UpdateExpectedAmount(_requestId, _payeeIndex, _deltaAmount);
    }

    /*
     * @dev Internal: Init payees for a request (needed to avoid 'stack too deep' in createRequest())
     * @param _requestId Request id
     * @param _payees array of payees address
     * @param _expectedAmounts array of payees initial expected amounts
     */ 
    function initSubPayees(bytes32 _requestId, address[] _payees, int256[] _expectedAmounts)
        internal
    {
        require(_payees.length == _expectedAmounts.length);
     
        for (uint8 i = 1; i < _payees.length; i = i.add(1))
        {
            // payees address cannot be 0x0
            require(_payees[i] != 0);
            subPayees[_requestId][i-1] = Payee(_payees[i], _expectedAmounts[i], 0);
            NewSubPayee(_requestId, _payees[i]);
        }
    }


    /* GETTER */
    /*
     * @dev Get address of a payee
     * @param _requestId Request id
     * @param _payeeIndex payee index (0 = main payee)
     * @return payee address
     */ 
    function getPayeeAddress(bytes32 _requestId, uint8 _payeeIndex)
        public
        constant
        returns(address)
    {
        if(_payeeIndex == 0) {
            return requests[_requestId].payee.addr;
        } else {
            return subPayees[_requestId][_payeeIndex-1].addr;
        }
    }

    /*
     * @dev Get payer of a request
     * @param _requestId Request id
     * @return payer address
     */ 
    function getPayer(bytes32 _requestId)
        public
        constant
        returns(address)
    {
        return requests[_requestId].payer;
    }

    /*
     * @dev Get amount expected of a payee
     * @param _requestId Request id
     * @param _payeeIndex payee index (0 = main payee)
     * @return amount expected
     */     
    function getPayeeExpectedAmount(bytes32 _requestId, uint8 _payeeIndex)
        public
        constant
        returns(int256)
    {
        if(_payeeIndex == 0) {
            return requests[_requestId].payee.expectedAmount;
        } else {
            return subPayees[_requestId][_payeeIndex-1].expectedAmount;
        }
    }

    /*
     * @dev Get number of subPayees for a request
     * @param _requestId Request id
     * @return number of subPayees
     */     
    function getSubPayeesCount(bytes32 _requestId)
        public
        constant
        returns(uint8)
    {
        for (uint8 i = 0; subPayees[_requestId][i].addr != address(0); i = i.add(1)) {
            // nothing to do
        }
        return i;
    }

    /*
     * @dev Get currencyContract of a request
     * @param _requestId Request id
     * @return currencyContract address
     */
    function getCurrencyContract(bytes32 _requestId)
        public
        constant
        returns(address)
    {
        return requests[_requestId].currencyContract;
    }

    /*
     * @dev Get balance of a payee
     * @param _requestId Request id
     * @param _payeeIndex payee index (0 = main payee)
     * @return balance
     */     
    function getPayeeBalance(bytes32 _requestId, uint8 _payeeIndex)
        public
        constant
        returns(int256)
    {
        if(_payeeIndex == 0) {
            return requests[_requestId].payee.balance;    
        } else {
            return subPayees[_requestId][_payeeIndex-1].balance;
        }
    }

    /*
     * @dev Get balance total of a request
     * @param _requestId Request id
     * @return balance
     */     
    function getBalance(bytes32 _requestId)
        public
        constant
        returns(int256)
    {
        int256 balance = requests[_requestId].payee.balance;

        for (uint8 i = 0; subPayees[_requestId][i].addr != address(0); i = i.add(1))
        {
            balance = balance.add(subPayees[_requestId][i].balance);
        }

        return balance;
    }


    /*
     * @dev check if all the payees balances are null
     * @param _requestId Request id
     * @return true if all the payees balances are equals to 0
     */     
    function areAllBalanceNull(bytes32 _requestId)
        public
        constant
        returns(bool isNull)
    {
        isNull = requests[_requestId].payee.balance == 0;

        for (uint8 i = 0; isNull && subPayees[_requestId][i].addr != address(0); i = i.add(1))
        {
            isNull = subPayees[_requestId][i].balance == 0;
        }

        return isNull;
    }

    /*
     * @dev Get total expectedAmount of a request
     * @param _requestId Request id
     * @return balance
     */     
    function getExpectedAmount(bytes32 _requestId)
        public
        constant
        returns(int256)
    {
        int256 expectedAmount = requests[_requestId].payee.expectedAmount;

        for (uint8 i = 0; subPayees[_requestId][i].addr != address(0); i = i.add(1))
        {
            expectedAmount = expectedAmount.add(subPayees[_requestId][i].expectedAmount);
        }

        return expectedAmount;
    }

    /*
     * @dev Get state of a request
     * @param _requestId Request id
     * @return state
     */ 
    function getState(bytes32 _requestId)
        public
        constant
        returns(State)
    {
        return requests[_requestId].state;
    }

    /*
     * @dev Get address of a payee
     * @param _requestId Request id
     * @return payee index (0 = main payee) or -1 if not address not found
     */
    function getPayeeIndex(bytes32 _requestId, address _address)
        public
        constant
        returns(int16)
    {
        // return 0 if main payee
        if(requests[_requestId].payee.addr == _address) return 0;

        for (uint8 i = 0; subPayees[_requestId][i].addr != address(0); i = i.add(1))
        {
            if(subPayees[_requestId][i].addr == _address) {
                // if found return subPayee index + 1 (0 is main payee)
                return i+1;
            }
        }
        return -1;
    }

    /*
     * @dev getter of a request
     * @param _requestId Request id
     * @return request as a tuple : (address payer, address currencyContract, State state, address payeeAddr, int256 payeeExpectedAmount, int256 payeeBalance)
     */ 
    function getRequest(bytes32 _requestId) 
        external
        constant
        returns(address payer, address currencyContract, State state, address payeeAddr, int256 payeeExpectedAmount, int256 payeeBalance)
    {
        Request storage r = requests[_requestId];
        return ( r.payer, 
                 r.currencyContract, 
                 r.state, 
                 r.payee.addr, 
                 r.payee.expectedAmount, 
                 r.payee.balance );
    }

    /*
     * @dev extract a string from a bytes. Extracts a sub-part from tha bytes and convert it to string
     * @param data bytes from where the string will be extracted
     * @param size string size to extract
     * @param _offset position of the first byte of the string in bytes
     * @return string
     */ 
    function extractString(bytes data, uint8 size, uint _offset) 
        internal 
        pure 
        returns (string) 
    {
        bytes memory bytesString = new bytes(size);
        for (uint j = 0; j < size; j++) {
            bytesString[j] = data[_offset+j];
        }
        return string(bytesString);
    }

    /*
     * @dev generate a new unique requestId
     * @return a bytes32 requestId 
     */ 
    function generateRequestId()
        internal
        returns (bytes32)
    {
        // Update numRequest
        numRequests = numRequests.add(1);
        // requestId = ADDRESS_CONTRACT_CORE + numRequests (0xADRRESSCONTRACT00000NUMREQUEST)
        return bytes32((uint256(this) << 96).add(numRequests));
    }

    /*
     * @dev extract an address from a bytes at a given position
     * @param _data bytes from where the address will be extract
     * @param _offset position of the first byte of the address
     * @return address
     */
    function extractAddress(bytes _data, uint offset)
        internal
        pure
        returns (address m)
    {
        require(offset >=0 && offset + 20 <= _data.length);
        assembly {
            m := and( mload(add(_data, add(20, offset))), 
                      0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
        }
    }

    /*
     * @dev extract a bytes32 from a bytes
     * @param data bytes from where the bytes32 will be extract
     * @param offset position of the first byte of the bytes32
     * @return address
     */
    function extractBytes32(bytes _data, uint offset)
        public
        pure
        returns (bytes32 bs)
    {
        require(offset >=0 && offset + 32 <= _data.length);
        assembly {
            bs := mload(add(_data, add(32, offset)))
        }
    }

    /**
     * @dev transfer to owner any tokens send by mistake on this contracts
     * @param token The address of the token to transfer.
     * @param amount The amount to be transfered.
     */
    function emergencyERC20Drain(ERC20 token, uint amount )
        public
        onlyOwner 
    {
        token.transfer(owner, amount);
    }
}

/**
 * @title RequestEthereumCollect
 *
 * @dev RequestEthereumCollect is a contract managing the fees for ethereum currency contract
 */
contract RequestEthereumCollect is Pausable {
    using SafeMath for uint256;

    // fees percentage (per 10 000)
    uint256 public feesPer10000;

    // maximum fees in wei
    uint256 public maxFees;

    // address of the contract that will burn req token (probably through Kyber)
    address public requestBurnerContract;

    /*
     * @dev Constructor
     * @param _requestBurnerContract Address of the contract where to send the ethers. 
     * This burner contract will have a function that can be called by anyone and will exchange ethers to req via Kyber and burn the REQ
     */  
    function RequestEthereumCollect(address _requestBurnerContract) 
        public
    {
        requestBurnerContract = _requestBurnerContract;
    }

    /*
     * @dev send fees to the request burning address
     * @param _amount amount to send to the burning address
     */  
    function collectForREQBurning(uint256 _amount)
        internal
        returns(bool)
    {
        return requestBurnerContract.send(_amount);
    }

    /*
     * @dev compute the fees
     * @param _expectedAmount amount expected for the request
     * @return 
     */  
    function collectEstimation(int256 _expectedAmount)
        public
        view
        returns(uint256)
    {
        // Force potential negative number to 0
        if (_expectedAmount <= 0) {
            return 0;
        }
        uint256 computedCollect = uint256(_expectedAmount).mul(feesPer10000).div(10000);
        return computedCollect < maxFees ? computedCollect : maxFees;
    }

    /*
     * @dev set the fees rate (per 10 000)
     * @param _newRate new rate
     * @return 
     */  
    function setFeesPerTenThousand(uint256 _newRate) 
        external
        onlyOwner
    {
        feesPer10000=_newRate;
    }

    /*
     * @dev set the maximum fees in wei
     * @param _newMax new max
     * @return 
     */  
    function setMaxCollectable(uint256 _newMax) 
        external
        onlyOwner
    {
        maxFees=_newMax;
    }

    /*
     * @dev set the request burner address
     * @param _requestBurnerContract address of the contract that will burn req token (probably through Kyber)
     * @return 
     */  
    function setRequestBurnerContract(address _requestBurnerContract) 
        external
        onlyOwner
    {
        requestBurnerContract=_requestBurnerContract;
    }
}



/**
 * @title RequestEthereum
 *
 * @dev RequestEthereum is the currency contract managing the request in Ethereum
 * @dev The contract can be paused. In this case, nobody can create Requests anymore but people can still interact with them.
 *
 * @dev Requests can be created by the Payee with createRequestAsPayee(), by the payer with createRequestAsPayer() or by the payer from a request signed offchain by the payee with broadcastSignedRequestAsPayer()
 */
contract RequestEthereum is RequestEthereumCollect {
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using SafeMathUint8 for uint8;

    // RequestCore object
    RequestCore public requestCore;

    // payment addresses by requestId (optional). We separate the Identity of the payee/payer (in the core) and the wallet address in the currency contract
    mapping(bytes32 => address[256]) public payeesPaymentAddress;
    mapping(bytes32 => address) public payerRefundAddress;

    /*
     * @dev Constructor
     * @param _requestCoreAddress Request Core address
     * @param _requestBurnerAddress Request Burner contract address
     */
    function RequestEthereum(address _requestCoreAddress, address _requestBurnerAddress) RequestEthereumCollect(_requestBurnerAddress) public
    {
        requestCore=RequestCore(_requestCoreAddress);
    }

    /*
     * @dev Function to create a request as payee
     *
     * @dev msg.sender will be the payee
     * @dev if _payeesPaymentAddress.length > _payeesIdAddress.length, the extra addresses will be stored but never used
     * @dev If a contract is given as a payee make sure it is payable. Otherwise, the request will not be payable.
     *
     * @param _payeesIdAddress array of payees address (the index 0 will be the payee - must be msg.sender - the others are subPayees)
     * @param _payeesPaymentAddress array of payees address for payment (optional)
     * @param _expectedAmounts array of Expected amount to be received by each payees
     * @param _payer Entity expected to pay
     * @param _payerRefundAddress Address of refund for the payer (optional)
     * @param _data Hash linking to additional data on the Request stored on IPFS
     *
     * @return Returns the id of the request
     */
    function createRequestAsPayee(
        address[]   _payeesIdAddress,
        address[]   _payeesPaymentAddress,
        int256[]    _expectedAmounts,
        address     _payer,
        address     _payerRefundAddress,
        string      _data)
        external
        payable
        whenNotPaused
        returns(bytes32 requestId)
    {
        require(msg.sender == _payeesIdAddress[0] && msg.sender != _payer && _payer != 0);

        uint256 fees;
        (requestId, fees) = createRequest(_payer, _payeesIdAddress, _payeesPaymentAddress, _expectedAmounts, _payerRefundAddress, _data);

        // check if the value send match exactly the fees (no under or over payment allowed)
        require(fees == msg.value);

        return requestId;
    }

    /*
     * @dev Function to create a request as payer. The request is payed if _payeeAmounts > 0.
     *
     * @dev msg.sender will be the payer
     * @dev If a contract is given as a payee make sure it is payable. Otherwise, the request will not be payable.
     *
     * @param _payeesIdAddress array of payees address (the index 0 will be the payee the others are subPayees)
     * @param _expectedAmounts array of Expected amount to be received by each payees
     * @param _payerRefundAddress Address of refund for the payer (optional)
     * @param _payeeAmounts array of amount repartition for the payment
     * @param _additionals array to increase the ExpectedAmount for payees
     * @param _data Hash linking to additional data on the Request stored on IPFS
     *
     * @return Returns the id of the request
     */
    function createRequestAsPayer(
        address[]   _payeesIdAddress,
        int256[]    _expectedAmounts,
        address     _payerRefundAddress,
        uint256[]   _payeeAmounts,
        uint256[]   _additionals,
        string      _data)
        external
        payable
        whenNotPaused
        returns(bytes32 requestId)
    {
        require(msg.sender != _payeesIdAddress[0] && _payeesIdAddress[0] != 0);

        // payeesPaymentAddress is not offered as argument here to avoid scam
        address[] memory emptyPayeesPaymentAddress = new address[](0);
        uint256 fees;
        (requestId, fees) = createRequest(msg.sender, _payeesIdAddress, emptyPayeesPaymentAddress, _expectedAmounts, _payerRefundAddress, _data);

        // accept and pay the request with the value remaining after the fee collect
        acceptAndPay(requestId, _payeeAmounts, _additionals, msg.value.sub(fees));

        return requestId;
    }


    /*
     * @dev Function to broadcast and accept an offchain signed request (can be paid and additionals also)
     *
     * @dev _payer will be set msg.sender
     * @dev if _payeesPaymentAddress.length > _requestData.payeesIdAddress.length, the extra addresses will be stored but never used
     * @dev If a contract is given as a payee make sure it is payable. Otherwise, the request will not be payable.
     *
     * @param _requestData nested bytes containing : creator, payer, payees, expectedAmounts, data
     * @param _payeesPaymentAddress array of payees address for payment (optional) 
     * @param _payeeAmounts array of amount repartition for the payment
     * @param _additionals array to increase the ExpectedAmount for payees
     * @param _expirationDate timestamp after that the signed request cannot be broadcasted
     * @param _signature ECDSA signature in bytes
     *
     * @return Returns the id of the request
     */
    function broadcastSignedRequestAsPayer(
        bytes       _requestData, // gather data to avoid "stack too deep"
        address[]   _payeesPaymentAddress,
        uint256[]   _payeeAmounts,
        uint256[]   _additionals,
        uint256     _expirationDate,
        bytes       _signature)
        external
        payable
        whenNotPaused
        returns(bytes32)
    {
        // check expiration date
        require(_expirationDate >= block.timestamp);

        // check the signature
        require(checkRequestSignature(_requestData, _payeesPaymentAddress, _expirationDate, _signature));

        // create accept and pay the request
        return createAcceptAndPayFromBytes(_requestData,  _payeesPaymentAddress, _payeeAmounts, _additionals);
    }

    /*
     * @dev Internal function to create, accept, add additionals and pay a request as Payer
     *
     * @dev msg.sender must be _payer
     *
     * @param _requestData nasty bytes containing : creator, payer, payees|expectedAmounts, data
     * @param _payeesPaymentAddress array of payees address for payment (optional)
     * @param _payeeAmounts array of amount repartition for the payment
     * @param _additionals Will increase the ExpectedAmount of the request right after its creation by adding additionals
     *
     * @return Returns the id of the request
     */
    function createAcceptAndPayFromBytes(
        bytes       _requestData,
        address[]   _payeesPaymentAddress,
        uint256[]   _payeeAmounts,
        uint256[]   _additionals)
        internal
        returns(bytes32 requestId)
    {
        // extract main payee
        address mainPayee = extractAddress(_requestData, 41);
        require(msg.sender != mainPayee && mainPayee != 0);
        // creator must be the main payee
        require(extractAddress(_requestData, 0) == mainPayee);

        // extract the number of payees
        uint8 payeesCount = uint8(_requestData[40]);
        int256 totalExpectedAmounts = 0;
        for(uint8 i = 0; i < payeesCount; i++) {
            // extract the expectedAmount for the payee[i]
            // NB: no need of SafeMath here because 0 < i < 256 (uint8)
            int256 expectedAmountTemp = int256(extractBytes32(_requestData, 61 + 52 * uint256(i)));
            // compute the total expected amount of the request
            totalExpectedAmounts = totalExpectedAmounts.add(expectedAmountTemp);
            // all expected amount must be positibe
            require(expectedAmountTemp>0);
        }

        // collect the fees
        uint256 fees = collectEstimation(totalExpectedAmounts);

        // check fees has been well received
        // do the action and assertion in one to save a variable
        require(collectForREQBurning(fees));

        // insert the msg.sender as the payer in the bytes
        updateBytes20inBytes(_requestData, 20, bytes20(msg.sender));
        // store request in the core,
        requestId = requestCore.createRequestFromBytes(_requestData);

        // set payment addresses for payees
        for (uint8 j = 0; j < _payeesPaymentAddress.length; j = j.add(1)) {
            payeesPaymentAddress[requestId][j] = _payeesPaymentAddress[j];
        }

        // accept and pay the request with the value remaining after the fee collect
        acceptAndPay(requestId, _payeeAmounts, _additionals, msg.value.sub(fees));

        return requestId;
    }


    /*
     * @dev Internal function to create a request
     *
     * @dev msg.sender is the creator of the request
     *
     * @param _payer Payer identity address
     * @param _payees Payees identity address
     * @param _payeesPaymentAddress Payees payment address
     * @param _expectedAmounts Expected amounts to be received by payees
     * @param _payerRefundAddress payer refund address
     * @param _data Hash linking to additional data on the Request stored on IPFS
     *
     * @return Returns the id of the request
     */
    function createRequest(
        address     _payer,
        address[]   _payees,
        address[]   _payeesPaymentAddress,
        int256[]    _expectedAmounts,
        address     _payerRefundAddress,
        string      _data)
        internal
        returns(bytes32 requestId, uint256 fees)
    {
        int256 totalExpectedAmounts = 0;
        for (uint8 i = 0; i < _expectedAmounts.length; i = i.add(1))
        {
            // all expected amount must be positive
            require(_expectedAmounts[i]>=0);
            // compute the total expected amount of the request
            totalExpectedAmounts = totalExpectedAmounts.add(_expectedAmounts[i]);
        }

        // collect the fees
        fees = collectEstimation(totalExpectedAmounts);
        // check fees has been well received
        require(collectForREQBurning(fees));

        // store request in the core
        requestId= requestCore.createRequest(msg.sender, _payees, _expectedAmounts, _payer, _data);

        // set payment addresses for payees
        for (uint8 j = 0; j < _payeesPaymentAddress.length; j = j.add(1)) {
            payeesPaymentAddress[requestId][j] = _payeesPaymentAddress[j];
        }
        // set payment address for payer
        if(_payerRefundAddress != 0) {
            payerRefundAddress[requestId] = _payerRefundAddress;
        }
    }

    /*
     * @dev Internal function to accept, add additionals and pay a request as Payer
     *
     * @param _requestId id of the request
     * @param _payeesAmounts Amount to pay to payees (sum must be equals to _amountPaid)
     * @param _additionals Will increase the ExpectedAmounts of payees
     * @param _amountPaid amount in msg.value minus the fees
     *
     */ 
    function acceptAndPay(
        bytes32 _requestId,
        uint256[] _payeeAmounts,
        uint256[] _additionals,
        uint256 _amountPaid)
        internal
    {
        requestCore.accept(_requestId);
        
        additionalInternal(_requestId, _additionals);

        if(_amountPaid > 0) {
            paymentInternal(_requestId, _payeeAmounts, _amountPaid);
        }
    }

    // ---- INTERFACE FUNCTIONS ------------------------------------------------------------------------------------

    /*
     * @dev Function to accept a request
     *
     * @dev msg.sender must be _payer
     * @dev A request can also be accepted by using directly the payment function on a request in the Created status
     *
     * @param _requestId id of the request
     */
    function accept(bytes32 _requestId)
        external
        whenNotPaused
        condition(requestCore.getPayer(_requestId)==msg.sender)
        condition(requestCore.getState(_requestId)==RequestCore.State.Created)
    {
        requestCore.accept(_requestId);
    }

    /*
     * @dev Function to cancel a request
     *
     * @dev msg.sender must be the _payer or the _payee.
     * @dev only request with balance equals to zero can be cancel
     *
     * @param _requestId id of the request
     */
    function cancel(bytes32 _requestId)
        external
        whenNotPaused
    {
        // payer can cancel if request is just created
        bool isPayerAndCreated = requestCore.getPayer(_requestId)==msg.sender && requestCore.getState(_requestId)==RequestCore.State.Created;

        // payee can cancel when request is not canceled yet
        bool isPayeeAndNotCanceled = requestCore.getPayeeAddress(_requestId,0)==msg.sender && requestCore.getState(_requestId)!=RequestCore.State.Canceled;

        require(isPayerAndCreated || isPayeeAndNotCanceled);

        // impossible to cancel a Request with any payees balance != 0
        require(requestCore.areAllBalanceNull(_requestId));

        requestCore.cancel(_requestId);
    }

    // ----------------------------------------------------------------------------------------


    // ---- CONTRACT FUNCTIONS ------------------------------------------------------------------------------------
    /*
     * @dev Function PAYABLE to pay a request in ether.
     *
     * @dev the request will be automatically accepted if msg.sender==payer.
     *
     * @param _requestId id of the request
     * @param _payeesAmounts Amount to pay to payees (sum must be equal to msg.value) in wei
     * @param _additionalsAmount amount of additionals per payee in wei to declare
     */
    function paymentAction(
        bytes32 _requestId,
        uint256[] _payeeAmounts,
        uint256[] _additionalAmounts)
        external
        whenNotPaused
        payable
        condition(requestCore.getState(_requestId)!=RequestCore.State.Canceled)
        condition(_additionalAmounts.length == 0 || msg.sender == requestCore.getPayer(_requestId))
    {
        // automatically accept request if request is created and msg.sender is payer
        if(requestCore.getState(_requestId)==RequestCore.State.Created && msg.sender == requestCore.getPayer(_requestId)) {
            requestCore.accept(_requestId);
        }

        additionalInternal(_requestId, _additionalAmounts);

        paymentInternal(_requestId, _payeeAmounts, msg.value);
    }

    /*
     * @dev Function PAYABLE to pay back in ether a request to the payer
     *
     * @dev msg.sender must be one of the payees
     * @dev the request must be created or accepted
     *
     * @param _requestId id of the request
     */
    function refundAction(bytes32 _requestId)
        external
        whenNotPaused
        payable
    {
        refundInternal(_requestId, msg.sender, msg.value);
    }

    /*
     * @dev Function to declare a subtract
     *
     * @dev msg.sender must be _payee
     * @dev the request must be accepted or created
     *
     * @param _requestId id of the request
     * @param _subtractAmounts amounts of subtract in wei to declare (index 0 is for main payee)
     */
    function subtractAction(bytes32 _requestId, uint256[] _subtractAmounts)
        external
        whenNotPaused
        condition(requestCore.getState(_requestId)!=RequestCore.State.Canceled)
        onlyRequestPayee(_requestId)
    {
        for(uint8 i = 0; i < _subtractAmounts.length; i = i.add(1)) {
            if(_subtractAmounts[i] != 0) {
                // subtract must be equal or lower than amount expected
                require(requestCore.getPayeeExpectedAmount(_requestId,i) >= _subtractAmounts[i].toInt256Safe());
                // store and declare the subtract in the core
                requestCore.updateExpectedAmount(_requestId, i, -_subtractAmounts[i].toInt256Safe());
            }
        }
    }

    /*
     * @dev Function to declare an additional
     *
     * @dev msg.sender must be _payer
     * @dev the request must be accepted or created
     *
     * @param _requestId id of the request
     * @param _additionalAmounts amounts of additional in wei to declare (index 0 is for main payee)
     */
    function additionalAction(bytes32 _requestId, uint256[] _additionalAmounts)
        external
        whenNotPaused
        condition(requestCore.getState(_requestId)!=RequestCore.State.Canceled)
        onlyRequestPayer(_requestId)
    {
        additionalInternal(_requestId, _additionalAmounts);
    }
    // ----------------------------------------------------------------------------------------


    // ---- INTERNAL FUNCTIONS ------------------------------------------------------------------------------------
    /*
     * @dev Function internal to manage additional declaration
     *
     * @param _requestId id of the request
     * @param _additionalAmounts amount of additional to declare
     */
    function additionalInternal(bytes32 _requestId, uint256[] _additionalAmounts)
        internal
    {
        // we cannot have more additional amounts declared than actual payees but we can have fewer
        require(_additionalAmounts.length <= requestCore.getSubPayeesCount(_requestId).add(1));

        for(uint8 i = 0; i < _additionalAmounts.length; i = i.add(1)) {
            if(_additionalAmounts[i] != 0) {
                // Store and declare the additional in the core
                requestCore.updateExpectedAmount(_requestId, i, _additionalAmounts[i].toInt256Safe());
            }
        }
    }

    /*
     * @dev Function internal to manage payment declaration
     *
     * @param _requestId id of the request
     * @param _payeesAmounts Amount to pay to payees (sum must be equals to msg.value)
     * @param _value amount paid
     */
    function paymentInternal(
        bytes32     _requestId,
        uint256[]   _payeeAmounts,
        uint256     _value)
        internal
    {
        // we cannot have more amounts declared than actual payees
        require(_payeeAmounts.length <= requestCore.getSubPayeesCount(_requestId).add(1));

        uint256 totalPayeeAmounts = 0;

        for(uint8 i = 0; i < _payeeAmounts.length; i = i.add(1)) {
            if(_payeeAmounts[i] != 0) {
                // compute the total amount declared
                totalPayeeAmounts = totalPayeeAmounts.add(_payeeAmounts[i]);

                // Store and declare the payment to the core
                requestCore.updateBalance(_requestId, i, _payeeAmounts[i].toInt256Safe());

                // pay the payment address if given, the id address otherwise
                address addressToPay;
                if(payeesPaymentAddress[_requestId][i] == 0) {
                    addressToPay = requestCore.getPayeeAddress(_requestId, i);
                } else {
                    addressToPay = payeesPaymentAddress[_requestId][i];
                }

                //payment done, the money was sent
                fundOrderInternal(addressToPay, _payeeAmounts[i]);
            }
        }

        // check if payment repartition match the value paid
        require(_value==totalPayeeAmounts);
    }

    /*
     * @dev Function internal to manage refund declaration
     *
     * @param _requestId id of the request

     * @param _fromAddress address from where the refund has been done
     * @param _amount amount of the refund in wei to declare
     *
     * @return true if the refund is done, false otherwise
     */
    function refundInternal(
        bytes32 _requestId,
        address _fromAddress,
        uint256 _amount)
        condition(requestCore.getState(_requestId)!=RequestCore.State.Canceled)
        internal
    {
        // Check if the _fromAddress is a payeesId
        // int16 to allow -1 value
        int16 payeeIndex = requestCore.getPayeeIndex(_requestId, _fromAddress);
        if(payeeIndex < 0) {
            uint8 payeesCount = requestCore.getSubPayeesCount(_requestId).add(1);

            // if not ID addresses maybe in the payee payments addresses
            for (uint8 i = 0; i < payeesCount && payeeIndex == -1; i = i.add(1)) {
                if(payeesPaymentAddress[_requestId][i] == _fromAddress) {
                    // get the payeeIndex
                    payeeIndex = int16(i);
                }
            }
        }
        // the address must be found somewhere
        require(payeeIndex >= 0); 

        // Casting to uin8 doesn't lose bits because payeeIndex < 256. payeeIndex was declared int16 to allow -1
        requestCore.updateBalance(_requestId, uint8(payeeIndex), -_amount.toInt256Safe());

        // refund to the payment address if given, the id address otherwise
        address addressToPay = payerRefundAddress[_requestId];
        if(addressToPay == 0) {
            addressToPay = requestCore.getPayer(_requestId);
        }

        // refund declared, the money is ready to be sent to the payer
        fundOrderInternal(addressToPay, _amount);
    }

    /*
     * @dev Function internal to manage fund mouvement
     * @dev We had to chose between a withdrawal pattern, a transfer pattern or a transfer+withdrawal pattern and chose the transfer pattern.
     * @dev The withdrawal pattern would make UX difficult. The transfer+withdrawal pattern would make contracts interacting with the request protocol complex.
     * @dev N.B.: The transfer pattern will have to be clearly explained to users. It enables a payee to create unpayable requests.
     *
     * @param _recipient address where the wei has to be sent to
     * @param _amount amount in wei to send
     *
     */
    function fundOrderInternal(
        address _recipient,
        uint256 _amount)
        internal
    {
        _recipient.transfer(_amount);
    }

    /*
     * @dev Function internal to calculate Keccak-256 hash of a request with specified parameters
     *
     * @param _data bytes containing all the data packed
     * @param _payeesPaymentAddress array of payees payment addresses
     * @param _expirationDate timestamp after what the signed request cannot be broadcasted
     *
     * @return Keccak-256 hash of (this,_requestData, _payeesPaymentAddress, _expirationDate)
     */
    function getRequestHash(
        // _requestData is from the core
        bytes       _requestData,

        // _payeesPaymentAddress and _expirationDate are not from the core but needs to be signed
        address[]   _payeesPaymentAddress,
        uint256     _expirationDate)
        internal
        view
        returns(bytes32)
    {
        return keccak256(this, _requestData, _payeesPaymentAddress, _expirationDate);
    }

    /*
     * @dev Verifies that a hash signature is valid. 0x style
     * @param signer address of signer.
     * @param hash Signed Keccak-256 hash.
     * @param v ECDSA signature parameter v.
     * @param r ECDSA signature parameters r.
     * @param s ECDSA signature parameters s.
     * @return Validity of order signature.
     */
    function isValidSignature(
        address signer,
        bytes32 hash,
        uint8   v,
        bytes32 r,
        bytes32 s)
        public
        pure
        returns (bool)
    {
        return signer == ecrecover(
            keccak256("\x19Ethereum Signed Message:\n32", hash),
            v,
            r,
            s
        );
    }

    /*
     * @dev Check the validity of a signed request & the expiration date
     * @param _data bytes containing all the data packed :
            address(creator)
            address(payer)
            uint8(number_of_payees)
            [
                address(main_payee_address)
                int256(main_payee_expected_amount)
                address(second_payee_address)
                int256(second_payee_expected_amount)
                ...
            ]
            uint8(data_string_size)
            size(data)
     * @param _payeesPaymentAddress array of payees payment addresses (the index 0 will be the payee the others are subPayees)
     * @param _expirationDate timestamp after that the signed request cannot be broadcasted
     * @param _signature ECDSA signature containing v, r and s as bytes
     *
     * @return Validity of order signature.
     */ 
    function checkRequestSignature(
        bytes       _requestData,
        address[]   _payeesPaymentAddress,
        uint256     _expirationDate,
        bytes       _signature)
        public
        view
        returns (bool)
    {
        bytes32 hash = getRequestHash(_requestData, _payeesPaymentAddress, _expirationDate);

        // extract "v, r, s" from the signature
        uint8 v = uint8(_signature[64]);
        v = v < 27 ? v.add(27) : v;
        bytes32 r = extractBytes32(_signature, 0);
        bytes32 s = extractBytes32(_signature, 32);

        // check signature of the hash with the creator address
        return isValidSignature(extractAddress(_requestData, 0), hash, v, r, s);
    }

    //modifier
    modifier condition(bool c)
    {
        require(c);
        _;
    }

    /*
     * @dev Modifier to check if msg.sender is payer
     * @dev Revert if msg.sender is not payer
     * @param _requestId id of the request
     */ 
    modifier onlyRequestPayer(bytes32 _requestId)
    {
        require(requestCore.getPayer(_requestId)==msg.sender);
        _;
    }
    
    /*
     * @dev Modifier to check if msg.sender is the main payee
     * @dev Revert if msg.sender is not the main payee
     * @param _requestId id of the request
     */ 
    modifier onlyRequestPayee(bytes32 _requestId)
    {
        require(requestCore.getPayeeAddress(_requestId, 0)==msg.sender);
        _;
    }

    /*
     * @dev modify 20 bytes in a bytes
     * @param data bytes to modify
     * @param offset position of the first byte to modify
     * @param b bytes20 to insert
     * @return address
     */
    function updateBytes20inBytes(bytes data, uint offset, bytes20 b)
        internal
        pure
    {
        require(offset >=0 && offset + 20 <= data.length);
        assembly {
            let m := mload(add(data, add(20, offset)))
            m := and(m, 0xFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000)
            m := or(m, div(b, 0x1000000000000000000000000))
            mstore(add(data, add(20, offset)), m)
        }
    }

    /*
     * @dev extract an address in a bytes
     * @param data bytes from where the address will be extract
     * @param offset position of the first byte of the address
     * @return address
     */
    function extractAddress(bytes _data, uint offset)
        internal
        pure
        returns (address m) 
    {
        require(offset >=0 && offset + 20 <= _data.length);
        assembly {
            m := and( mload(add(_data, add(20, offset))), 
                      0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
        }
    }

    /*
     * @dev extract a bytes32 from a bytes
     * @param data bytes from where the bytes32 will be extract
     * @param offset position of the first byte of the bytes32
     * @return address
     */
    function extractBytes32(bytes _data, uint offset)
        public
        pure
        returns (bytes32 bs)
    {
        require(offset >=0 && offset + 32 <= _data.length);
        assembly {
            bs := mload(add(_data, add(32, offset)))
        }
    }


    /**
     * @dev transfer to owner any tokens send by mistake on this contracts
     * @param token The address of the token to transfer.
     * @param amount The amount to be transfered.
     */
    function emergencyERC20Drain(ERC20 token, uint amount )
        public
        onlyOwner 
    {
        token.transfer(owner, amount);
    }
}

Contract ABI
[{"constant":true,"inputs":[{"name":"_expectedAmount","type":"int256"}],"name":"collectEstimation","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_payeesIdAddress","type":"address[]"},{"name":"_expectedAmounts","type":"int256[]"},{"name":"_payerRefundAddress","type":"address"},{"name":"_payeeAmounts","type":"uint256[]"},{"name":"_additionals","type":"uint256[]"},{"name":"_data","type":"string"}],"name":"createRequestAsPayer","outputs":[{"name":"requestId","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"},{"name":"_payeeAmounts","type":"uint256[]"},{"name":"_additionalAmounts","type":"uint256[]"}],"name":"paymentAction","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"},{"name":"_subtractAmounts","type":"uint256[]"}],"name":"subtractAction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newRate","type":"uint256"}],"name":"setFeesPerTenThousand","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_requestData","type":"bytes"},{"name":"_payeesPaymentAddress","type":"address[]"},{"name":"_expirationDate","type":"uint256"},{"name":"_signature","type":"bytes"}],"name":"checkRequestSignature","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestBurnerContract","type":"address"}],"name":"setRequestBurnerContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"requestCore","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"},{"name":"hash","type":"bytes32"},{"name":"v","type":"uint8"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"isValidSignature","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"},{"name":"_additionalAmounts","type":"uint256[]"}],"name":"additionalAction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestData","type":"bytes"},{"name":"_payeesPaymentAddress","type":"address[]"},{"name":"_payeeAmounts","type":"uint256[]"},{"name":"_additionals","type":"uint256[]"},{"name":"_expirationDate","type":"uint256"},{"name":"_signature","type":"bytes"}],"name":"broadcastSignedRequestAsPayer","outputs":[{"name":"","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"payerRefundAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_payeesIdAddress","type":"address[]"},{"name":"_payeesPaymentAddress","type":"address[]"},{"name":"_expectedAmounts","type":"int256[]"},{"name":"_payer","type":"address"},{"name":"_payerRefundAddress","type":"address"},{"name":"_data","type":"string"}],"name":"createRequestAsPayee","outputs":[{"name":"requestId","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_data","type":"bytes"},{"name":"offset","type":"uint256"}],"name":"extractBytes32","outputs":[{"name":"bs","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"feesPer10000","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"uint256"}],"name":"payeesPaymentAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"}],"name":"refundAction","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"}],"name":"cancel","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newMax","type":"uint256"}],"name":"setMaxCollectable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"}],"name":"emergencyERC20Drain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"requestBurnerContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"}],"name":"accept","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maxFees","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_requestCoreAddress","type":"address"},{"name":"_requestBurnerAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

Contract Creation Code
606060405260008060146101000a81548160ff021916908315150217905550341561002957600080fd5b6040516040806145dd8339810160405280805190602001909190805190602001909190505080336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506144ba806101236000396000f30060606040526004361061016a576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318954b3e1461016f5780631e24e029146101a657806327dd16e514610254578063289b45fb1461029857806338bf77c3146102d35780633f4ba83a146102f65780634b0a0d041461030b578063524eb29c1461040c5780635c975abb146104455780636c4fbaa4146104725780638163681e146104c757806383565cc71461054b5780638456cb59146105865780638da5cb5b1461059b5780639dbdd85c146105f0578063a460b89c14610688578063afd6b607146106ef578063b1e05e8a146107a8578063b2ba0aa51461082a578063b2f35bdd14610853578063b9103e1f146108c3578063c4d252f5146108df578063d7b8de0014610906578063db0e16f114610929578063e40e84571461096b578063e4725ba1146109c0578063e83e34b1146109e7578063f2fde38b14610a10575b600080fd5b341561017a57600080fd5b6101906004808035906020019091905050610a49565b6040518082815260200191505060405180910390f35b61023660048080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019082018035906020019190919290803590602001908201803590602001919091929080359060200190820180359060200191909192905050610aa6565b60405180826000191660001916815260200191505060405180910390f35b61029660048080356000191690602001909190803590602001908201803590602001919091929080359060200190820180359060200191909192905050610cd9565b005b34156102a357600080fd5b6102d160048080356000191690602001909190803590602001908201803590602001919091929050506111cf565b005b34156102de57600080fd5b6102f46004808035906020019091905050611604565b005b341561030157600080fd5b610309611669565b005b341561031657600080fd5b6103f2600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611727565b604051808215151515815260200191505060405180910390f35b341561041757600080fd5b610443600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611825565b005b341561045057600080fd5b6104586118c4565b604051808215151515815260200191505060405180910390f35b341561047d57600080fd5b6104856118d7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104d257600080fd5b610531600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118fd565b604051808215151515815260200191505060405180910390f35b341561055657600080fd5b6105846004808035600019169060200190919080359060200190820180359060200191909192905050611a04565b005b341561059157600080fd5b610599611c37565b005b34156105a657600080fd5b6105ae611cf7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61066a600480803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803590602001908201803590602001919091929080359060200190919080359060200190820180359060200191909192905050611d1c565b60405180826000191660001916815260200191505060405180910390f35b341561069357600080fd5b6106ad600480803560001916906020019091905050611ece565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61078a600480803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190820180359060200191909192905050611f01565b60405180826000191660001916815260200191505060405180910390f35b34156107b357600080fd5b61080c600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190919050506120d5565b60405180826000191660001916815260200191505060405180910390f35b341561083557600080fd5b61083d612105565b6040518082815260200191505060405180910390f35b341561085e57600080fd5b61088160048080356000191690602001909190803590602001909190505061210b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108dd600480803560001916906020019091905050612150565b005b34156108ea57600080fd5b61090460048080356000191690602001909190505061217a565b005b341561091157600080fd5b61092760048080359060200190919050506126c2565b005b341561093457600080fd5b610969600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050612727565b005b341561097657600080fd5b61097e61286e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156109cb57600080fd5b6109e5600480803560001916906020019091905050612894565b005b34156109f257600080fd5b6109fa612b38565b6040518082815260200191505060405180910390f35b3415610a1b57600080fd5b610a47600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612b3e565b005b600080600083131515610a5f5760009150610aa0565b610a88612710610a7a60015486612c9390919063ffffffff16565b612cc690919063ffffffff16565b90506002548110610a9b57600254610a9d565b805b91505b50919050565b6000610ab061447a565b60008060149054906101000a900460ff16151515610acd57600080fd5b8d8d60008181101515610adc57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610b76575060008e8e60008181101515610b4057fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b1515610b8157600080fd5b6000604051805910610b905750595b90808252806020026020018201604052509150610c41338f8f80806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050848f8f808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508e8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050612ce1565b8092508194505050610cc5838a8a80806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050898980806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050610cc085346130e690919063ffffffff16565b6130ff565b82925050509b9a5050505050505050505050565b600060149054906101000a900460ff16151515610cf557600080fd5b600280811115610d0157fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610da257600080fd5b6102c65a03f11515610db357600080fd5b505050604051805190506002811115610dc857fe5b1415801515610dd657600080fd5b6000838390501480610ece5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610e8457600080fd5b6102c65a03f11515610e9557600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b801515610eda57600080fd5b60006002811115610ee757fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610f8857600080fd5b6102c65a03f11515610f9957600080fd5b505050604051805190506002811115610fae57fe5b1480156110a15750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70886000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561105757600080fd5b6102c65a03f1151561106857600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1561115357600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1886040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b151561113e57600080fd5b6102c65a03f1151561114f57600080fd5b5050505b61118c878585808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506131d0565b6111c687878780806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050346133f3565b50505050505050565b60008060149054906101000a900460ff161515156111ec57600080fd5b6002808111156111f857fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561129957600080fd5b6102c65a03f115156112aa57600080fd5b5050506040518051905060028111156112bf57fe5b14158015156112cd57600080fd5b843373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0183600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b151561139157600080fd5b6102c65a03f115156113a257600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff161415156113ce57600080fd5b600092505b848490508360ff1610156115fc57600085858560ff1681811015156113f457fe5b905060200201351415156115de5761142285858560ff16818110151561141657fe5b9050602002013561380f565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ad8d87588866000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b15156114d157600080fd5b6102c65a03f115156114e257600080fd5b50505060405180519050121515156114f957600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce165894878561155989898960ff16818110151561154d57fe5b9050602002013561380f565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156115c957600080fd5b6102c65a03f115156115da57600080fd5b5050505b6115f560018460ff1661382b90919063ffffffff16565b92506113d3565b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561165f57600080fd5b8060018190555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116c457600080fd5b600060149054906101000a900460ff1615156116df57600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600080600061173a89898961384f565b935085604081518110151561174b57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090049250601b8360ff16106117cc57826117e4565b6117e3601b8460ff1661382b90919063ffffffff16565b5b92506117f18660006120d5565b91506117fe8660206120d5565b905061181761180e8a600061393d565b858585856118fd565b945050505050949350505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188057600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060149054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f115156119c257600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614905095945050505050565b600060149054906101000a900460ff16151515611a2057600080fd5b600280811115611a2c57fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611acd57600080fd5b6102c65a03f11515611ade57600080fd5b505050604051805190506002811115611af357fe5b1415801515611b0157600080fd5b833373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611bba57600080fd5b6102c65a03f11515611bcb57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16141515611bf757600080fd5b611c30858585808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506131d0565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611c9257600080fd5b600060149054906101000a900460ff16151515611cae57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060149054906101000a900460ff16151515611d3957600080fd5b428410151515611d4857600080fd5b611de78c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508686868080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611727565b1515611df257600080fd5b611ebd8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508a8a80806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050898980806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050613983565b90509b9a5050505050505050505050565b60066020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600060149054906101000a900460ff16151515611f2057600080fd5b8b8b60008181101515611f2f57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148015611fb257508573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b8015611fd5575060008673ffffffffffffffffffffffffffffffffffffffff1614155b1515611fe057600080fd5b6120ad868d8d808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508c8c808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508989898080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050612ce1565b809250819350505034811415156120c357600080fd5b819150509a9950505050505050505050565b60008082101580156120eb575082516020830111155b15156120f657600080fd5b81602001830151905092915050565b60015481565b6005602052816000526040600020816101008110151561212757fe5b016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1615151561216c57600080fd5b612177813334613d58565b50565b600080600060149054906101000a900460ff1615151561219957600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561225157600080fd5b6102c65a03f1151561226257600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff1614801561236057506000600281111561229757fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561233857600080fd5b6102c65a03f1151561234957600080fd5b50505060405180519050600281111561235e57fe5b145b91503373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0185600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b151561242557600080fd5b6102c65a03f1151561243657600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015612534575060028081111561246a57fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561250b57600080fd5b6102c65a03f1151561251c57600080fd5b50505060405180519050600281111561253157fe5b14155b9050818061253f5750805b151561254a57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166307550f0a846000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156125eb57600080fd5b6102c65a03f115156125fc57600080fd5b50505060405180519050151561261157600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c4d252f5846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b15156126a957600080fd5b6102c65a03f115156126ba57600080fd5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561271d57600080fd5b8060028190555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561278257600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561284e57600080fd5b6102c65a03f1151561285f57600080fd5b50505060405180519050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff161515156128b057600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561296857600080fd5b6102c65a03f1151561297957600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015156129a657600080fd5b600060028111156129b357fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d846000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515612a5457600080fd5b6102c65a03f11515612a6557600080fd5b505050604051805190506002811115612a7a57fe5b14801515612a8757600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b1515612b1f57600080fd5b6102c65a03f11515612b3057600080fd5b505050505050565b60025481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612b9957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612bd557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008082840290506000841480612cb45750828482811515612cb157fe5b04145b1515612cbc57fe5b8091505092915050565b6000808284811515612cd457fe5b0490508091505092915050565b6000806000806000809250600091505b87518260ff161015612d74576000888360ff16815181101515612d1057fe5b9060200190602002015112151515612d2757600080fd5b612d54888360ff16815181101515612d3b57fe5b906020019060200201518461430990919063ffffffff16565b9250612d6d60018360ff1661382b90919063ffffffff16565b9150612cf1565b612d7d83610a49565b9350612d888461434a565b1515612d9357600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166343107290338c8b8f8b6000604051602001526040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001848103845288818151815260200191508051906020019060200280838360005b83811015612eb9578082015181840152602081019050612e9e565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015612efb578082015181840152602081019050612ee0565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612f3a578082015181840152602081019050612f1f565b50505050905090810190601f168015612f675780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1515612f8b57600080fd5b6102c65a03f11515612f9c57600080fd5b505050604051805190509450600090505b88518160ff16101561305d57888160ff16815181101515612fca57fe5b906020019060200201516005600087600019166000191681526020019081526020016000208260ff166101008110151561300057fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061305660018260ff1661382b90919063ffffffff16565b9050612fad565b60008773ffffffffffffffffffffffffffffffffffffffff161415156130d8578660066000876000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505050965096945050505050565b60008282111515156130f457fe5b818303905092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b151561319757600080fd5b6102c65a03f115156131a857600080fd5b5050506131b584836131d0565b60008111156131ca576131c98484836133f3565b5b50505050565b60006132a46001600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561327857600080fd5b6102c65a03f1151561328957600080fd5b5050506040518051905060ff1661382b90919063ffffffff16565b60ff168251111515156132b657600080fd5b600090505b81518160ff1610156133ee576000828260ff168151811015156132da57fe5b906020019060200201511415156133d057600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce165894848361334e868660ff1681518110151561333f57fe5b9060200190602002015161380f565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156133bb57600080fd5b6102c65a03f115156133cc57600080fd5b5050505b6133e760018260ff1661382b90919063ffffffff16565b90506132bb565b505050565b60008060006134ca6001600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561349e57600080fd5b6102c65a03f115156134af57600080fd5b5050506040518051905060ff1661382b90919063ffffffff16565b60ff168551111515156134dc57600080fd5b60009250600091505b84518260ff1610156137f9576000858360ff1681518110151561350457fe5b906020019060200201511415156137db57613542858360ff1681518110151561352957fe5b90602001906020020151846143aa90919063ffffffff16565b9250600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b87846135a7898760ff1681518110151561359857fe5b9060200190602002015161380f565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b151561361457600080fd5b6102c65a03f1151561362557600080fd5b50505060006005600088600019166000191681526020019081526020016000208360ff166101008110151561365657fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561376557600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0187846000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b151561374357600080fd5b6102c65a03f1151561375457600080fd5b5050506040518051905090506137b6565b6005600087600019166000191681526020019081526020016000208260ff166101008110151561379157fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b6137da81868460ff168151811015156137cb57fe5b906020019060200201516143c8565b5b6137f260018360ff1661382b90919063ffffffff16565b91506134e5565b828414151561380757600080fd5b505050505050565b6000808290506000811215151561382257fe5b80915050919050565b60008082840190508360ff168160ff161015151561384557fe5b8091505092915050565b600030848484604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140184805190602001908083835b6020831015156138cb57805182526020820191506020810190506020830392506138a6565b6001836020036101000a038019825116818451168082178552505050505050905001838051906020019060200280838360005b838110156139195780820151818401526020810190506138fe565b50505050905001828152602001945050505050604051809103902090509392505050565b6000808210158015613953575082516014830111155b151561395e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8260140184015116905092915050565b60008060008060008060008061399a8c602961393d565b96508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156139ef575060008773ffffffffffffffffffffffffffffffffffffffff1614155b15156139fa57600080fd5b8673ffffffffffffffffffffffffffffffffffffffff16613a1c8d600061393d565b73ffffffffffffffffffffffffffffffffffffffff16141515613a3e57600080fd5b8b6028815181101515613a4d57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004955060009450600093505b8560ff168460ff161015613b1e57613ae78c8560ff16603402603d016120d5565b600190049250613b00838661430990919063ffffffff16565b9450600083131515613b1157600080fd5b8380600101945050613ac6565b613b2785610a49565b9150613b328261434a565b1515613b3d57600080fd5b613b588c6014336c010000000000000000000000000261440c565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1cda4688d6000604051602001526040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613c0b578082015181840152602081019050613bf0565b50505050905090810190601f168015613c385780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1515613c5657600080fd5b6102c65a03f11515613c6757600080fd5b505050604051805190509750600090505b8a518160ff161015613d28578a8160ff16815181101515613c9557fe5b90602001906020020151600560008a600019166000191681526020019081526020016000208260ff1661010081101515613ccb57fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550613d2160018260ff1661382b90919063ffffffff16565b9050613c78565b613d46888b8b613d4186346130e690919063ffffffff16565b6130ff565b87975050505050505050949350505050565b600080600080600280811115613d6a57fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613e0b57600080fd5b6102c65a03f11515613e1c57600080fd5b505050604051805190506002811115613e3157fe5b1415801515613e3f57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f6112d6889896000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1515613f1457600080fd5b6102c65a03f11515613f2557600080fd5b50505060405180519050945060008560010b12156140f95761400f6001600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec8b6000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613fe357600080fd5b6102c65a03f11515613ff457600080fd5b5050506040518051905060ff1661382b90919063ffffffff16565b9350600092505b8360ff168360ff1610801561404d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8560010b145b156140f8578673ffffffffffffffffffffffffffffffffffffffff16600560008a600019166000191681526020019081526020016000208460ff166101008110151561409557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156140da578260ff1694505b6140f160018460ff1661382b90919063ffffffff16565b9250614016565b5b60008560010b1215151561410c57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b89876141558a61380f565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156141c557600080fd5b6102c65a03f115156141d657600080fd5b50505060066000896000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915060008273ffffffffffffffffffffffffffffffffffffffff1614156142f557600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156142d757600080fd5b6102c65a03f115156142e857600080fd5b5050506040518051905091505b6142ff82876143c8565b5050505050505050565b6000808284019050600083121580156143225750838112155b80614338575060008312801561433757508381125b5b151561434057fe5b8091505092915050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050509050919050565b60008082840190508381101515156143be57fe5b8091505092915050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561440857600080fd5b5050565b60008210158015614421575082516014830111155b151561442c57600080fd5b816014018301517fffffffffffffffffffffffff0000000000000000000000000000000000000000811690506c01000000000000000000000000820481179050808360140185015250505050565b6020604051908101604052806000815250905600a165627a7a72305820b7b7de135c9eef2f859422958047d56a4552bfdcdc9c55e27c6ec758d24886ff0029000000000000000000000000db600fda54568a35b78565b5257125bebc51eb27000000000000000000000000fcb4393e7faef06fab01c00d67c1895545aff3b8


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

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000db600fda54568a35b78565b5257125bebc51eb27
Arg [1] : 000000000000000000000000fcb4393e7faef06fab01c00d67c1895545aff3b8


   Swarm Source:
bzzr://b7b7de135c9eef2f859422958047d56a4552bfdcdc9c55e27c6ec758d24886ff
Block Age transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.