ETH Price: $2,774.69 (+5.15%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Create Request A...118444032021-02-12 21:49:491453 days ago1613166589IN
0x62b37F05...1D97149B5
0.00166587 ETH0.02142907130
Create Request A...118444012021-02-12 21:49:221453 days ago1613166562IN
0x62b37F05...1D97149B5
0.00166587 ETH0.0164839100
Create Request A...108369162020-09-10 23:06:451608 days ago1599779205IN
0x62b37F05...1D97149B5
0.00224315 ETH0.02060487125
Create Request A...108221222020-09-08 16:33:151611 days ago1599582795IN
0x62b37F05...1D97149B5
0.00170435 ETH0.01813229110
Cancel Action107707942020-08-31 20:04:521619 days ago1598904292IN
0x62b37F05...1D97149B5
0 ETH0.01374945271
Create Request A...107702442020-08-31 18:12:271619 days ago1598897547IN
0x62b37F05...1D97149B5
0.00055666 ETH0.04978137302
Create Request A...106000452020-08-05 13:41:261645 days ago1596634886IN
0x62b37F05...1D97149B5
0.00219917 ETH0.0102200162
Create Request A...105950092020-08-04 18:48:261646 days ago1596566906IN
0x62b37F05...1D97149B5
0.00296888 ETH0.0066100440.1
Create Request A...105864142020-08-03 10:55:091647 days ago1596452109IN
0x62b37F05...1D97149B5
0.00809275 ETH0.0107679665
Create Request A...105674662020-07-31 12:57:211650 days ago1596200241IN
0x62b37F05...1D97149B5
0.00809275 ETH0.01557194
Payment Action105642712020-07-31 1:04:561650 days ago1596157496IN
0x62b37F05...1D97149B5
0 ETH0.0060352860
Payment Action105642112020-07-31 0:51:271650 days ago1596156687IN
0x62b37F05...1D97149B5
0 ETH0.00603660
Payment Action105642022020-07-31 0:49:321650 days ago1596156572IN
0x62b37F05...1D97149B5
0 ETH0.00603660
Payment Action105642002020-07-31 0:48:571650 days ago1596156537IN
0x62b37F05...1D97149B5
0 ETH0.0047559550
Payment Action105641992020-07-31 0:48:491650 days ago1596156529IN
0x62b37F05...1D97149B5
0 ETH0.0050350
Payment Action105641612020-07-31 0:40:271650 days ago1596156027IN
0x62b37F05...1D97149B5
0 ETH0.004653150
Payment Action105641302020-07-31 0:29:291650 days ago1596155369IN
0x62b37F05...1D97149B5
0 ETH0.0050350
Create Request A...105603012020-07-30 10:06:351651 days ago1596103595IN
0x62b37F05...1D97149B5
0.00076971 ETH0.0131871280
Create Request A...105496622020-07-28 18:37:231653 days ago1595961443IN
0x62b37F05...1D97149B5
0.00483818 ETH0.0105504664
Create Request A...105451352020-07-28 1:48:221653 days ago1595900902IN
0x62b37F05...1D97149B5
0.00809275 ETH0.0091113555
Create Request A...105445322020-07-27 23:38:291653 days ago1595893109IN
0x62b37F05...1D97149B5
0.00809275 ETH0.0101053261
Create Request A...105329612020-07-26 4:40:161655 days ago1595738416IN
0x62b37F05...1D97149B5
0.00809275 ETH0.0096083358
Create Request A...105307462020-07-25 20:24:551656 days ago1595708695IN
0x62b37F05...1D97149B5
0.00109958 ETH0.0067583941
Create Request A...105188112020-07-23 23:55:211657 days ago1595548521IN
0x62b37F05...1D97149B5
0.0037111 ETH0.0065935640
Payment Action105172222020-07-23 18:08:511658 days ago1595527731IN
0x62b37F05...1D97149B5
0 ETH0.01070213115
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
118444032021-02-12 21:49:491453 days ago1613166589
0x62b37F05...1D97149B5
0.00166587 ETH
118444012021-02-12 21:49:221453 days ago1613166562
0x62b37F05...1D97149B5
0.00166587 ETH
108369162020-09-10 23:06:451608 days ago1599779205
0x62b37F05...1D97149B5
0.00224315 ETH
108221222020-09-08 16:33:151611 days ago1599582795
0x62b37F05...1D97149B5
0.00170435 ETH
107702442020-08-31 18:12:271619 days ago1598897547
0x62b37F05...1D97149B5
0.00055666 ETH
106000452020-08-05 13:41:261645 days ago1596634886
0x62b37F05...1D97149B5
0.00219917 ETH
105950092020-08-04 18:48:261646 days ago1596566906
0x62b37F05...1D97149B5
0.00296888 ETH
105864142020-08-03 10:55:091647 days ago1596452109
0x62b37F05...1D97149B5
0.00809275 ETH
105674662020-07-31 12:57:211650 days ago1596200241
0x62b37F05...1D97149B5
0.00809275 ETH
105603012020-07-30 10:06:351651 days ago1596103595
0x62b37F05...1D97149B5
0.00076971 ETH
105496622020-07-28 18:37:231653 days ago1595961443
0x62b37F05...1D97149B5
0.00483818 ETH
105451352020-07-28 1:48:221653 days ago1595900902
0x62b37F05...1D97149B5
0.00809275 ETH
105445322020-07-27 23:38:291653 days ago1595893109
0x62b37F05...1D97149B5
0.00809275 ETH
105329612020-07-26 4:40:161655 days ago1595738416
0x62b37F05...1D97149B5
0.00809275 ETH
105307462020-07-25 20:24:551656 days ago1595708695
0x62b37F05...1D97149B5
0.00109958 ETH
105188112020-07-23 23:55:211657 days ago1595548521
0x62b37F05...1D97149B5
0.0037111 ETH
104272942020-07-09 19:58:491672 days ago1594324729
0x62b37F05...1D97149B5
0.00214419 ETH
104272522020-07-09 19:47:421672 days ago1594324062
0x62b37F05...1D97149B5
0.00643258 ETH
104150512020-07-07 22:29:111673 days ago1594160951
0x62b37F05...1D97149B5
0.0023916 ETH
104064092020-07-06 14:21:151675 days ago1594045275
0x62b37F05...1D97149B5
0.00137448 ETH
103793762020-07-02 10:05:521679 days ago1593684352
0x62b37F05...1D97149B5
0.00809275 ETH
103778362020-07-02 4:26:381679 days ago1593663998
0x62b37F05...1D97149B5
0.00809275 ETH
103745062020-07-01 16:07:391680 days ago1593619659
0x62b37F05...1D97149B5
0.00809275 ETH
103736732020-07-01 13:03:121680 days ago1593608592
0x62b37F05...1D97149B5
0.00137448 ETH
103736722020-07-01 13:03:101680 days ago1593608590
0x62b37F05...1D97149B5
0.00137448 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RequestERC20

Compiler Version
v0.4.18+commit.9cf6e910

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-11-18
*/

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

pragma solidity 0.4.18;

// From https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
/**
 * @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 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 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 RequestCollectInterface
 *
 * @dev RequestCollectInterface is a contract managing the fees for currency contracts
 */
contract RequestCollectInterface is Pausable {
    using SafeMath for uint256;

    uint256 public rateFeesNumerator;
    uint256 public rateFeesDenominator;
    uint256 public maxFees;

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

    /*
     *  Events 
     */
    event UpdateRateFees(uint256 rateFeesNumerator, uint256 rateFeesDenominator);
    event UpdateMaxFees(uint256 maxFees);

    /*
     * @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 RequestCollectInterface(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 the expected amount of fees in wei
     */  
    function collectEstimation(int256 _expectedAmount)
        public
        view
        returns(uint256)
    {
        if(_expectedAmount<0) return 0;

        uint256 computedCollect = uint256(_expectedAmount).mul(rateFeesNumerator);

        if(rateFeesDenominator != 0) {
            computedCollect = computedCollect.div(rateFeesDenominator);
        }

        return computedCollect < maxFees ? computedCollect : maxFees;
    }

    /*
     * @dev set the fees rate
     * NB: if the _rateFeesDenominator is 0, it will be treated as 1. (in other words, the computation of the fees will not use it)
     * @param _rateFeesNumerator        numerator rate
     * @param _rateFeesDenominator      denominator rate
     */  
    function setRateFees(uint256 _rateFeesNumerator, uint256 _rateFeesDenominator)
        external
        onlyOwner
    {
        rateFeesNumerator = _rateFeesNumerator;
        rateFeesDenominator = _rateFeesDenominator;
        UpdateRateFees(rateFeesNumerator, rateFeesDenominator);
    }

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

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

}

/**
 * @title RequestCurrencyContractInterface
 *
 * @dev RequestCurrencyContractInterface 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 or withdraw funds.
 *
 * @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 RequestCurrencyContractInterface is RequestCollectInterface {
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using SafeMathUint8 for uint8;

    // RequestCore object
    RequestCore public requestCore;

    /*
     * @dev Constructor
     * @param _requestCoreAddress Request Core address
     */
    function RequestCurrencyContractInterface(address _requestCoreAddress, address _addressBurner) 
        RequestCollectInterface(_addressBurner)
        public
    {
        requestCore=RequestCore(_requestCoreAddress);
    }

    /*
     * @dev Base function for request creation
     *
     * @dev msg.sender will be the creator
     *
     * @param _payer Entity expected to pay
     * @param _payeesIdAddress array of payees address (the index 0 will be the payee - must be msg.sender - the others are subPayees)
     * @param _expectedAmounts array of Expected amount to be received by each payees
     * @param _data Hash linking to additional data on the Request stored on IPFS
     *
     * @return Returns the id of the request and the sum of the expected amounts
     */
    function createCoreRequestInternal(
        address     _payer,
        address[]   _payeesIdAddress,
        int256[]    _expectedAmounts,
        string      _data)
        internal
        whenNotPaused
        returns(bytes32 requestId, int256 totalExpectedAmounts)
    {
        totalExpectedAmounts = 0;
        for (uint8 i = 0; i < _expectedAmounts.length; i = i.add(1))
        {
            // all expected amounts must be positive
            require(_expectedAmounts[i]>=0);
            // compute the total expected amount of the request
            totalExpectedAmounts = totalExpectedAmounts.add(_expectedAmounts[i]);
        }

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

    /*
     * @dev Function to accept a request
     *
     * @dev msg.sender must be _payer
     *
     * @param _requestId id of the request
     */
    function acceptAction(bytes32 _requestId)
        public
        whenNotPaused
        onlyRequestPayer(_requestId)
    {
        // only a created request can be accepted
        require(requestCore.getState(_requestId)==RequestCore.State.Created);

        // declare the acceptation in the core
        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 cancelAction(bytes32 _requestId)
        public
        whenNotPaused
    {
        // payer can cancel if request is just created
        // payee can cancel when request is not canceled yet
        require((requestCore.getPayer(_requestId)==msg.sender && requestCore.getState(_requestId)==RequestCore.State.Created)
                || (requestCore.getPayeeAddress(_requestId,0)==msg.sender && requestCore.getState(_requestId)!=RequestCore.State.Canceled));

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

        // declare the cancellation in the core
        requestCore.cancel(_requestId);
    }


    /*
     * @dev Function to declare additionals
     *
     * @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 to declare (index 0 is for main payee)
     */
    function additionalAction(bytes32 _requestId, uint256[] _additionalAmounts)
        public
        whenNotPaused
        onlyRequestPayer(_requestId)
    {

        // impossible to make additional if request is canceled
        require(requestCore.getState(_requestId)!=RequestCore.State.Canceled);

        // impossible to declare more additionals than the number of payees
        require(_additionalAmounts.length <= requestCore.getSubPayeesCount(_requestId).add(1));

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

    /*
     * @dev Function to declare subtracts
     *
     * @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 to declare (index 0 is for main payee)
     */
    function subtractAction(bytes32 _requestId, uint256[] _subtractAmounts)
        public
        whenNotPaused
        onlyRequestPayee(_requestId)
    {
        // impossible to make subtracts if request is canceled
        require(requestCore.getState(_requestId)!=RequestCore.State.Canceled);

        // impossible to declare more subtracts than the number of payees
        require(_subtractAmounts.length <= requestCore.getSubPayeesCount(_requestId).add(1));

        for(uint8 i = 0; i < _subtractAmounts.length; i = i.add(1)) {
            // no need to declare a zero as subtracts 
            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 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 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);
        _;
    }
}


/**
 * @title RequestERC20
 *
 * @dev RequestERC20 is the currency contract managing the request in ERC20 token
 * @dev The contract can be paused. In this case, nobody can create Requests anymore but people can still interact with them or withdraw funds.
 *
 * @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 RequestERC20 is RequestCurrencyContractInterface {
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using SafeMathUint8 for uint8;

    // 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;

    // token address
    ERC20 public erc20Token;

    /*
     * @dev Constructor
     * @param _requestCoreAddress Request Core address
     * @param _requestBurnerAddress Request Burner contract address
     * @param _erc20Token ERC20 token contract handled by this currency contract
     */
    function RequestERC20(address _requestCoreAddress, address _requestBurnerAddress, ERC20 _erc20Token) 
        RequestCurrencyContractInterface(_requestCoreAddress, _requestBurnerAddress)
        public
    {
        erc20Token = _erc20Token;
    }

    /*
     * @dev Function to create a request as payee
     *
     * @dev msg.sender must be the main payee
     * @dev if _payeesPaymentAddress.length > _payeesIdAddress.length, the extra addresses will be stored but never used
     *
     * @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 createRequestAsPayeeAction(
        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);

        int256 totalExpectedAmounts;
        (requestId, totalExpectedAmounts) = createCoreRequestInternal(_payer, _payeesIdAddress, _expectedAmounts, _data);
        
        // compute and send fees
        uint256 fees = collectEstimation(totalExpectedAmounts);
        require(fees == msg.value && collectForREQBurning(fees));

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

        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 createRequestAsPayerAction(
        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);

        int256 totalExpectedAmounts;
        (requestId, totalExpectedAmounts) = createCoreRequestInternal(msg.sender, _payeesIdAddress, _expectedAmounts, _data);

        // set payment address for payer
        if(_payerRefundAddress != 0) {
            payerRefundAddress[requestId] = _payerRefundAddress;
        }

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

        return requestId;
    }

    /*
     * @dev Function to broadcast and accept an offchain signed request (the broadcaster can also pays and makes additionals )
     *
     * @dev msg.sender will be the _payer
     * @dev only the _payer can make additionals
     * @dev if _payeesPaymentAddress.length > _requestData.payeesIdAddress.length, the extra addresses will be stored but never used
     *
     * @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 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 broadcastSignedRequestAsPayerAction(
        bytes       _requestData, // gather data to avoid "stack too deep"
        address[]   _payeesPaymentAddress,
        uint256[]   _payeeAmounts,
        uint256[]   _additionals,
        uint256     _expirationDate,
        bytes       _signature)
        external
        payable
        whenNotPaused
        returns(bytes32 requestId)
    {
        // check expiration date
        require(_expirationDate >= block.timestamp);

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

        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]
            int256 expectedAmountTemp = int256(extractBytes32(_requestData, uint256(i).mul(52).add(61)));
            // compute the total expected amount of the request
            totalExpectedAmounts = totalExpectedAmounts.add(expectedAmountTemp);
            // all expected amount must be positive
            require(expectedAmountTemp>0);
        }

        // compute and send fees
        uint256 fees = collectEstimation(totalExpectedAmounts);
        // check fees has been well received
        require(fees == msg.value && 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, totalExpectedAmounts);

        return requestId;
    }

    /*
     * @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 _payeeAmountsSum total of amount token send for this transaction
     *
     */ 
    function acceptAndPay(
        bytes32 _requestId,
        uint256[] _payeeAmounts,
        uint256[] _additionals,
        int256 _payeeAmountsSum)
        internal
    {
        acceptAction(_requestId);
        
        additionalAction(_requestId, _additionals);

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

    /*
     * @dev Function to pay a request in ERC20 token
     *
     * @dev msg.sender must have a balance of the token higher or equal to the sum of _payeeAmounts
     * @dev msg.sender must have approved an amount of the token higher or equal to the sum of _payeeAmounts to the current contract
     * @dev the request will be automatically accepted if msg.sender==payer. 
     *
     * @param _requestId id of the request
     * @param _payeeAmounts Amount to pay to payees (sum must be equal to msg.value) in wei
     * @param _additionalAmounts amount of additionals per payee in wei to declare
     */
    function paymentAction(
        bytes32 _requestId,
        uint256[] _payeeAmounts,
        uint256[] _additionalAmounts)
        external
        whenNotPaused
    {
        // automatically accept request if request is created and msg.sender is payer
        if (requestCore.getState(_requestId)==RequestCore.State.Created && msg.sender == requestCore.getPayer(_requestId)) {
            acceptAction(_requestId);
        }

        if (_additionalAmounts.length != 0) {
            additionalAction(_requestId, _additionalAmounts);
        }

        paymentInternal(_requestId, _payeeAmounts);
    }


    /*
     * @dev Function to pay back in ERC20 token a request to the payees
     *
     * @dev msg.sender must have a balance of the token higher or equal to _amountToRefund
     * @dev msg.sender must have approved an amount of the token higher or equal to _amountToRefund to the current contract
     * @dev msg.sender must be one of the payees or one of the payees payment address
     * @dev the request must be created or accepted
     *
     * @param _requestId id of the request
     */
    function refundAction(bytes32 _requestId, uint256 _amountToRefund)
        external
        whenNotPaused
    {
        refundInternal(_requestId, msg.sender, _amountToRefund);
    }


    // ---- INTERNAL FUNCTIONS ----------------------------------------------------------------
    /*
     * @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)
     */
    function paymentInternal(
        bytes32     _requestId,
        uint256[]   _payeeAmounts)
        internal
    {
        require(requestCore.getState(_requestId)!=RequestCore.State.Canceled);

        // we cannot have more amounts declared than actual payees
        require(_payeeAmounts.length <= requestCore.getSubPayeesCount(_requestId).add(1));

        for(uint8 i = 0; i < _payeeAmounts.length; i = i.add(1)) {
            if(_payeeAmounts[i] != 0) {
                // 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 token need to be sent
                fundOrderInternal(msg.sender, addressToPay, _payeeAmounts[i]);
            }
        }
    }


    /*
     * @dev Function internal to manage refund declaration
     *
     * @param _requestId id of the request
     * @param _address address from where the refund has been done
     * @param _amount amount of the refund in ERC20 token to declare
     */
    function refundInternal(
        bytes32 _requestId,
        address _address,
        uint256 _amount)
        internal
    {
        require(requestCore.getState(_requestId)!=RequestCore.State.Canceled);

        // Check if the _address is a payeesId
        int16 payeeIndex = requestCore.getPayeeIndex(_requestId, _address);

        // get the number of payees
        uint8 payeesCount = requestCore.getSubPayeesCount(_requestId).add(1);

        if(payeeIndex < 0) {
            // 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] == _address) {
                    // get the payeeIndex
                    payeeIndex = int16(i);
                }
            }
        }
        // the address must be found somewhere
        require(payeeIndex >= 0); 

        // useless (subPayee size <256): require(payeeIndex < 265);
        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(_address, addressToPay, _amount);
    }

    /*
     * @dev Function internal to manage fund mouvement
     *
     * @param _from address where the token will get from
     * @param _recipient address where the token has to be sent to
     * @param _amount amount in ERC20 token to send
     */
    function fundOrderInternal(
        address _from,
        address _recipient,
        uint256 _amount)
        internal
    {   
        require(erc20Token.transferFrom(_from, _recipient, _amount));
    }
    // -----------------------------------------------------------------------------

    /*
     * @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);
    }

    /*
     * @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(
        bytes       _requestData,
        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 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 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)
        }
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"_expectedAmount","type":"int256"}],"name":"collectEstimation","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rateFeesNumerator","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"},{"name":"_payeeAmounts","type":"uint256[]"},{"name":"_additionalAmounts","type":"uint256[]"}],"name":"paymentAction","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"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":"_requestData","type":"bytes"},{"name":"_payeesPaymentAddress","type":"address[]"},{"name":"_payeeAmounts","type":"uint256[]"},{"name":"_additionals","type":"uint256[]"},{"name":"_expirationDate","type":"uint256"},{"name":"_signature","type":"bytes"}],"name":"broadcastSignedRequestAsPayerAction","outputs":[{"name":"requestId","type":"bytes32"}],"payable":true,"stateMutability":"payable","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":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":"createRequestAsPayeeAction","outputs":[{"name":"requestId","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"requestCore","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rateFeesDenominator","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"}],"name":"cancelAction","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"erc20Token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"payerRefundAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"}],"name":"acceptAction","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"","type":"bytes32"},{"name":"","type":"uint256"}],"name":"payeesPaymentAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_rateFeesNumerator","type":"uint256"},{"name":"_rateFeesDenominator","type":"uint256"}],"name":"setRateFees","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"createRequestAsPayerAction","outputs":[{"name":"requestId","type":"bytes32"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_newMaxFees","type":"uint256"}],"name":"setMaxCollectable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"requestBurnerContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxFees","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requestId","type":"bytes32"},{"name":"_amountToRefund","type":"uint256"}],"name":"refundAction","outputs":[],"payable":false,"stateMutability":"nonpayable","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"},{"name":"_erc20Token","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"rateFeesNumerator","type":"uint256"},{"indexed":false,"name":"rateFeesDenominator","type":"uint256"}],"name":"UpdateRateFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"maxFees","type":"uint256"}],"name":"UpdateMaxFees","type":"event"},{"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"}]

606060405260008060146101000a81548160ff021916908315150217905550341561002957600080fd5b60405160608061458b83398101604052808051906020019091908051906020019091908051906020019091905050828280336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050614419806101726000396000f300606060405260043610610175576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318954b3e1461017a578063263f6a42146101b157806327dd16e5146101da578063289b45fb146102295780633f4ba83a146102905780634b0a0d04146102a557806350faaeff146103a6578063524eb29c1461043e5780635c975abb14610477578063629873b2146104a45780636c4fbaa41461055d57806375c268f3146105b2578063781cc3d3146105db5780638163681e1461060257806383565cc7146106865780638456cb59146106ed5780638a13eea7146107025780638da5cb5b14610757578063a460b89c146107ac578063a9de504514610813578063b1e05e8a1461083a578063b2f35bdd146108bc578063c60116331461092c578063d5d067b014610958578063d7b8de0014610a06578063e40e845714610a29578063e83e34b114610a7e578063e9187ef414610aa7578063f2fde38b14610ad7575b600080fd5b341561018557600080fd5b61019b6004808035906020019091905050610b10565b6040518082815260200191505060405180910390f35b34156101bc57600080fd5b6101c4610b7c565b6040518082815260200191505060405180910390f35b34156101e557600080fd5b61022760048080356000191690602001909190803590602001908201803590602001919091929080359060200190820180359060200191909192905050610b82565b005b341561023457600080fd5b61028e60048080356000191690602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610dfb565b005b341561029b57600080fd5b6102a3611318565b005b34156102b057600080fd5b61038c600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001909190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506113d6565b604051808215151515815260200191505060405180910390f35b6104206004808035906020019082018035906020019190919290803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803590602001909190803590602001908201803590602001919091929050506114d4565b60405180826000191660001916815260200191505060405180910390f35b341561044957600080fd5b610475600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611686565b005b341561048257600080fd5b61048a611725565b604051808215151515815260200191505060405180910390f35b61053f600480803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190820180359060200191909192905050611738565b60405180826000191660001916815260200191505060405180910390f35b341561056857600080fd5b610570611a41565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105bd57600080fd5b6105c5611a67565b6040518082815260200191505060405180910390f35b34156105e657600080fd5b610600600480803560001916906020019091905050611a6d565b005b341561060d57600080fd5b61066c600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff169060200190919080356000191690602001909190803560001916906020019091905050611faa565b604051808215151515815260200191505060405180910390f35b341561069157600080fd5b6106eb600480803560001916906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919050506120b1565b005b34156106f857600080fd5b6107006124c6565b005b341561070d57600080fd5b610715612586565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561076257600080fd5b61076a6125ac565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156107b757600080fd5b6107d16004808035600019169060200190919050506125d1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561081e57600080fd5b610838600480803560001916906020019091905050612604565b005b341561084557600080fd5b61089e600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190919050506128a6565b60405180826000191660001916815260200191505060405180910390f35b34156108c757600080fd5b6108ea6004808035600019169060200190919080359060200190919050506128d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561093757600080fd5b610956600480803590602001909190803590602001909190505061291b565b005b6109e860048080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190820180359060200191909192908035906020019082018035906020019190919290803590602001908201803590602001919091929050506129cb565b60405180826000191660001916815260200191505060405180910390f35b3415610a1157600080fd5b610a276004808035906020019091905050612c3a565b005b3415610a3457600080fd5b610a3c612cd8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3415610a8957600080fd5b610a91612cfe565b6040518082815260200191505060405180910390f35b3415610ab257600080fd5b610ad5600480803560001916906020019091908035906020019091905050612d04565b005b3415610ae257600080fd5b610b0e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612d2f565b005b6000806000831215610b255760009150610b76565b610b3a60015484612e8490919063ffffffff16565b90506000600254141515610b6057610b5d60025482612eb790919063ffffffff16565b90505b6003548110610b7157600354610b73565b805b91505b50919050565b60015481565b600060149054906101000a900460ff16151515610b9e57600080fd5b60006002811115610bab57fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610c4c57600080fd5b6102c65a03f11515610c5d57600080fd5b505050604051805190506002811115610c7257fe5b148015610d655750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610d1b57600080fd5b6102c65a03f11515610d2c57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15610d7457610d7385612604565b5b600082829050141515610dbb57610dba858383808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506120b1565b5b610df485858580806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050612ed2565b5050505050565b60008060149054906101000a900460ff16151515610e1857600080fd5b823373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0183600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b1515610edc57600080fd5b6102c65a03f11515610eed57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16141515610f1957600080fd5b600280811115610f2557fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610fc657600080fd5b6102c65a03f11515610fd757600080fd5b505050604051805190506002811115610fec57fe5b14151515610ff957600080fd5b6110cb6001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561109f57600080fd5b6102c65a03f115156110b057600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b60ff168351111515156110dd57600080fd5b600091505b82518260ff161015611312576000838360ff1681518110151561110157fe5b906020019060200201511415156112f457611135838360ff1681518110151561112657fe5b906020019060200201516133ae565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ad8d87586856000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b15156111e457600080fd5b6102c65a03f115156111f557600080fd5b505050604051805190501215151561120c57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce165894858461126f878760ff1681518110151561126057fe5b906020019060200201516133ae565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156112df57600080fd5b6102c65a03f115156112f057600080fd5b5050505b61130b60018360ff1661338a90919063ffffffff16565b91506110e2565b50505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561137357600080fd5b600060149054906101000a900460ff16151561138e57600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b60008060008060006113e98989896133ca565b93508560408151811015156113fa57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090049250601b8360ff161061147b5782611493565b611492601b8460ff1661338a90919063ffffffff16565b5b92506114a08660006128a6565b91506114ad8660206128a6565b90506114c66114bd8a60006134b8565b85858585611faa565b945050505050949350505050565b60008060149054906101000a900460ff161515156114f157600080fd5b42841015151561150057600080fd5b61159f8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508686868080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050506113d6565b15156115aa57600080fd5b6116758c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508a8a808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508989808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506134fe565b90509b9a5050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116e157600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060149054906101000a900460ff1681565b600080600080600060149054906101000a900460ff1615151561175a57600080fd5b8d8d6000818110151561176957fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156117ec57508773ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b801561180f575060008873ffffffffffffffffffffffffffffffffffffffff1614155b151561181a57600080fd5b6118b6888f8f808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508c8c8080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505089898080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050506138ec565b80945081955050506118c783610b10565b915034821480156118dd57506118dc82613bb7565b5b15156118e857600080fd5b600090505b8b8b90508160ff1610156119b2578b8b8260ff16818110151561190c57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff166006600086600019166000191681526020019081526020016000208260ff166101008110151561195557fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506119ab60018260ff1661338a90919063ffffffff16565b90506118ed565b60008773ffffffffffffffffffffffffffffffffffffffff16141515611a2d578660076000866000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b8393505050509a9950505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b600060149054906101000a900460ff16151515611a8957600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611b4157600080fd5b6102c65a03f11515611b5257600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015611c50575060006002811115611b8757fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611c2857600080fd5b6102c65a03f11515611c3957600080fd5b505050604051805190506002811115611c4e57fe5b145b80611e2957503373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0183600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b1515611d1957600080fd5b6102c65a03f11515611d2a57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015611e285750600280811115611d5e57fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611dff57600080fd5b6102c65a03f11515611e1057600080fd5b505050604051805190506002811115611e2557fe5b14155b5b1515611e3457600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166307550f0a826000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611ed557600080fd5b6102c65a03f11515611ee657600080fd5b505050604051805190501515611efb57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c4d252f5826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b1515611f9357600080fd5b6102c65a03f11515611fa457600080fd5b50505050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561206f57600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614905095945050505050565b60008060149054906101000a900460ff161515156120ce57600080fd5b823373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561218757600080fd5b6102c65a03f1151561219857600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff161415156121c457600080fd5b6002808111156121d057fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561227157600080fd5b6102c65a03f1151561228257600080fd5b50505060405180519050600281111561229757fe5b141515156122a457600080fd5b6123766001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561234a57600080fd5b6102c65a03f1151561235b57600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b60ff1683511115151561238857600080fd5b600091505b82518260ff1610156124c0576000838360ff168151811015156123ac57fe5b906020019060200201511415156124a257600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce1658948584612420878760ff1681518110151561241157fe5b906020019060200201516133ae565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b151561248d57600080fd5b6102c65a03f1151561249e57600080fd5b5050505b6124b960018360ff1661338a90919063ffffffff16565b915061238d565b50505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561252157600080fd5b600060149054906101000a900460ff1615151561253d57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60076020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1615151561262057600080fd5b803373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156126d957600080fd5b6102c65a03f115156126ea57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff1614151561271657600080fd5b6000600281111561272357fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d846000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156127c457600080fd5b6102c65a03f115156127d557600080fd5b5050506040518051905060028111156127ea57fe5b1415156127f657600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b151561288e57600080fd5b6102c65a03f1151561289f57600080fd5b5050505050565b60008082101580156128bc575082516020830111155b15156128c757600080fd5b81602001830151905092915050565b600660205281600052604060002081610100811015156128f257fe5b016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561297657600080fd5b81600181905550806002819055507f74001f9764398216f36f3f1c1e3271c5a965a45dfa33bb132c699ed6e171ab1f600154600254604051808381526020018281526020019250505060405180910390a15050565b600080600060149054906101000a900460ff161515156129ea57600080fd5b8c8c600081811015156129f957fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015612a93575060008d8d60008181101515612a5d57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b1515612a9e57600080fd5b612b3a338e8e808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508d8d8080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505087878080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050506138ec565b809250819350505060008973ffffffffffffffffffffffffffffffffffffffff16141515612bbd578860076000846000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b612c278289898080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505088888080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505084613c17565b819150509b9a5050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612c9557600080fd5b806003819055507f6b1c63dd26ab451d994d7f5c0b5b6e9425a2da8206cb849a5c33e34a68b011686003546040518082815260200191505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b600060149054906101000a900460ff16151515612d2057600080fd5b612d2b823383613c44565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612d8a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612dc657600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008082840290506000841480612ea55750828482811515612ea257fe5b04145b1515612ead57fe5b8091505092915050565b6000808284811515612ec557fe5b0490508091505092915050565b600080600280811115612ee157fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515612f8257600080fd5b6102c65a03f11515612f9357600080fd5b505050604051805190506002811115612fa857fe5b14151515612fb557600080fd5b6130876001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561305b57600080fd5b6102c65a03f1151561306c57600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b60ff1683511115151561309957600080fd5b600091505b82518260ff161015613384576000838360ff168151811015156130bd57fe5b9060200190602002015114151561336657600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b8584613131878760ff1681518110151561312257fe5b906020019060200201516133ae565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b151561319e57600080fd5b6102c65a03f115156131af57600080fd5b50505060006006600086600019166000191681526020019081526020016000208360ff16610100811015156131e057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156132ef57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0185846000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b15156132cd57600080fd5b6102c65a03f115156132de57600080fd5b505050604051805190509050613340565b6006600085600019166000191681526020019081526020016000208260ff166101008110151561331b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b6133653382858560ff1681518110151561335657fe5b906020019060200201516141f4565b5b61337d60018360ff1661338a90919063ffffffff16565b915061309e565b50505050565b60008082840190508360ff168160ff16101515156133a457fe5b8091505092915050565b600080829050600081121515156133c157fe5b80915050919050565b600030848484604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140184805190602001908083835b6020831015156134465780518252602082019150602081019050602083039250613421565b6001836020036101000a038019825116818451168082178552505050505050905001838051906020019060200280838360005b83811015613494578082015181840152602081019050613479565b50505050905001828152602001945050505050604051809103902090509392505050565b60008082101580156134ce575082516014830111155b15156134d957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8260140184015116905092915050565b6000806000806000806000806135158c60296134b8565b96508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415801561356a575060008773ffffffffffffffffffffffffffffffffffffffff1614155b151561357557600080fd5b8673ffffffffffffffffffffffffffffffffffffffff166135978d60006134b8565b73ffffffffffffffffffffffffffffffffffffffff161415156135b957600080fd5b8b60288151811015156135c857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004955060009450600093505b8560ff168460ff1610156136b9576136828c61367d603d61366f60348960ff16612e8490919063ffffffff16565b61432090919063ffffffff16565b6128a6565b60019004925061369b838661433e90919063ffffffff16565b94506000831315156136ac57600080fd5b8380600101945050613641565b6136c285610b10565b915034821480156136d857506136d782613bb7565b5b15156136e357600080fd5b6136fe8c6014336c010000000000000000000000000261437f565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1cda4688d6000604051602001526040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137b1578082015181840152602081019050613796565b50505050905090810190601f1680156137de5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15156137fc57600080fd5b6102c65a03f1151561380d57600080fd5b505050604051805190509750600090505b8a518160ff1610156138ce578a8160ff1681518110151561383b57fe5b90602001906020020151600660008a600019166000191681526020019081526020016000208260ff166101008110151561387157fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506138c760018260ff1661338a90919063ffffffff16565b905061381e565b6138da888b8b88613c17565b87975050505050505050949350505050565b60008060008060149054906101000a900460ff1615151561390c57600080fd5b60009150600090505b84518160ff161015613998576000858260ff1681518110151561393457fe5b906020019060200201511215151561394b57600080fd5b613978858260ff1681518110151561395f57fe5b906020019060200201518361433e90919063ffffffff16565b915061399160018260ff1661338a90919063ffffffff16565b9050613915565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663431072903388888b896000604051602001526040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001848103845288818151815260200191508051906020019060200280838360005b83811015613abe578082015181840152602081019050613aa3565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015613b00578082015181840152602081019050613ae5565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015613b3f578082015181840152602081019050613b24565b50505050905090810190601f168015613b6c5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1515613b9057600080fd5b6102c65a03f11515613ba157600080fd5b5050506040518051905092505094509492505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050509050919050565b613c2084612604565b613c2a84836120b1565b6000811315613c3e57613c3d8484612ed2565b5b50505050565b600080600080600280811115613c5657fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613cf757600080fd5b6102c65a03f11515613d0857600080fd5b505050604051805190506002811115613d1d57fe5b14151515613d2a57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f6112d6888886000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1515613dff57600080fd5b6102c65a03f11515613e1057600080fd5b505050604051805190509350613eee6001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec8a6000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613ec257600080fd5b6102c65a03f11515613ed357600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b925060008460010b1215613fe457600091505b8260ff168260ff16108015613f3857507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8460010b145b15613fe3578573ffffffffffffffffffffffffffffffffffffffff166006600089600019166000191681526020019081526020016000208360ff1661010081101515613f8057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613fc5578160ff1693505b613fdc60018360ff1661338a90919063ffffffff16565b9150613f01565b5b60008460010b12151515613ff757600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b8886614040896133ae565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156140b057600080fd5b6102c65a03f115156140c157600080fd5b50505060076000886000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1614156141e057600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70886000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156141c257600080fd5b6102c65a03f115156141d357600080fd5b5050506040518051905090505b6141eb8682876141f4565b50505050505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8484846000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15156142f557600080fd5b6102c65a03f1151561430657600080fd5b50505060405180519050151561431b57600080fd5b505050565b600080828401905083811015151561433457fe5b8091505092915050565b6000808284019050600083121580156143575750838112155b8061436d575060008312801561436c57508381125b5b151561437557fe5b8091505092915050565b60008210158015614394575082516014830111155b151561439f57600080fd5b816014018301517fffffffffffffffffffffffff0000000000000000000000000000000000000000811690506c010000000000000000000000008204811790508083601401850152505050505600a165627a7a723058208f1fd49f36fd856358b7ad669338b622084ba89f01f4ed62a8bea3e27656d8880029000000000000000000000000db600fda54568a35b78565b5257125bebc51eb270000000000000000000000007b3c4d90e8af6030d66c07f8f815f9505e379d6f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f

Deployed Bytecode

0x606060405260043610610175576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806318954b3e1461017a578063263f6a42146101b157806327dd16e5146101da578063289b45fb146102295780633f4ba83a146102905780634b0a0d04146102a557806350faaeff146103a6578063524eb29c1461043e5780635c975abb14610477578063629873b2146104a45780636c4fbaa41461055d57806375c268f3146105b2578063781cc3d3146105db5780638163681e1461060257806383565cc7146106865780638456cb59146106ed5780638a13eea7146107025780638da5cb5b14610757578063a460b89c146107ac578063a9de504514610813578063b1e05e8a1461083a578063b2f35bdd146108bc578063c60116331461092c578063d5d067b014610958578063d7b8de0014610a06578063e40e845714610a29578063e83e34b114610a7e578063e9187ef414610aa7578063f2fde38b14610ad7575b600080fd5b341561018557600080fd5b61019b6004808035906020019091905050610b10565b6040518082815260200191505060405180910390f35b34156101bc57600080fd5b6101c4610b7c565b6040518082815260200191505060405180910390f35b34156101e557600080fd5b61022760048080356000191690602001909190803590602001908201803590602001919091929080359060200190820180359060200191909192905050610b82565b005b341561023457600080fd5b61028e60048080356000191690602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610dfb565b005b341561029b57600080fd5b6102a3611318565b005b34156102b057600080fd5b61038c600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001909190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506113d6565b604051808215151515815260200191505060405180910390f35b6104206004808035906020019082018035906020019190919290803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803590602001909190803590602001908201803590602001919091929050506114d4565b60405180826000191660001916815260200191505060405180910390f35b341561044957600080fd5b610475600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611686565b005b341561048257600080fd5b61048a611725565b604051808215151515815260200191505060405180910390f35b61053f600480803590602001908201803590602001919091929080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190820180359060200191909192905050611738565b60405180826000191660001916815260200191505060405180910390f35b341561056857600080fd5b610570611a41565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105bd57600080fd5b6105c5611a67565b6040518082815260200191505060405180910390f35b34156105e657600080fd5b610600600480803560001916906020019091905050611a6d565b005b341561060d57600080fd5b61066c600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff169060200190919080356000191690602001909190803560001916906020019091905050611faa565b604051808215151515815260200191505060405180910390f35b341561069157600080fd5b6106eb600480803560001916906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919050506120b1565b005b34156106f857600080fd5b6107006124c6565b005b341561070d57600080fd5b610715612586565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561076257600080fd5b61076a6125ac565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156107b757600080fd5b6107d16004808035600019169060200190919050506125d1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561081e57600080fd5b610838600480803560001916906020019091905050612604565b005b341561084557600080fd5b61089e600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190919050506128a6565b60405180826000191660001916815260200191505060405180910390f35b34156108c757600080fd5b6108ea6004808035600019169060200190919080359060200190919050506128d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561093757600080fd5b610956600480803590602001909190803590602001909190505061291b565b005b6109e860048080359060200190820180359060200191909192908035906020019082018035906020019190919290803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190820180359060200191909192908035906020019082018035906020019190919290803590602001908201803590602001919091929050506129cb565b60405180826000191660001916815260200191505060405180910390f35b3415610a1157600080fd5b610a276004808035906020019091905050612c3a565b005b3415610a3457600080fd5b610a3c612cd8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3415610a8957600080fd5b610a91612cfe565b6040518082815260200191505060405180910390f35b3415610ab257600080fd5b610ad5600480803560001916906020019091908035906020019091905050612d04565b005b3415610ae257600080fd5b610b0e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612d2f565b005b6000806000831215610b255760009150610b76565b610b3a60015484612e8490919063ffffffff16565b90506000600254141515610b6057610b5d60025482612eb790919063ffffffff16565b90505b6003548110610b7157600354610b73565b805b91505b50919050565b60015481565b600060149054906101000a900460ff16151515610b9e57600080fd5b60006002811115610bab57fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610c4c57600080fd5b6102c65a03f11515610c5d57600080fd5b505050604051805190506002811115610c7257fe5b148015610d655750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610d1b57600080fd5b6102c65a03f11515610d2c57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15610d7457610d7385612604565b5b600082829050141515610dbb57610dba858383808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506120b1565b5b610df485858580806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050612ed2565b5050505050565b60008060149054906101000a900460ff16151515610e1857600080fd5b823373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0183600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b1515610edc57600080fd5b6102c65a03f11515610eed57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16141515610f1957600080fd5b600280811115610f2557fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515610fc657600080fd5b6102c65a03f11515610fd757600080fd5b505050604051805190506002811115610fec57fe5b14151515610ff957600080fd5b6110cb6001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561109f57600080fd5b6102c65a03f115156110b057600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b60ff168351111515156110dd57600080fd5b600091505b82518260ff161015611312576000838360ff1681518110151561110157fe5b906020019060200201511415156112f457611135838360ff1681518110151561112657fe5b906020019060200201516133ae565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ad8d87586856000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b15156111e457600080fd5b6102c65a03f115156111f557600080fd5b505050604051805190501215151561120c57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce165894858461126f878760ff1681518110151561126057fe5b906020019060200201516133ae565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156112df57600080fd5b6102c65a03f115156112f057600080fd5b5050505b61130b60018360ff1661338a90919063ffffffff16565b91506110e2565b50505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561137357600080fd5b600060149054906101000a900460ff16151561138e57600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b60008060008060006113e98989896133ca565b93508560408151811015156113fa57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090049250601b8360ff161061147b5782611493565b611492601b8460ff1661338a90919063ffffffff16565b5b92506114a08660006128a6565b91506114ad8660206128a6565b90506114c66114bd8a60006134b8565b85858585611faa565b945050505050949350505050565b60008060149054906101000a900460ff161515156114f157600080fd5b42841015151561150057600080fd5b61159f8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508686868080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050506113d6565b15156115aa57600080fd5b6116758c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508a8a808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508989808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050506134fe565b90509b9a5050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116e157600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060149054906101000a900460ff1681565b600080600080600060149054906101000a900460ff1615151561175a57600080fd5b8d8d6000818110151561176957fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156117ec57508773ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b801561180f575060008873ffffffffffffffffffffffffffffffffffffffff1614155b151561181a57600080fd5b6118b6888f8f808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508c8c8080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505089898080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050506138ec565b80945081955050506118c783610b10565b915034821480156118dd57506118dc82613bb7565b5b15156118e857600080fd5b600090505b8b8b90508160ff1610156119b2578b8b8260ff16818110151561190c57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff166006600086600019166000191681526020019081526020016000208260ff166101008110151561195557fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506119ab60018260ff1661338a90919063ffffffff16565b90506118ed565b60008773ffffffffffffffffffffffffffffffffffffffff16141515611a2d578660076000866000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b8393505050509a9950505050505050505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b600060149054906101000a900460ff16151515611a8957600080fd5b3373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611b4157600080fd5b6102c65a03f11515611b5257600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015611c50575060006002811115611b8757fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611c2857600080fd5b6102c65a03f11515611c3957600080fd5b505050604051805190506002811115611c4e57fe5b145b80611e2957503373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0183600080604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff16815260200192505050602060405180830381600087803b1515611d1957600080fd5b6102c65a03f11515611d2a57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff16148015611e285750600280811115611d5e57fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611dff57600080fd5b6102c65a03f11515611e1057600080fd5b505050604051805190506002811115611e2557fe5b14155b5b1515611e3457600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166307550f0a826000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515611ed557600080fd5b6102c65a03f11515611ee657600080fd5b505050604051805190501515611efb57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c4d252f5826040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b1515611f9357600080fd5b6102c65a03f11515611fa457600080fd5b50505050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561206f57600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614905095945050505050565b60008060149054906101000a900460ff161515156120ce57600080fd5b823373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561218757600080fd5b6102c65a03f1151561219857600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff161415156121c457600080fd5b6002808111156121d057fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561227157600080fd5b6102c65a03f1151561228257600080fd5b50505060405180519050600281111561229757fe5b141515156122a457600080fd5b6123766001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561234a57600080fd5b6102c65a03f1151561235b57600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b60ff1683511115151561238857600080fd5b600091505b82518260ff1610156124c0576000838360ff168151811015156123ac57fe5b906020019060200201511415156124a257600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce1658948584612420878760ff1681518110151561241157fe5b906020019060200201516133ae565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b151561248d57600080fd5b6102c65a03f1151561249e57600080fd5b5050505b6124b960018360ff1661338a90919063ffffffff16565b915061238d565b50505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561252157600080fd5b600060149054906101000a900460ff1615151561253d57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60076020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1615151561262057600080fd5b803373ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156126d957600080fd5b6102c65a03f115156126ea57600080fd5b5050506040518051905073ffffffffffffffffffffffffffffffffffffffff1614151561271657600080fd5b6000600281111561272357fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d846000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156127c457600080fd5b6102c65a03f115156127d557600080fd5b5050506040518051905060028111156127ea57fe5b1415156127f657600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e4725ba1836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050600060405180830381600087803b151561288e57600080fd5b6102c65a03f1151561289f57600080fd5b5050505050565b60008082101580156128bc575082516020830111155b15156128c757600080fd5b81602001830151905092915050565b600660205281600052604060002081610100811015156128f257fe5b016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561297657600080fd5b81600181905550806002819055507f74001f9764398216f36f3f1c1e3271c5a965a45dfa33bb132c699ed6e171ab1f600154600254604051808381526020018281526020019250505060405180910390a15050565b600080600060149054906101000a900460ff161515156129ea57600080fd5b8c8c600081811015156129f957fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015612a93575060008d8d60008181101515612a5d57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b1515612a9e57600080fd5b612b3a338e8e808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050508d8d8080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505087878080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050506138ec565b809250819350505060008973ffffffffffffffffffffffffffffffffffffffff16141515612bbd578860076000846000191660001916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b612c278289898080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505088888080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505084613c17565b819150509b9a5050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612c9557600080fd5b806003819055507f6b1c63dd26ab451d994d7f5c0b5b6e9425a2da8206cb849a5c33e34a68b011686003546040518082815260200191505060405180910390a150565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b600060149054906101000a900460ff16151515612d2057600080fd5b612d2b823383613c44565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612d8a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612dc657600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008082840290506000841480612ea55750828482811515612ea257fe5b04145b1515612ead57fe5b8091505092915050565b6000808284811515612ec557fe5b0490508091505092915050565b600080600280811115612ee157fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d866000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515612f8257600080fd5b6102c65a03f11515612f9357600080fd5b505050604051805190506002811115612fa857fe5b14151515612fb557600080fd5b6130876001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec876000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b151561305b57600080fd5b6102c65a03f1151561306c57600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b60ff1683511115151561309957600080fd5b600091505b82518260ff161015613384576000838360ff168151811015156130bd57fe5b9060200190602002015114151561336657600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b8584613131878760ff1681518110151561312257fe5b906020019060200201516133ae565b6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b151561319e57600080fd5b6102c65a03f115156131af57600080fd5b50505060006006600086600019166000191681526020019081526020016000208360ff16610100811015156131e057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156132ef57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166392fd1f0185846000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018260ff1660ff16815260200192505050602060405180830381600087803b15156132cd57600080fd5b6102c65a03f115156132de57600080fd5b505050604051805190509050613340565b6006600085600019166000191681526020019081526020016000208260ff166101008110151561331b57fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b6133653382858560ff1681518110151561335657fe5b906020019060200201516141f4565b5b61337d60018360ff1661338a90919063ffffffff16565b915061309e565b50505050565b60008082840190508360ff168160ff16101515156133a457fe5b8091505092915050565b600080829050600081121515156133c157fe5b80915050919050565b600030848484604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140184805190602001908083835b6020831015156134465780518252602082019150602081019050602083039250613421565b6001836020036101000a038019825116818451168082178552505050505050905001838051906020019060200280838360005b83811015613494578082015181840152602081019050613479565b50505050905001828152602001945050505050604051809103902090509392505050565b60008082101580156134ce575082516014830111155b15156134d957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8260140184015116905092915050565b6000806000806000806000806135158c60296134b8565b96508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415801561356a575060008773ffffffffffffffffffffffffffffffffffffffff1614155b151561357557600080fd5b8673ffffffffffffffffffffffffffffffffffffffff166135978d60006134b8565b73ffffffffffffffffffffffffffffffffffffffff161415156135b957600080fd5b8b60288151811015156135c857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004955060009450600093505b8560ff168460ff1610156136b9576136828c61367d603d61366f60348960ff16612e8490919063ffffffff16565b61432090919063ffffffff16565b6128a6565b60019004925061369b838661433e90919063ffffffff16565b94506000831315156136ac57600080fd5b8380600101945050613641565b6136c285610b10565b915034821480156136d857506136d782613bb7565b5b15156136e357600080fd5b6136fe8c6014336c010000000000000000000000000261437f565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e1cda4688d6000604051602001526040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156137b1578082015181840152602081019050613796565b50505050905090810190601f1680156137de5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15156137fc57600080fd5b6102c65a03f1151561380d57600080fd5b505050604051805190509750600090505b8a518160ff1610156138ce578a8160ff1681518110151561383b57fe5b90602001906020020151600660008a600019166000191681526020019081526020016000208260ff166101008110151561387157fe5b0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506138c760018260ff1661338a90919063ffffffff16565b905061381e565b6138da888b8b88613c17565b87975050505050505050949350505050565b60008060008060149054906101000a900460ff1615151561390c57600080fd5b60009150600090505b84518160ff161015613998576000858260ff1681518110151561393457fe5b906020019060200201511215151561394b57600080fd5b613978858260ff1681518110151561395f57fe5b906020019060200201518361433e90919063ffffffff16565b915061399160018260ff1661338a90919063ffffffff16565b9050613915565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663431072903388888b896000604051602001526040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001848103845288818151815260200191508051906020019060200280838360005b83811015613abe578082015181840152602081019050613aa3565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015613b00578082015181840152602081019050613ae5565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015613b3f578082015181840152602081019050613b24565b50505050905090810190601f168015613b6c5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1515613b9057600080fd5b6102c65a03f11515613ba157600080fd5b5050506040518051905092505094509492505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050509050919050565b613c2084612604565b613c2a84836120b1565b6000811315613c3e57613c3d8484612ed2565b5b50505050565b600080600080600280811115613c5657fe5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166309648a9d896000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613cf757600080fd5b6102c65a03f11515613d0857600080fd5b505050604051805190506002811115613d1d57fe5b14151515613d2a57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f6112d6888886000604051602001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1515613dff57600080fd5b6102c65a03f11515613e1057600080fd5b505050604051805190509350613eee6001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caef5dec8a6000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b1515613ec257600080fd5b6102c65a03f11515613ed357600080fd5b5050506040518051905060ff1661338a90919063ffffffff16565b925060008460010b1215613fe457600091505b8260ff168260ff16108015613f3857507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8460010b145b15613fe3578573ffffffffffffffffffffffffffffffffffffffff166006600089600019166000191681526020019081526020016000208360ff1661010081101515613f8057fe5b0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613fc5578160ff1693505b613fdc60018360ff1661338a90919063ffffffff16565b9150613f01565b5b60008460010b12151515613ff757600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b073f52b8886614040896133ae565b6000036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018360ff1660ff1681526020018281526020019350505050600060405180830381600087803b15156140b057600080fd5b6102c65a03f115156140c157600080fd5b50505060076000886000191660001916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1614156141e057600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a12cad70886000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260001916600019168152602001915050602060405180830381600087803b15156141c257600080fd5b6102c65a03f115156141d357600080fd5b5050506040518051905090505b6141eb8682876141f4565b50505050505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8484846000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15156142f557600080fd5b6102c65a03f1151561430657600080fd5b50505060405180519050151561431b57600080fd5b505050565b600080828401905083811015151561433457fe5b8091505092915050565b6000808284019050600083121580156143575750838112155b8061436d575060008312801561436c57508381125b5b151561437557fe5b8091505092915050565b60008210158015614394575082516014830111155b151561439f57600080fd5b816014018301517fffffffffffffffffffffffff0000000000000000000000000000000000000000811690506c010000000000000000000000008204811790508083601401850152505050505600a165627a7a723058208f1fd49f36fd856358b7ad669338b622084ba89f01f4ed62a8bea3e27656d8880029

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

000000000000000000000000db600fda54568a35b78565b5257125bebc51eb270000000000000000000000007b3c4d90e8af6030d66c07f8f815f9505e379d6f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f

-----Decoded View---------------
Arg [0] : _requestCoreAddress (address): 0xdb600fdA54568A35b78565B5257125beBC51Eb27
Arg [1] : _requestBurnerAddress (address): 0x7b3C4D90e8AF6030d66c07F8F815f9505E379d6F
Arg [2] : _erc20Token (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000db600fda54568a35b78565b5257125bebc51eb27
Arg [1] : 0000000000000000000000007b3c4d90e8af6030d66c07f8f815f9505e379d6f
Arg [2] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f


Deployed Bytecode Sourcemap

40696:20627:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31309:446;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30028:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51288:621;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38439:1030;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6895:90;;;;;;;;;;;;;;57377:727;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46491:757;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32802:172;;;;;;;;;;;;;;;;;;;;;;;;;;;;6279:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42536:1195;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33710:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30067:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36239:708;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59218:364;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37266:862;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6720:88;;;;;;;;;;;;;;41175:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5284:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41091:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35631:353;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60369:269;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41024:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32060:296;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44591:974;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32455:164;;;;;;;;;;;;;;;;;;;;;;;;;;30212:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30108:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52426:187;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5908:173;;;;;;;;;;;;;;;;;;;;;;;;;;;;31309:446;31407:7;31475:23;31451:1;31435:15;:17;31432:30;;;31461:1;31454:8;;;;31432:30;31501:47;31530:17;;31509:15;31501:28;;:47;;;;:::i;:::-;31475:73;;31587:1;31564:19;;:24;;31561:114;;;31623:40;31643:19;;31623:15;:19;;:40;;;;:::i;:::-;31605:58;;31561:114;31712:7;;31694:15;:25;:53;;31740:7;;31694:53;;;31722:15;31694:53;31687:60;;31309:446;;;;;:::o;30028:32::-;;;;:::o;51288:621::-;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;51596:25;51562:59;;;;;;;;:11;;;;;;;;;;;:20;;;51583:10;51562:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:59;;;;;;;;;:109;;;;;51639:11;;;;;;;;;;;:20;;;51660:10;51639:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51625:46;;:10;:46;;;51562:109;51558:166;;;51688:24;51701:10;51688:12;:24::i;:::-;51558:166;51769:1;51740:18;;:25;;:30;;51736:111;;;51787:48;51804:10;51816:18;;51787:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:16;:48::i;:::-;51736:111;51859:42;51875:10;51887:13;;51859:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:15;:42::i;:::-;51288:621;;;;;:::o;38439:1030::-;38926:7;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;38576:10;39869;39825:54;;:11;;;;;;;;;;;:27;;;39853:10;39865:1;39825:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:54;;;39817:63;;;;;;;;38710:26;38676:60;;;;;;;;:11;;;;;;;;;;;:20;;;38697:10;38676:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:60;;;;;;;;;;38668:69;;;;;;;;38860:48;38906:1;38860:11;;;;;;;;;;;:29;;;38890:10;38860:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:45;;;;:48;;;;:::i;:::-;38833:75;;:16;:23;:75;;38825:84;;;;;;;;38936:1;38926:11;;38922:540;38943:16;:23;38939:1;:27;;;38922:540;;;39079:1;39056:16;39073:1;39056:19;;;;;;;;;;;;;;;;;;;;:24;;39053:398;;;39234:34;:16;39251:1;39234:19;;;;;;;;;;;;;;;;;;;;:32;:34::i;:::-;39182:11;;;;;;;;;;;:34;;;39217:10;39228:1;39182:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:86;;39174:95;;;;;;;;39351:11;;;;;;;;;;;:32;;;39384:10;39396:1;39400:34;:16;39417:1;39400:19;;;;;;;;;;;;;;;;;;;;:32;:34::i;:::-;39399:35;;39351:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39053:398;38972:8;38978:1;38972;:5;;;;:8;;;;:::i;:::-;38968:12;;38922:540;;;6469:1;38439:1030;;;:::o;6895:90::-;5719:5;;;;;;;;;;;5705:19;;:10;:19;;;5697:28;;;;;;;;6615:6;;;;;;;;;;;6607:15;;;;;;;;6958:5;6949:6;;:14;;;;;;;;;;;;;;;;;;6970:9;;;;;;;;;;6895:90::o;57377:727::-;57607:4;57629:12;57774:7;57853:9;57905;57644:68;57659:12;57673:21;57696:15;57644:14;:68::i;:::-;57629:83;;57790:10;57801:2;57790:14;;;;;;;;;;;;;;;;;;;;57784:21;;;57774:31;;57824:2;57820:1;:6;;;:22;;57841:1;57820:22;;;57829:9;57835:2;57829:1;:5;;;;:9;;;;:::i;:::-;57820:22;57816:26;;57865:29;57880:10;57892:1;57865:14;:29::i;:::-;57853:41;;57917:30;57932:10;57944:2;57917:14;:30::i;:::-;57905:42;;58032:64;58049:31;58064:12;58078:1;58049:14;:31::i;:::-;58082:4;58088:1;58091;58094;58032:16;:64::i;:::-;58025:71;;57377:727;;;;;;;;;;:::o;46491:757::-;46874:17;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;46970:15;46951;:34;;46943:43;;;;;;;;47039:87;47061:12;;47039:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47075:21;;47039:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47098:15;47115:10;;47039:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:21;:87::i;:::-;47031:96;;;;;;;;47147:93;47175:12;;47147:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47189:21;;47147:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47212:13;;47147:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47227:12;;47147:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:27;:93::i;:::-;47140:100;;46491:757;;;;;;;;;;;;;:::o;32802:172::-;5719:5;;;;;;;;;;;5705:19;;:10;:19;;;5697:28;;;;;;;;32944:22;32922:21;;:44;;;;;;;;;;;;;;;;;;32802:172;:::o;6279:26::-;;;;;;;;;;;;;:::o;42536:1195::-;42869:17;42998:27;43203:12;43387:7;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;42926;;42943:1;42926:19;;;;;;;;;;;;;;;;;42912:33;;:10;:33;;;:57;;;;;42963:6;42949:20;;:10;:20;;;;42912:57;:72;;;;;42983:1;42973:6;:11;;;;42912:72;42904:81;;;;;;;;43072:76;43098:6;43106:16;;43072:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43124:16;;43072:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43142:5;;43072:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:25;:76::i;:::-;43036:112;;;;;;;;43218:39;43236:20;43218:17;:39::i;:::-;43203:54;;43284:9;43276:4;:17;:47;;;;;43297:26;43318:4;43297:20;:26::i;:::-;43276:47;43268:56;;;;;;;;43397:1;43387:11;;43382:154;43404:21;;:28;;43400:1;:32;;;43382:154;;;43500:21;;43522:1;43500:24;;;;;;;;;;;;;;;;;;;43463:20;:31;43484:9;43463:31;;;;;;;;;;;;;;;;;43495:1;43463:34;;;;;;;;;;;;;:61;;;;;;;;;;;;;;;;;;43438:8;43444:1;43438;:5;;;;:8;;;;:::i;:::-;43434:12;;43382:154;;;43614:1;43591:19;:24;;;;43588:107;;;43664:19;43632:18;:29;43651:9;43632:29;;;;;;;;;;;;;;;;;;:51;;;;;;;;;;;;;;;;;;43588:107;43714:9;43707:16;;42536:1195;;;;;;;;;;;;;;;:::o;33710:30::-;;;;;;;;;;;;;:::o;30067:34::-;;;;:::o;36239:708::-;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;36497:10;36463:44;;:11;;;;;;;;;;;:20;;;36484:10;36463:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;;:107;;;;;36545:25;36511:59;;;;;;;;:11;;;;;;;;;;;:20;;;36532:10;36511:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:59;;;;;;;;;36463:107;36462:249;;;;36636:10;36593:53;;:11;;;;;;;;;;;:27;;;36621:10;36632:1;36593:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:53;;;:117;;;;;36684:26;36650:60;;;;;;;;:11;;;;;;;;;;;:20;;;36671:10;36650:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:60;;;;;;;;;;36593:117;36462:249;36454:258;;;;;;;;36805:11;;;;;;;;;;;:29;;;36835:10;36805:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36797:50;;;;;;;;36909:11;;;;;;;;;;;:18;;;36928:10;36909:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36239:708;:::o;59218:364::-;59401:4;59440:134;59510:4;59464:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59530:1;59546;59562;59440:134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59430:144;;:6;:144;;;59423:151;;59218:364;;;;;;;:::o;37266:862::-;37764:7;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;37407:10;40175;40141:44;;:11;;;;;;;;;;;:20;;;40162:10;40141:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;;40133:53;;;;;;;;37544:26;37510:60;;;;;;;;:11;;;;;;;;;;;:20;;;37531:10;37510:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:60;;;;;;;;;;37502:69;;;;;;;;37698:48;37744:1;37698:11;;;;;;;;;;;:29;;;37728:10;37698:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:45;;;;:48;;;;:::i;:::-;37669:77;;:18;:25;:77;;37661:86;;;;;;;;37774:1;37764:11;;37760:361;37781:18;:25;37777:1;:29;;;37760:361;;;37922:1;37897:18;37916:1;37897:21;;;;;;;;;;;;;;;;;;;;:26;;37894:216;;;38009:11;;;;;;;;;;;:32;;;38042:10;38054:1;38057:36;:18;38076:1;38057:21;;;;;;;;;;;;;;;;;;;;:34;:36::i;:::-;38009:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37894:216;37812:8;37818:1;37812;:5;;;;:8;;;;:::i;:::-;37808:12;;37760:361;;;6469:1;37266:862;;;:::o;6720:88::-;5719:5;;;;;;;;;;;5705:19;;:10;:19;;;5697:28;;;;;;;;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;6784:4;6775:6;;:13;;;;;;;;;;;;;;;;;;6795:7;;;;;;;;;;6720:88::o;41175:23::-;;;;;;;;;;;;;:::o;5284:20::-;;;;;;;;;;;;;:::o;41091:53::-;;;;;;;;;;;;;;;;;;;;;;:::o;35631:353::-;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;35738:10;40175;40141:44;;:11;;;;;;;;;;;:20;;;40162:10;40141:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;;;40133:53;;;;;;;;35859:25;35825:59;;;;;;;;:11;;;;;;;;;;;:20;;;35846:10;35825:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:59;;;;;;;;;35817:68;;;;;;;;35946:11;;;;;;;;;;;:18;;;35965:10;35946:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6469:1;35631:353;:::o;60369:269::-;60467:10;60512:1;60503:6;:10;;:41;;;;;60532:5;:12;60526:2;60517:6;:11;:27;;60503:41;60495:50;;;;;;;;60611:6;60607:2;60603:3;60596:5;60592:3;60586:5;60580:40;;60565:66;;;;:::o;41024:60::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;32060:296::-;5719:5;;;;;;;;;;;5705:19;;:10;:19;;;5697:28;;;;;;;;32212:18;32192:17;:38;;;;32263:20;32241:19;:42;;;;32294:54;32309:17;;32328:19;;32294:54;;;;;;;;;;;;;;;;;;;;;;;;32060:296;;:::o;44591:974::-;44922:17;45040:27;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;44979;;44996:1;44979:19;;;;;;;;;;;;;;;;;44965:33;;:10;:33;;;;:61;;;;;45025:1;45002:16;;45019:1;45002:19;;;;;;;;;;;;;;;;;:24;;;;44965:61;44957:70;;;;;;;;45114:80;45140:10;45152:16;;45114:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45170:16;;45114:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45188:5;;45114:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:25;:80::i;:::-;45078:116;;;;;;;;45275:1;45252:19;:24;;;;45249:107;;;45325:19;45293:18;:29;45312:9;45293:29;;;;;;;;;;;;;;;;;;:51;;;;;;;;;;;;;;;;;;45249:107;45454:74;45467:9;45478:13;;45454:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45493:12;;45454:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45507:20;45454:12;:74::i;:::-;45548:9;45541:16;;44591:974;;;;;;;;;;;;;;:::o;32455:164::-;5719:5;;;;;;;;;;;5705:19;;:10;:19;;;5697:28;;;;;;;;32567:11;32557:7;:21;;;;32589:22;32603:7;;32589:22;;;;;;;;;;;;;;;;;;32455:164;:::o;30212:36::-;;;;;;;;;;;;;:::o;30108:22::-;;;;:::o;52426:187::-;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;52550:55;52565:10;52577;52589:15;52550:14;:55::i;:::-;52426:187;;:::o;5908:173::-;5719:5;;;;;;;;;;;5705:19;;:10;:19;;;5697:28;;;;;;;;6005:1;5985:22;;:8;:22;;;;5977:31;;;;;;;;6043:8;6015:37;;6036:5;;;;;;;;;;;6015:37;;;;;;;;;;;;6067:8;6059:5;;:16;;;;;;;;;;;;;;;;;;5908:173;:::o;313:149::-;371:7;387:9;403:1;399;:5;387:17;;425:1;420;:6;:20;;;;439:1;434;430;:5;;;;;;;;:10;420:20;413:28;;;;;;455:1;448:8;;313:149;;;;;:::o;468:270::-;526:7;617:9;633:1;629;:5;;;;;;;;617:17;;731:1;724:8;;468:270;;;;;:::o;52938:1183::-;53315:7;53663:20;53109:26;53075:60;;;;;;;;:11;;;;;;;;;;;:20;;;53096:10;53075:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:60;;;;;;;;;;53067:69;;;;;;;;53249:48;53295:1;53249:11;;;;;;;;;;;:29;;;53279:10;53249:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:45;;;;:48;;;;:::i;:::-;53225:72;;:13;:20;:72;;53217:81;;;;;;;;53325:1;53315:11;;53311:803;53332:13;:20;53328:1;:24;;;53311:803;;;53406:1;53386:13;53400:1;53386:16;;;;;;;;;;;;;;;;;;;;:21;;53383:720;;;53490:11;;;;;;;;;;;:25;;;53516:10;53528:1;53531:31;:13;53545:1;53531:16;;;;;;;;;;;;;;;;;;;;:29;:31::i;:::-;53490:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53744:1;53705:20;:32;53726:10;53705:32;;;;;;;;;;;;;;;;;53738:1;53705:35;;;;;;;;;;;;;;;;;;;;;;:40;;;53702:244;;;53785:11;;;;;;;;;;;:27;;;53813:10;53825:1;53785:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53770:57;;53702:244;;;53891:20;:32;53912:10;53891:32;;;;;;;;;;;;;;;;;53924:1;53891:35;;;;;;;;;;;;;;;;;;;;;;53876:50;;53702:244;54026:61;54044:10;54056:12;54070:13;54084:1;54070:16;;;;;;;;;;;;;;;;;;;;54026:17;:61::i;:::-;53383:720;53358:8;53364:1;53358;:5;;;;:8;;;;:::i;:::-;53354:12;;53311:803;;;52938:1183;;;;:::o;3225:125::-;3279:5;3293:7;3307:1;3303;:5;3293:15;;3327:1;3322:6;;:1;:6;;;;3315:14;;;;;;3343:1;3336:8;;3225:125;;;;;:::o;1002:133::-;1058:6;1073:8;1091:1;1073:20;;1112:1;1107;:6;;1100:14;;;;;;1128:1;1121:8;;1002:133;;;;:::o;58561:299::-;58752:7;58794:4;58799:12;58813:21;58836:15;58784:68;;;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:2;51:6;36:153;;;182:3;176:5;171:3;164:6;98:2;93:3;89;82:19;;123:2;118:3;114;107:19;;148:2;143:3;139;132:19;;36:153;;;274:1;267:3;263:2;259:3;254;250;246;315:4;311:3;305;299:5;295:3;356:4;350:3;344:5;340:3;389:7;380;377:2;372:3;365:6;3:399;;;;;;;;;;;;;;;;;;;;;23:1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;80:1;75:3;71;64:6;52:2;49:1;45:3;40:15;;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;58777:75:0;;58561:299;;;;;:::o;59803:344::-;59903:9;59948:1;59939:6;:10;;:41;;;;;59968:5;:12;59962:2;59953:6;:11;:27;;59939:41;59931:50;;;;;;;;60086:42;60051:6;60047:2;60043:3;60036:5;60032:3;60026:5;60021:3;60016:113;;60001:139;;;;:::o;47853:2004::-;48076:17;48142;48416;48470:27;48516:7;48626:25;49020:12;49499:7;48162:32;48177:12;48191:2;48162:14;:32::i;:::-;48142:52;;48227:9;48213:23;;:10;:23;;;;:41;;;;;48253:1;48240:9;:14;;;;48213:41;48205:50;;;;;;;;48352:9;48317:44;;:31;48332:12;48346:1;48317:14;:31::i;:::-;:44;;;48309:53;;;;;;;;48442:12;48455:2;48442:16;;;;;;;;;;;;;;;;;;;;48436:23;;;48416:43;;48500:1;48470:31;;48526:1;48516:11;;48512:462;48533:11;48529:15;;:1;:15;;;48512:462;;;48661:56;48676:12;48690:26;48713:2;48690:18;48705:2;48698:1;48690:10;;:14;;:18;;;;:::i;:::-;:22;;:26;;;;:::i;:::-;48661:14;:56::i;:::-;48654:64;;;48626:92;;48821:44;48846:18;48821:20;:24;;:44;;;;:::i;:::-;48798:67;;48960:1;48941:18;:20;48933:29;;;;;;;;48546:3;;;;;;;48512:462;;;49035:39;49053:20;49035:17;:39::i;:::-;49020:54;;49147:9;49139:4;:17;:47;;;;;49160:26;49181:4;49160:20;:26::i;:::-;49139:47;49131:56;;;;;;;;49260:59;49281:12;49295:2;49307:10;49299:19;;49260:20;:59::i;:::-;49380:11;;;;;;;;;;;:34;;;49415:12;49380:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;80:1;75:3;71;64:6;52:2;49:1;45:3;40:15;;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49368:60:0;;49509:1;49499:11;;49494:154;49516:21;:28;49512:1;:32;;;49494:154;;;49612:21;49634:1;49612:24;;;;;;;;;;;;;;;;;;;;49575:20;:31;49596:9;49575:31;;;;;;;;;;;;;;;;;49607:1;49575:34;;;;;;;;;;;;;:61;;;;;;;;;;;;;;;;;;49550:8;49556:1;49550;:5;;;;:8;;;;:::i;:::-;49546:12;;49494:154;;;49746:74;49759:9;49770:13;49785:12;49799:20;49746:12;:74::i;:::-;49840:9;49833:16;;47853:2004;;;;;;;;;;;;;:::o;34650:815::-;34879:17;34898:27;34983:7;6455:6;;;;;;;;;;;6454:7;6446:16;;;;;;;;34966:1;34943:24;;34993:1;34983:11;;34978:330;35000:16;:23;34996:1;:27;;;34978:330;;;35146:1;35125:16;35142:1;35125:19;;;;;;;;;;;;;;;;;;;;:22;;35117:31;;;;;;;;35251:45;35276:16;35293:1;35276:19;;;;;;;;;;;;;;;;;;;;35251:20;:24;;:45;;;;:::i;:::-;35228:68;;35029:8;35035:1;35029;:5;;;;:8;;;;:::i;:::-;35025:12;;34978:330;;;35369:11;;;;;;;;;;;:25;;;35395:10;35407:16;35425;35443:6;35451:5;35369:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;80:1;75:3;71;64:6;52:2;49:1;45:3;40:15;;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;80:1;75:3;71;64:6;52:2;49:1;45:3;40:15;;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;80:1;75:3;71;64:6;52:2;49:1;45:3;40:15;;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35358:99:0;;34650:815;;;;;;;;:::o;30984:154::-;31066:4;31095:21;;;;;;;;;;;:26;;:35;31122:7;31095:35;;;;;;;;;;;;;;;;;;;;;;;31088:42;;30984:154;;;:::o;50270:388::-;50457:24;50470:10;50457:12;:24::i;:::-;50502:42;50519:10;50531:12;50502:16;:42::i;:::-;50579:1;50560:16;:20;50557:94;;;50597:42;50613:10;50625:13;50597:15;:42::i;:::-;50557:94;50270:388;;;;:::o;54398:1500::-;54669:16;54785:17;54979:7;55596:20;54581:26;54547:60;;;;;;;;:11;;;;;;;;;;;:20;;;54568:10;54547:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:60;;;;;;;;;;54539:69;;;;;;;;54688:11;;;;;;;;;;;:25;;;54714:10;54726:8;54688:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54669:66;;54805:48;54851:1;54805:11;;;;;;;;;;;:29;;;54835:10;54805:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:45;;;;:48;;;;:::i;:::-;54785:68;;54882:1;54869:10;:14;;;54866:394;;;54989:1;54979:11;;54974:275;54996:11;54992:15;;:1;:15;;;:35;;;;;55025:2;55011:10;:16;;;54992:35;54974:275;;;55117:8;55078:47;;:20;:32;55099:10;55078:32;;;;;;;;;;;;;;;;;55111:1;55078:35;;;;;;;;;;;;;;;;;;;;;;:47;;;55075:159;;;55212:1;55206:8;;55193:21;;55075:159;55033:8;55039:1;55033;:5;;;;:8;;;;:::i;:::-;55029:12;;54974:275;;;54866:394;55340:1;55326:10;:15;;;;55318:24;;;;;;;;55425:11;;;;;;;;;;;:25;;;55451:10;55469;55483:22;:7;:20;:22::i;:::-;55482:23;;55425:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55619:18;:30;55638:10;55619:30;;;;;;;;;;;;;;;;;;;;;;;;;;;55596:53;;55679:1;55663:12;:17;;;55660:96;;;55712:11;;;;;;;;;;;:20;;;55733:10;55712:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55697:47;;55660:96;55840:50;55858:8;55868:12;55882:7;55840:17;:50::i;:::-;54398:1500;;;;;;;:::o;56167:212::-;56319:10;;;;;;;;;;;:23;;;56343:5;56350:10;56362:7;56319:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56311:60;;;;;;;;56167:212;;;:::o;863:133::-;921:7;937:9;953:1;949;:5;937:17;;973:1;968;:6;;961:14;;;;;;989:1;982:8;;863:133;;;;;:::o;2254:161::-;2310:6;2325:8;2340:1;2336;:5;2325:16;;2361:1;2356;:6;;:16;;;;;2371:1;2366;:6;;2356:16;2355:38;;;;2382:1;2378;:5;:14;;;;;2391:1;2387;:5;2378:14;2355:38;2348:46;;;;;;2408:1;2401:8;;2254:161;;;;;:::o;60857:463::-;60988:1;60979:6;:10;;:40;;;;;61008:4;:11;61002:2;60993:6;:11;:26;;60979:40;60971:49;;;;;;;;61088:6;61084:2;61080:3;61074:4;61070:3;61064:5;61123:66;61120:1;61116:3;61111:79;;61222:27;61219:1;61215:3;61212:1;61209:2;61204:47;;61300:1;61290:6;61286:2;61282:3;61276:4;61272:3;61265:6;61040:273;;;;:::o

Swarm Source

bzzr://8f1fd49f36fd856358b7ad669338b622084ba89f01f4ed62a8bea3e27656d888

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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