Contract 0xd88ab9b1691340e04a5bbf78529c11d592d35f57

Contract Overview

Balance:
0 Ether
TxHash Block Age From To Value [TxFee]
0x31dcacedbdf9476fd3926d80fc0b7a5d99add5811eb0db97ee92a12c0ade9b7d40347024 days 11 hrs ago0xe910978b243111ed3f9d253e841c1bde20d89719 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.00004259508 Ether0.00137808
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xe910978b243111ed3f9d253e841c1bde20d89719 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000034306272 Ether0.00184684
0x51d5faf6435d719ccff7adf3437b64b9925dec861242b1724a68ca8136a1eb1840244356 days 6 hrs ago0x320c820013a1d229b9925342a8fe1c358ddafc7b IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.0000099 Ether0.0005372016
0xc464814ac162cf200d05edb50af2c7cd7d34535198c053b596a0fe14ba766fea40236286 days 9 hrs ago0x0a8a88573c6d1cf087b6d2b5deb66d3774cca33c IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000001 Ether0.0010749024
0x4e85081789d2e17694d4945d526aec67204346492a600f776921fe8d5ce6f71040236206 days 9 hrs ago0x0a8a88573c6d1cf087b6d2b5deb66d3774cca33c IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000001 Ether0.0010749024
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xf232028e8c4fdb513138d8c7c87986a774632f53 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.001 Ether0.00076296
0x8ae0f347872b762fdb0a46c0bbf6a0813ce259212cb2f7a113b8e299f882c9f740236016 days 9 hrs ago0xf232028e8c4fdb513138d8c7c87986a774632f53 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000001 Ether0.0010749024
0x33d709387e8e569aba084201d956dc01d05d42ef8e4ef4a1d4dcb12e71164d7940191297 days 4 hrs ago0x0acebc5977b6a984959f73a6b8b3c867e57b10e0 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000001 Ether0.000895752
0x18371a9e5e9f9c03029cf1dbdbee1dda2e4778cd0305175288f1762fbf61bad240190137 days 4 hrs ago0xdcb336734032da752344c83b4d22325a6650a1fa IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000001 Ether0.000895752
0xe25cc0ad9b62225b515779a0910c9b74ee17aa14d115f7842f0b6f5a63bdc91240185987 days 6 hrs ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.037305267999999 Ether0.0018494
0xc7c33e70df0ab0194d92530875ecdbf0b25e3a28d3eeea4ffa3d3ad43dfa94dc40140958 days 1 hr ago0x0acebc5977b6a984959f73a6b8b3c867e57b10e0 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.00000007454 Ether0.00137744
0x57adf3ebda45109c5355b68b1726a8a1f9c07ec81c2ff5956b897dd7a9f9a11840140098 days 1 hr ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.0001696695 Ether0.00184684
0xdb9191f276d4cea6c617da0e4a2904d5be727103cd9ce8a78c4c83795d9d35e540137928 days 2 hrs ago0x0acebc5977b6a984959f73a6b8b3c867e57b10e0 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.00000007509 Ether0.00137744
0xd88ff9fbeeddc34f5d17e493773155aeec4e8ee2be47d7b80dbb49d8345c87ca40132658 days 4 hrs ago0x0acebc5977b6a984959f73a6b8b3c867e57b10e0 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.00000007491 Ether0.00137744
0xd3f906609ff39112800b2259ca8daf73e68fadd31bf4c0ddd24416d22a92f01f40132598 days 4 hrs ago0x0acebc5977b6a984959f73a6b8b3c867e57b10e0 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000007492 Ether0.00137872
0x8ec7fa0a4005ecff80aea946109d8ea4b238d3865d36b3cd79d9887c461afc1340131738 days 5 hrs ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.003003 Ether0.00184812
0x689788a7e13286ef12537b37d7ae93cba06ecacd838607146c14af669a99963f40131358 days 5 hrs ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.06006 Ether0.00184684
0x4f92283316d13e7caf2980b9962c3a9f739517e7f6e189936a98611bee5b93dd40131108 days 5 hrs ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.009009 Ether0.00184812
0x4af782ab18036d15cdb55142e498e2ed5e5e7f57bbc0fe7a5f348a60747cb76840130818 days 5 hrs ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.004252248 Ether0.00184812
0x7f748199c2bae38eae454b10c35f782ea71c12da0077b149882f0134be10148a40130438 days 5 hrs ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.033941908 Ether0.0018494
0x32933939913de98bd55763f1a53be7529bb852f6aeb574261b2ebb08e04dcec640130318 days 5 hrs ago0x5129f06d1e500b342807592c2d04eae664eb52b2 IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.0005090085 Ether0.00184812
0xd0090acb403c40340772af3bcba0339fcb42558f923089375f3498bb44e3284040126298 days 7 hrs ago0x0bcf54f8145444b2da71e3e042b0313b38e8a41b IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.0000856 Ether0.0012540528
0xbe64e99ba562f7d3ba9876c1f66903b66db2a4d4b165834f064007d43276d94940125968 days 7 hrs ago0x0bcf54f8145444b2da71e3e042b0313b38e8a41b IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.0000654 Ether0.0012540528
0x39a4424aaf9ec735c55f77aca56b1f285e72dc8c0b64f89ea5fdec0101e3de8b40124248 days 8 hrs ago0x0bcf54f8145444b2da71e3e042b0313b38e8a41b IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000007543 Ether0.00137808
0x6fa6297887faa2bb7a7260573a96a7cdd1a22b71f7b54f88c71d87a8dd3c318440124238 days 8 hrs ago0x0bcf54f8145444b2da71e3e042b0313b38e8a41b IN  0xd88ab9b1691340e04a5bbf78529c11d592d35f570.000007549 Ether0.00137808
[ 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
0x31dcacedbdf9476fd3926d80fc0b7a5d99add5811eb0db97ee92a12c0ade9b7d40347024 days 11 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x31dcacedbdf9476fd3926d80fc0b7a5d99add5811eb0db97ee92a12c0ade9b7d40347024 days 11 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570xfcb4393e7faef06fab01c00d67c1895545aff3b80.00004259508 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x0bcf54f8145444b2da71e3e042b0313b38e8a41b0.000034272 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x680ec8ca7d90c46d7a8d68b80511a48698c621da1efc64b9667b9a2a90978de040316095 days 15 mins ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570xfcb4393e7faef06fab01c00d67c1895545aff3b80.000000034272 Ether
0x51d5faf6435d719ccff7adf3437b64b9925dec861242b1724a68ca8136a1eb1840244356 days 6 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x51d5faf6435d719ccff7adf3437b64b9925dec861242b1724a68ca8136a1eb1840244356 days 6 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570xfcb4393e7faef06fab01c00d67c1895545aff3b80.0000099 Ether
0xc464814ac162cf200d05edb50af2c7cd7d34535198c053b596a0fe14ba766fea40236286 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0xc464814ac162cf200d05edb50af2c7cd7d34535198c053b596a0fe14ba766fea40236286 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570xfcb4393e7faef06fab01c00d67c1895545aff3b80.000001 Ether
0x4e85081789d2e17694d4945d526aec67204346492a600f776921fe8d5ce6f71040236206 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x4e85081789d2e17694d4945d526aec67204346492a600f776921fe8d5ce6f71040236206 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570xfcb4393e7faef06fab01c00d67c1895545aff3b80.000001 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570xf232028e8c4fdb513138d8c7c87986a774632f530.001 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0xe74b79568b60318bffe42a821ad9be4bcb5c34bb57bf46d9e7205eb00ee701ea40236066 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 Ether
0x8ae0f347872b762fdb0a46c0bbf6a0813ce259212cb2f7a113b8e299f882c9f740236016 days 9 hrs ago0xd88ab9b1691340e04a5bbf78529c11d592d35f570x8fc2e7f2498f1d06461ee2d547002611b801202b0 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
606060405260008060146101000a81548160ff021916908315150217905550341561002957600080fd5b6040516040806145dd8339810160405280805190602001909190805190602001909190505080336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506144ba806101236000396000f30060606040526004361061016a576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318954b3e1461016f5780631e24e029146101a657806327dd16e514610254578063289b45fb1461029857806338bf77c3146102d35780633f4ba83a146102f65780634b0a0d041461030b578063524eb29c1461040c5780635c975abb146104455780636c4fbaa4146104725780638163681e146104c757806383565cc71461054b5780638456cb59146105865780638da5cb5b1461059b5780639dbdd85c146105f0578063a460b89c14610688578063afd6b607146106ef578063b1e05e8a146107a8578063b2ba0aa51461082a578063b2f35bdd14610853578063b9103e1f146108c3578063c4d252f5146108df578063d7b8de0014610906578063db0e16f114610929578063e40e84571461096b578063e4725ba1146109c0578063e83e34b1146109e7578063f2fde38b14610a10575b600080fd5b341561017a57600080fd5b6101906004808035906020019091905050610a49565b6040518082815260200191505060405180910390f35b61023660048080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019082018035906020019190919290803590602001908201803590602001919091929080359060200190820180359060200191909192905050610aa6565b60405180826000191660001916815260200191505060405180910390f35b61029660048080356000191690602001909190803590602001908201803590602001919091929080359060200190820180359060200191909192905050610cd9565b005b34156102a357600080fd5b6102d160048080356000191690602001909190803590602001908201803590602001919091929050506111cf565b005b34156102de57600080fd5b6102f46004808035906020019091905050611604565b005b341561030157600080fd5b610309611669565b005b341561031657600080fd5b6103f2600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611727565b604051808215151515815260200191505060405180910390f35b341561041757600080fd5b610443600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611825565b005b341561045057600080fd5b6104586118c4565b604051808215151515815260200191505060405180910390f35b341561047d57600080fd5b6104856118d7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104d257600080fd5b610531600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118fd565b604051808215151515815260200191505060405180910390f35b341561055657600080fd5b6105846004808035600019169060200190919080359060200190820180359060200191909192905050611a04565b005b341561059157600080fd5b610599611c37565b005b34156105a657600080fd5b6105ae611cf7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61066a600480803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803590602001908201803590602001919091929080359060200190919080359060200190820180359060200191909192905050611d1c565b60405180826000191660001916815260200191505060405180910390f35b341561069357600080fd5b6106ad600480803560001916906020019091905050611ece565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61078a600480803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190820180359060200191909192905050611f01565b60405180826000191660001916815260200191505060405180910390f35b34156107b357600080fd5b61080c600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190919050506120d5565b60405180826000191660001916815260200191505060405180910390f35b341561083557600080fd5b61083d612105565b6040518082815260200191505060405180910390f35b341561085e57600080fd5b61088160048080356000191690602001909190803590602001909190505061210b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108dd600480803560001916906020019091905050612150565b005b34156108ea57600080fd5b61090460048080356000191690602001909190505061217a565b005b341561091157600080fd5b61092760048080359060200190919050506126c2565b005b341561093457600080fd5b610969600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050612727565b005b341561097657600080fd5b61097e61286e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156109cb57600080fd5b6109e5600480803560001916906020019091905050612894565b005b34156109f257600080fd5b6109fa612b38565b6040518082815260200191505060405180910390f35b3415610a1b57600080fd5b610a47600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612b3e565b005b600080600083131515610a5f5760009150610aa0565b610a88612710610a7a60015486612c9390919063ffffffff16565b612cc690919063ffffffff16565b90506002548110610a9b57600254610a9d565b805b91505b50919050565b6000610ab061447a565b60008060149054906101000a900460ff16151515610acd57600080fd5b8d8d60008181101515610adc57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610b76575060008e8e60008181101515610b4057fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b1515610b8157600080fd5b6000604051805910610b905750595b90808252806020026020018201604052509150610c41338f8f80806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050848f8f808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508e8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050612ce1565b8092508194505050610cc5838a8a80806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050898980806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050610cc085346130e690919063ffffffff16565b6130ff565b82925050509b9a5050505050505050505050565b600060149054906101000a900460ff16151515610cf557600080fd5b600280811115610d0157fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610da257600080fd5b6102c65a03f11515610db357600080fd5b505050604051805190506002811115610dc857fe5b1415801515610dd657600080fd5b6000838390501480610ece5750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610e8457600080fd5b6102c65a03f11515610e9557600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b801515610eda57600080fd5b60006002811115610ee757fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610f8857600080fd5b6102c65a03f11515610f9957600080fd5b505050604051805190506002811115610fae57fe5b1480156110a15750600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70886000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561105757600080fd5b6102c65a03f1151561106857600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1561115357600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1886040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b151561113e57600080fd5b6102c65a03f1151561114f57600080fd5b5050505b61118c878585808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506131d0565b6111c687878780806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050346133f3565b50505050505050565b60008060149054906101000a900460ff161515156111ec57600080fd5b6002808111156111f857fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561129957600080fd5b6102c65a03f115156112aa57600080fd5b5050506040518051905060028111156112bf57fe5b14158015156112cd57600080fd5b843373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0183600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b151561139157600080fd5b6102c65a03f115156113a257600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff161415156113ce57600080fd5b600092505b848490508360ff1610156115fc57600085858560ff1681811015156113f457fe5b905060200201351415156115de5761142285858560ff16818110151561141657fe5b9050602002013561380f565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ad8d87588866000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b15156114d157600080fd5b6102c65a03f115156114e257600080fd5b50505060405180519050121515156114f957600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce165894878561155989898960ff16818110151561154d57fe5b9050602002013561380f565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156115c957600080fd5b6102c65a03f115156115da57600080fd5b5050505b6115f560018460ff1661382b90919063ffffffff16565b92506113d3565b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561165f57600080fd5b8060018190555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116c457600080fd5b600060149054906101000a900460ff1615156116df57600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600080600061173a89898961384f565b935085604081518110151561174b57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090049250601b8360ff16106117cc57826117e4565b6117e3601b8460ff1661382b90919063ffffffff16565b5b92506117f18660006120d5565b91506117fe8660206120d5565b905061181761180e8a600061393d565b858585856118fd565b945050505050949350505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188057600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060149054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f115156119c257600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614905095945050505050565b600060149054906101000a900460ff16151515611a2057600080fd5b600280811115611a2c57fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611acd57600080fd5b6102c65a03f11515611ade57600080fd5b505050604051805190506002811115611af357fe5b1415801515611b0157600080fd5b833373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611bba57600080fd5b6102c65a03f11515611bcb57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16141515611bf757600080fd5b611c30858585808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506131d0565b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611c9257600080fd5b600060149054906101000a900460ff16151515611cae57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060149054906101000a900460ff16151515611d3957600080fd5b428410151515611d4857600080fd5b611de78c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508686868080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611727565b1515611df257600080fd5b611ebd8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508a8a80806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050898980806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050613983565b90509b9a5050505050505050505050565b60066020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600060149054906101000a900460ff16151515611f2057600080fd5b8b8b60008181101515611f2f57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148015611fb257508573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b8015611fd5575060008673ffffffffffffffffffffffffffffffffffffffff1614155b1515611fe057600080fd5b6120ad868d8d808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508c8c808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508989898080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050612ce1565b809250819350505034811415156120c357600080fd5b819150509a9950505050505050505050565b60008082101580156120eb575082516020830111155b15156120f657600080fd5b81602001830151905092915050565b60015481565b6005602052816000526040600020816101008110151561212757fe5b016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1615151561216c57600080fd5b612177813334613d58565b50565b600080600060149054906101000a900460ff1615151561219957600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561225157600080fd5b6102c65a03f1151561226257600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff1614801561236057506000600281111561229757fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561233857600080fd5b6102c65a03f1151561234957600080fd5b50505060405180519050600281111561235e57fe5b145b91503373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0185600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b151561242557600080fd5b6102c65a03f1151561243657600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015612534575060028081111561246a57fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d856000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561250b57600080fd5b6102c65a03f1151561251c57600080fd5b50505060405180519050600281111561253157fe5b14155b9050818061253f5750805b151561254a57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166307550f0a846000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156125eb57600080fd5b6102c65a03f115156125fc57600080fd5b50505060405180519050151561261157600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c4d252f5846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b15156126a957600080fd5b6102c65a03f115156126ba57600080fd5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561271d57600080fd5b8060028190555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561278257600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561284e57600080fd5b6102c65a03f1151561285f57600080fd5b50505060405180519050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff161515156128b057600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561296857600080fd5b6102c65a03f1151561297957600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015156129a657600080fd5b600060028111156129b357fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d846000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515612a5457600080fd5b6102c65a03f11515612a6557600080fd5b505050604051805190506002811115612a7a57fe5b14801515612a8757600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b1515612b1f57600080fd5b6102c65a03f11515612b3057600080fd5b505050505050565b60025481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612b9957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612bd557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008082840290506000841480612cb45750828482811515612cb157fe5b04145b1515612cbc57fe5b8091505092915050565b6000808284811515612cd457fe5b0490508091505092915050565b6000806000806000809250600091505b87518260ff161015612d74576000888360ff16815181101515612d1057fe5b9060200190602002015112151515612d2757600080fd5b612d54888360ff16815181101515612d3b57fe5b906020019060200201518461430990919063ffffffff16565b9250612d6d60018360ff1661382b90919063ffffffff16565b9150612cf1565b612d7d83610a49565b9350612d888461434a565b1515612d9357600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166343107290338c8b8f8b6000604051602001526040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001848103845288818151815260200191508051906020019060200280838360005b83811015612eb9578082015181840152602081019050612e9e565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015612efb578082015181840152602081019050612ee0565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612f3a578082015181840152602081019050612f1f565b50505050905090810190601f168015612f675780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1515612f8b57600080fd5b6102c65a03f11515612f9c57600080fd5b505050604051805190509450600090505b88518160ff16101561305d57888160ff16815181101515612fca57fe5b906020019060200201516005600087600019166000191681526020019081526020016000208260ff166101008110151561300057fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061305660018260ff1661382b90919063ffffffff16565b9050612fad565b60008773ffffffffffffffffffffffffffffffffffffffff161415156130d8578660066000876000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505050965096945050505050565b60008282111515156130f457fe5b818303905092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1856040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b151561319757600080fd5b6102c65a03f115156131a857600080fd5b5050506131b584836131d0565b60008111156131ca576131c98484836133f3565b5b50505050565b60006132a46001600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561327857600080fd5b6102c65a03f1151561328957600080fd5b5050506040518051905060ff1661382b90919063ffffffff16565b60ff168251111515156132b657600080fd5b600090505b81518160ff1610156133ee576000828260ff168151811015156132da57fe5b906020019060200201511415156133d057600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce165894848361334e868660ff1681518110151561333f57fe5b9060200190602002015161380f565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156133bb57600080fd5b6102c65a03f115156133cc57600080fd5b5050505b6133e760018260ff1661382b90919063ffffffff16565b90506132bb565b505050565b60008060006134ca6001600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561349e57600080fd5b6102c65a03f115156134af57600080fd5b5050506040518051905060ff1661382b90919063ffffffff16565b60ff168551111515156134dc57600080fd5b60009250600091505b84518260ff1610156137f9576000858360ff1681518110151561350457fe5b906020019060200201511415156137db57613542858360ff1681518110151561352957fe5b90602001906020020151846143aa90919063ffffffff16565b9250600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b87846135a7898760ff1681518110151561359857fe5b9060200190602002015161380f565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b151561361457600080fd5b6102c65a03f1151561362557600080fd5b50505060006005600088600019166000191681526020019081526020016000208360ff166101008110151561365657fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561376557600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0187846000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b151561374357600080fd5b6102c65a03f1151561375457600080fd5b5050506040518051905090506137b6565b6005600087600019166000191681526020019081526020016000208260ff166101008110151561379157fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b6137da81868460ff168151811015156137cb57fe5b906020019060200201516143c8565b5b6137f260018360ff1661382b90919063ffffffff16565b91506134e5565b828414151561380757600080fd5b505050505050565b6000808290506000811215151561382257fe5b80915050919050565b60008082840190508360ff168160ff161015151561384557fe5b8091505092915050565b600030848484604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140184805190602001908083835b6020831015156138cb57805182526020820191506020810190506020830392506138a6565b6001836020036101000a038019825116818451168082178552505050505050905001838051906020019060200280838360005b838110156139195780820151818401526020810190506138fe565b50505050905001828152602001945050505050604051809103902090509392505050565b6000808210158015613953575082516014830111155b151561395e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8260140184015116905092915050565b60008060008060008060008061399a8c602961393d565b96508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156139ef575060008773ffffffffffffffffffffffffffffffffffffffff1614155b15156139fa57600080fd5b8673ffffffffffffffffffffffffffffffffffffffff16613a1c8d600061393d565b73ffffffffffffffffffffffffffffffffffffffff16141515613a3e57600080fd5b8b6028815181101515613a4d57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004955060009450600093505b8560ff168460ff161015613b1e57613ae78c8560ff16603402603d016120d5565b600190049250613b00838661430990919063ffffffff16565b9450600083131515613b1157600080fd5b8380600101945050613ac6565b613b2785610a49565b9150613b328261434a565b1515613b3d57600080fd5b613b588c6014336c010000000000000000000000000261440c565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1cda4688d6000604051602001526040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613c0b578082015181840152602081019050613bf0565b50505050905090810190601f168015613c385780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1515613c5657600080fd5b6102c65a03f11515613c6757600080fd5b505050604051805190509750600090505b8a518160ff161015613d28578a8160ff16815181101515613c9557fe5b90602001906020020151600560008a600019166000191681526020019081526020016000208260ff1661010081101515613ccb57fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550613d2160018260ff1661382b90919063ffffffff16565b9050613c78565b613d46888b8b613d4186346130e690919063ffffffff16565b6130ff565b87975050505050505050949350505050565b600080600080600280811115613d6a57fe5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613e0b57600080fd5b6102c65a03f11515613e1c57600080fd5b505050604051805190506002811115613e3157fe5b1415801515613e3f57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f6112d6889896000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1515613f1457600080fd5b6102c65a03f11515613f2557600080fd5b50505060405180519050945060008560010b12156140f95761400f6001600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec8b6000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613fe357600080fd5b6102c65a03f11515613ff457600080fd5b5050506040518051905060ff1661382b90919063ffffffff16565b9350600092505b8360ff168360ff1610801561404d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8560010b145b156140f8578673ffffffffffffffffffffffffffffffffffffffff16600560008a600019166000191681526020019081526020016000208460ff166101008110151561409557fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156140da578260ff1694505b6140f160018460ff1661382b90919063ffffffff16565b9250614016565b5b60008560010b1215151561410c57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b89876141558a61380f565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156141c557600080fd5b6102c65a03f115156141d657600080fd5b50505060066000896000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915060008273ffffffffffffffffffffffffffffffffffffffff1614156142f557600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156142d757600080fd5b6102c65a03f115156142e857600080fd5b5050506040518051905091505b6142ff82876143c8565b5050505050505050565b6000808284019050600083121580156143225750838112155b80614338575060008312801561433757508381125b5b151561434057fe5b8091505092915050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050509050919050565b60008082840190508381101515156143be57fe5b8091505092915050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561440857600080fd5b5050565b60008210158015614421575082516014830111155b151561442c57600080fd5b816014018301517fffffffffffffffffffffffff0000000000000000000000000000000000000000811690506c01000000000000000000000000820481179050808360140185015250505050565b6020604051908101604052806000815250905600a165627a7a72305820b7b7de135c9eef2f859422958047d56a4552bfdcdc9c55e27c6ec758d24886ff00290000000000000000000000008fc2e7f2498f1d06461ee2d547002611b801202b000000000000000000000000fcb4393e7faef06fab01c00d67c1895545aff3b8


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

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


   Swarm Source:
bzzr://b7b7de135c9eef2f859422958047d56a4552bfdcdc9c55e27c6ec758d24886ff
Block Age Transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward