Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x4dD6655Ad5ed7C06c882f496E3f42acE5766cb89
Contract Name:
AccessControlledOffchainAggregator
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2021-07-12 */ // Sources flattened with hardhat v2.3.0 https://hardhat.org // File contract/src/AccessControllerInterface.sol // SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface AccessControllerInterface { function hasAccess(address user, bytes calldata data) external view returns (bool); } // File contract/src/AggregatorInterface.sol pragma solidity ^0.7.0; interface AggregatorInterface { function latestAnswer() external view returns (int256); function latestTimestamp() external view returns (uint256); function latestRound() external view returns (uint256); function getAnswer(uint256 roundId) external view returns (int256); function getTimestamp(uint256 roundId) external view returns (uint256); event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); } // File contract/src/AggregatorV3Interface.sol pragma solidity ^0.7.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); } // File contract/src/AggregatorV2V3Interface.sol pragma solidity ^0.7.0; interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface { } // File contract/src/AggregatorValidatorInterface.sol pragma solidity ^0.7.0; interface AggregatorValidatorInterface { function validate( uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ) external returns (bool); } // File contract/src/LinkTokenInterface.sol pragma solidity ^0.7.1; interface LinkTokenInterface { function allowance(address owner, address spender) external view returns (uint256 remaining); function approve(address spender, uint256 value) external returns (bool success); function balanceOf(address owner) external view returns (uint256 balance); function decimals() external view returns (uint8 decimalPlaces); function decreaseApproval(address spender, uint256 addedValue) external returns (bool success); function increaseApproval(address spender, uint256 subtractedValue) external; function name() external view returns (string memory tokenName); function symbol() external view returns (string memory tokenSymbol); function totalSupply() external view returns (uint256 totalTokensIssued); function transfer(address to, uint256 value) external returns (bool success); function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success); function transferFrom(address from, address to, uint256 value) external returns (bool success); } // File contract/src/Owned.sol pragma solidity ^0.7.0; /** * @title The Owned contract * @notice A contract with helpers for basic contract ownership. */ contract Owned { address payable public owner; address private pendingOwner; event OwnershipTransferRequested( address indexed from, address indexed to ); event OwnershipTransferred( address indexed from, address indexed to ); constructor() { owner = msg.sender; } /** * @dev Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership(address _to) external onlyOwner() { pendingOwner = _to; emit OwnershipTransferRequested(owner, _to); } /** * @dev Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external { require(msg.sender == pendingOwner, "Must be proposed owner"); address oldOwner = owner; owner = msg.sender; pendingOwner = address(0); emit OwnershipTransferred(oldOwner, msg.sender); } /** * @dev Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { require(msg.sender == owner, "Only callable by owner"); _; } } // File contract/src/OffchainAggregatorBilling.sol pragma solidity ^0.7.0; /** * @notice tracks administration of oracle-reward and gas-reimbursement parameters. * @dev * If you read or change this, be sure to read or adjust the comments. They * track the units of the values under consideration, and are crucial to * the readability of the operations it specifies. * @notice * Trust Model: * Nothing in this contract prevents a billing admin from setting insane * values for the billing parameters in setBilling. Oracles * participating in this contract should regularly check that the * parameters make sense. Similarly, the outstanding obligations of this * contract to the oracles can exceed the funds held by the contract. * Oracles participating in this contract should regularly check that it * holds sufficient funds and stop interacting with it if funding runs * out. * This still leaves oracles with some risk due to TOCTOU issues. * However, since the sums involved are pretty small (Ethereum * transactions aren't that expensive in the end) and an oracle would * likely stop participating in a contract it repeatedly lost money on, * this risk is deemed acceptable. Oracles should also regularly * withdraw any funds in the contract to prevent issues where the * contract becomes underfunded at a later time, and different oracles * are competing for the left-over funds. * Finally, note that any change to the set of oracles or to the billing * parameters will trigger payout of all oracles first (using the old * parameters), a billing admin cannot take away funds that are already * marked for payment. */ contract OffchainAggregatorBilling is Owned { // Maximum number of oracles the offchain reporting protocol is designed for uint256 constant internal maxNumOracles = 31; // Parameters for oracle payments struct Billing { // Highest compensated gas price, in ETH-gwei uints uint32 maximumGasPrice; // If gas price is less (in ETH-gwei units), transmitter gets half the savings uint32 reasonableGasPrice; // Pay transmitter back this much LINK per unit eth spent on gas // (1e-6LINK/ETH units) uint32 microLinkPerEth; // Fixed LINK reward for each observer, in LINK-gwei units uint32 linkGweiPerObservation; // Fixed reward for transmitter, in linkGweiPerObservation units uint32 linkGweiPerTransmission; } Billing internal s_billing; /** * @return LINK token contract used for billing */ LinkTokenInterface immutable public LINK; AccessControllerInterface internal s_billingAccessController; // ith element is number of observation rewards due to ith process, plus one. // This is expected to saturate after an oracle has submitted 65,535 // observations, or about 65535/(3*24*20) = 45 days, given a transmission // every 3 minutes. // // This is always one greater than the actual value, so that when the value is // reset to zero, we don't end up with a zero value in storage (which would // result in a higher gas cost, the next time the value is incremented.) // Calculations using this variable need to take that offset into account. uint16[maxNumOracles] internal s_oracleObservationsCounts; // Addresses at which oracles want to receive payments, by transmitter address mapping (address /* transmitter */ => address /* payment address */) internal s_payees; // Payee addresses which must be approved by the owner mapping (address /* transmitter */ => address /* payment address */) internal s_proposedPayees; // LINK-wei-denominated reimbursements for gas used by transmitters. // // This is always one greater than the actual value, so that when the value is // reset to zero, we don't end up with a zero value in storage (which would // result in a higher gas cost, the next time the value is incremented.) // Calculations using this variable need to take that offset into account. // // Argument for overflow safety: // We have the following maximum intermediate values: // - 2**40 additions to this variable (epochAndRound is a uint40) // - 2**32 gas price in ethgwei/gas // - 1e9 ethwei/ethgwei // - 2**32 gas since the block gas limit is at ~20 million // - 2**32 (microlink/eth) // And we have 2**40 * 2**32 * 1e9 * 2**32 * 2**32 < 2**166 // (we also divide in some places, but that only makes the value smaller) // We can thus safely use uint256 intermediate values for the computation // updating this variable. uint256[maxNumOracles] internal s_gasReimbursementsLinkWei; // Used for s_oracles[a].role, where a is an address, to track the purpose // of the address, or to indicate that the address is unset. enum Role { // No oracle role has been set for address a Unset, // Signing address for the s_oracles[a].index'th oracle. I.e., report // signatures from this oracle should ecrecover back to address a. Signer, // Transmission address for the s_oracles[a].index'th oracle. I.e., if a // report is received by OffchainAggregator.transmit in which msg.sender is // a, it is attributed to the s_oracles[a].index'th oracle. Transmitter } struct Oracle { uint8 index; // Index of oracle in s_signers/s_transmitters Role role; // Role of the address which mapped to this struct } mapping (address /* signer OR transmitter address */ => Oracle) internal s_oracles; // s_signers contains the signing address of each oracle address[] internal s_signers; // s_transmitters contains the transmission address of each oracle, // i.e. the address the oracle actually sends transactions to the contract from address[] internal s_transmitters; uint256 constant private maxUint16 = (1 << 16) - 1; uint256 constant internal maxUint128 = (1 << 128) - 1; constructor( uint32 _maximumGasPrice, uint32 _reasonableGasPrice, uint32 _microLinkPerEth, uint32 _linkGweiPerObservation, uint32 _linkGweiPerTransmission, address _link, AccessControllerInterface _billingAccessController ) { setBillingInternal(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth, _linkGweiPerObservation, _linkGweiPerTransmission); setBillingAccessControllerInternal(_billingAccessController); LINK = LinkTokenInterface(_link); uint16[maxNumOracles] memory counts; // See s_oracleObservationsCounts docstring uint256[maxNumOracles] memory gas; // see s_gasReimbursementsLinkWei docstring for (uint8 i = 0; i < maxNumOracles; i++) { counts[i] = 1; gas[i] = 1; } s_oracleObservationsCounts = counts; s_gasReimbursementsLinkWei = gas; } /** * @notice emitted when billing parameters are set * @param maximumGasPrice highest gas price for which transmitter will be compensated * @param reasonableGasPrice transmitter will receive reward for gas prices under this value * @param microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units * @param linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units * @param linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units */ event BillingSet( uint32 maximumGasPrice, uint32 reasonableGasPrice, uint32 microLinkPerEth, uint32 linkGweiPerObservation, uint32 linkGweiPerTransmission ); function setBillingInternal( uint32 _maximumGasPrice, uint32 _reasonableGasPrice, uint32 _microLinkPerEth, uint32 _linkGweiPerObservation, uint32 _linkGweiPerTransmission ) internal { s_billing = Billing(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth, _linkGweiPerObservation, _linkGweiPerTransmission); emit BillingSet(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth, _linkGweiPerObservation, _linkGweiPerTransmission); } /** * @notice sets billing parameters * @param _maximumGasPrice highest gas price for which transmitter will be compensated * @param _reasonableGasPrice transmitter will receive reward for gas prices under this value * @param _microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units * @param _linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units * @param _linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units * @dev access control provided by billingAccessController */ function setBilling( uint32 _maximumGasPrice, uint32 _reasonableGasPrice, uint32 _microLinkPerEth, uint32 _linkGweiPerObservation, uint32 _linkGweiPerTransmission ) external { AccessControllerInterface access = s_billingAccessController; require(msg.sender == owner || access.hasAccess(msg.sender, msg.data), "Only owner&billingAdmin can call"); payOracles(); setBillingInternal(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth, _linkGweiPerObservation, _linkGweiPerTransmission); } /** * @notice gets billing parameters * @param maximumGasPrice highest gas price for which transmitter will be compensated * @param reasonableGasPrice transmitter will receive reward for gas prices under this value * @param microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units * @param linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units * @param linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units */ function getBilling() external view returns ( uint32 maximumGasPrice, uint32 reasonableGasPrice, uint32 microLinkPerEth, uint32 linkGweiPerObservation, uint32 linkGweiPerTransmission ) { Billing memory billing = s_billing; return ( billing.maximumGasPrice, billing.reasonableGasPrice, billing.microLinkPerEth, billing.linkGweiPerObservation, billing.linkGweiPerTransmission ); } /** * @notice emitted when a new access-control contract is set * @param old the address prior to the current setting * @param current the address of the new access-control contract */ event BillingAccessControllerSet(AccessControllerInterface old, AccessControllerInterface current); function setBillingAccessControllerInternal(AccessControllerInterface _billingAccessController) internal { AccessControllerInterface oldController = s_billingAccessController; if (_billingAccessController != oldController) { s_billingAccessController = _billingAccessController; emit BillingAccessControllerSet( oldController, _billingAccessController ); } } /** * @notice sets billingAccessController * @param _billingAccessController new billingAccessController contract address * @dev only owner can call this */ function setBillingAccessController(AccessControllerInterface _billingAccessController) external onlyOwner { setBillingAccessControllerInternal(_billingAccessController); } /** * @notice gets billingAccessController * @return address of billingAccessController contract */ function billingAccessController() external view returns (AccessControllerInterface) { return s_billingAccessController; } /** * @notice withdraws an oracle's payment from the contract * @param _transmitter the transmitter address of the oracle * @dev must be called by oracle's payee address */ function withdrawPayment(address _transmitter) external { require(msg.sender == s_payees[_transmitter], "Only payee can withdraw"); payOracle(_transmitter); } /** * @notice query an oracle's payment amount * @param _transmitter the transmitter address of the oracle */ function owedPayment(address _transmitter) public view returns (uint256) { Oracle memory oracle = s_oracles[_transmitter]; if (oracle.role == Role.Unset) { return 0; } Billing memory billing = s_billing; uint256 linkWeiAmount = uint256(s_oracleObservationsCounts[oracle.index] - 1) * uint256(billing.linkGweiPerObservation) * (1 gwei); linkWeiAmount += s_gasReimbursementsLinkWei[oracle.index] - 1; return linkWeiAmount; } /** * @notice emitted when an oracle has been paid LINK * @param transmitter address from which the oracle sends reports to the transmit method * @param payee address to which the payment is sent * @param amount amount of LINK sent */ event OraclePaid(address transmitter, address payee, uint256 amount); // payOracle pays out _transmitter's balance to the corresponding payee, and zeros it out function payOracle(address _transmitter) internal { Oracle memory oracle = s_oracles[_transmitter]; uint256 linkWeiAmount = owedPayment(_transmitter); if (linkWeiAmount > 0) { address payee = s_payees[_transmitter]; // Poses no re-entrancy issues, because LINK.transfer does not yield // control flow. require(LINK.transfer(payee, linkWeiAmount), "insufficient funds"); s_oracleObservationsCounts[oracle.index] = 1; // "zero" the counts. see var's docstring s_gasReimbursementsLinkWei[oracle.index] = 1; // "zero" the counts. see var's docstring emit OraclePaid(_transmitter, payee, linkWeiAmount); } } // payOracles pays out all transmitters, and zeros out their balances. // // It's much more gas-efficient to do this as a single operation, to avoid // hitting storage too much. function payOracles() internal { Billing memory billing = s_billing; uint16[maxNumOracles] memory observationsCounts = s_oracleObservationsCounts; uint256[maxNumOracles] memory gasReimbursementsLinkWei = s_gasReimbursementsLinkWei; address[] memory transmitters = s_transmitters; for (uint transmitteridx = 0; transmitteridx < transmitters.length; transmitteridx++) { uint256 reimbursementAmountLinkWei = gasReimbursementsLinkWei[transmitteridx] - 1; uint256 obsCount = observationsCounts[transmitteridx] - 1; uint256 linkWeiAmount = obsCount * uint256(billing.linkGweiPerObservation) * (1 gwei) + reimbursementAmountLinkWei; if (linkWeiAmount > 0) { address payee = s_payees[transmitters[transmitteridx]]; // Poses no re-entrancy issues, because LINK.transfer does not yield // control flow. require(LINK.transfer(payee, linkWeiAmount), "insufficient funds"); observationsCounts[transmitteridx] = 1; // "zero" the counts. gasReimbursementsLinkWei[transmitteridx] = 1; // "zero" the counts. emit OraclePaid(transmitters[transmitteridx], payee, linkWeiAmount); } } // "Zero" the accounting storage variables s_oracleObservationsCounts = observationsCounts; s_gasReimbursementsLinkWei = gasReimbursementsLinkWei; } function oracleRewards( bytes memory observers, uint16[maxNumOracles] memory observations ) internal pure returns (uint16[maxNumOracles] memory) { // reward each observer-participant with the observer reward for (uint obsIdx = 0; obsIdx < observers.length; obsIdx++) { uint8 observer = uint8(observers[obsIdx]); observations[observer] = saturatingAddUint16(observations[observer], 1); } return observations; } // This value needs to change if maxNumOracles is increased, or the accounting // calculations at the bottom of reimburseAndRewardOracles change. // // To recalculate it, run the profiler as described in // ../../profile/README.md, and add up the gas-usage values reported for the // lines in reimburseAndRewardOracles following the "gasLeft = gasleft()" // line. E.g., you will see output like this: // // 7 uint256 gasLeft = gasleft(); // 29 uint256 gasCostEthWei = transmitterGasCostEthWei( // 9 uint256(initialGas), // 3 gasPrice, // 3 callDataGasCost, // 3 gasLeft // . // . // . // 59 uint256 gasCostLinkWei = (gasCostEthWei * billing.microLinkPerEth)/ 1e6; // . // . // . // 5047 s_gasReimbursementsLinkWei[txOracle.index] = // 856 s_gasReimbursementsLinkWei[txOracle.index] + gasCostLinkWei + // 26 uint256(billing.linkGweiPerTransmission) * (1 gwei); // // If those were the only lines to be accounted for, you would add up // 29+9+3+3+3+59+5047+856+26=6035. uint256 internal constant accountingGasCost = 6035; // Uncomment the following declaration to compute the remaining gas cost after // above gasleft(). (This must exist in a base class to OffchainAggregator, so // it can't go in TestOffchainAggregator.) // // uint256 public gasUsedInAccounting; // Gas price at which the transmitter should be reimbursed, in ETH-gwei/gas function impliedGasPrice( uint256 txGasPrice, // ETH-gwei/gas units uint256 reasonableGasPrice, // ETH-gwei/gas units uint256 maximumGasPrice // ETH-gwei/gas units ) internal pure returns (uint256) { // Reward the transmitter for choosing an efficient gas price: if they manage // to come in lower than considered reasonable, give them half the savings. // // The following calculations are all in units of gwei/gas, i.e. 1e-9ETH/gas uint256 gasPrice = txGasPrice; if (txGasPrice < reasonableGasPrice) { // Give transmitter half the savings for coming in under the reasonable gas price gasPrice += (reasonableGasPrice - txGasPrice) / 2; } // Don't reimburse a gas price higher than maximumGasPrice return min(gasPrice, maximumGasPrice); } // gas reimbursement due the transmitter, in ETH-wei // // If this function is changed, accountingGasCost needs to change, too. See // its docstring function transmitterGasCostEthWei( uint256 initialGas, uint256 gasPrice, // ETH-gwei/gas units uint256 callDataCost, // gas units uint256 gasLeft ) internal pure returns (uint128 gasCostEthWei) { require(initialGas >= gasLeft, "gasLeft cannot exceed initialGas"); uint256 gasUsed = // gas units initialGas - gasLeft + // observed gas usage callDataCost + accountingGasCost; // estimated gas usage // gasUsed is in gas units, gasPrice is in ETH-gwei/gas units; convert to ETH-wei uint256 fullGasCostEthWei = gasUsed * gasPrice * (1 gwei); assert(fullGasCostEthWei < maxUint128); // the entire ETH supply fits in a uint128... return uint128(fullGasCostEthWei); } /** * @notice withdraw any available funds left in the contract, up to _amount, after accounting for the funds due to participants in past reports * @param _recipient address to send funds to * @param _amount maximum amount to withdraw, denominated in LINK-wei. * @dev access control provided by billingAccessController */ function withdrawFunds(address _recipient, uint256 _amount) external { require(msg.sender == owner || s_billingAccessController.hasAccess(msg.sender, msg.data), "Only owner&billingAdmin can call"); uint256 linkDue = totalLINKDue(); uint256 linkBalance = LINK.balanceOf(address(this)); require(linkBalance >= linkDue, "insufficient balance"); require(LINK.transfer(_recipient, min(linkBalance - linkDue, _amount)), "insufficient funds"); } // Total LINK due to participants in past reports. function totalLINKDue() internal view returns (uint256 linkDue) { // Argument for overflow safety: We do all computations in // uint256s. The inputs to linkDue are: // - the <= 31 observation rewards each of which has less than // 64 bits (32 bits for billing.linkGweiPerObservation, 32 bits // for wei/gwei conversion). Hence 69 bits are sufficient for this part. // - the <= 31 gas reimbursements, each of which consists of at most 166 // bits (see s_gasReimbursementsLinkWei docstring). Hence 171 bits are // sufficient for this part // In total, 172 bits are enough. uint16[maxNumOracles] memory observationCounts = s_oracleObservationsCounts; for (uint i = 0; i < maxNumOracles; i++) { linkDue += observationCounts[i] - 1; // Stored value is one greater than actual value } Billing memory billing = s_billing; // Convert linkGweiPerObservation to uint256, or this overflows! linkDue *= uint256(billing.linkGweiPerObservation) * (1 gwei); address[] memory transmitters = s_transmitters; uint256[maxNumOracles] memory gasReimbursementsLinkWei = s_gasReimbursementsLinkWei; for (uint i = 0; i < transmitters.length; i++) { linkDue += uint256(gasReimbursementsLinkWei[i]-1); // Stored value is one greater than actual value } } /** * @notice allows oracles to check that sufficient LINK balance is available * @return availableBalance LINK available on this contract, after accounting for outstanding obligations. can become negative */ function linkAvailableForPayment() external view returns (int256 availableBalance) { // there are at most one billion LINK, so this cast is safe int256 balance = int256(LINK.balanceOf(address(this))); // according to the argument in the definition of totalLINKDue, // totalLINKDue is never greater than 2**172, so this cast is safe int256 due = int256(totalLINKDue()); // safe from overflow according to above sizes return int256(balance) - int256(due); } /** * @notice number of observations oracle is due to be reimbursed for * @param _signerOrTransmitter address used by oracle for signing or transmitting reports */ function oracleObservationCount(address _signerOrTransmitter) external view returns (uint16) { Oracle memory oracle = s_oracles[_signerOrTransmitter]; if (oracle.role == Role.Unset) { return 0; } return s_oracleObservationsCounts[oracle.index] - 1; } function reimburseAndRewardOracles( uint32 initialGas, bytes memory observers ) internal { Oracle memory txOracle = s_oracles[msg.sender]; Billing memory billing = s_billing; // Reward oracles for providing observations. Oracles are not rewarded // for providing signatures, because signing is essentially free. s_oracleObservationsCounts = oracleRewards(observers, s_oracleObservationsCounts); // Reimburse transmitter of the report for gas usage require(txOracle.role == Role.Transmitter, "sent by undesignated transmitter" ); uint256 gasPrice = impliedGasPrice( tx.gasprice / (1 gwei), // convert to ETH-gwei units billing.reasonableGasPrice, billing.maximumGasPrice ); // The following is only an upper bound, as it ignores the cheaper cost for // 0 bytes. Safe from overflow, because calldata just isn't that long. uint256 callDataGasCost = 16 * msg.data.length; // If any changes are made to subsequent calculations, accountingGasCost // needs to change, too. uint256 gasLeft = gasleft(); uint256 gasCostEthWei = transmitterGasCostEthWei( uint256(initialGas), gasPrice, callDataGasCost, gasLeft ); // microLinkPerEth is 1e-6LINK/ETH units, gasCostEthWei is 1e-18ETH units // (ETH-wei), product is 1e-24LINK-wei units, dividing by 1e6 gives // 1e-18LINK units, i.e. LINK-wei units // Safe from over/underflow, since all components are non-negative, // gasCostEthWei will always fit into uint128 and microLinkPerEth is a // uint32 (128+32 < 256!). uint256 gasCostLinkWei = (gasCostEthWei * billing.microLinkPerEth)/ 1e6; // Safe from overflow, because gasCostLinkWei < 2**160 and // billing.linkGweiPerTransmission * (1 gwei) < 2**64 and we increment // s_gasReimbursementsLinkWei[txOracle.index] at most 2**40 times. s_gasReimbursementsLinkWei[txOracle.index] = s_gasReimbursementsLinkWei[txOracle.index] + gasCostLinkWei + uint256(billing.linkGweiPerTransmission) * (1 gwei); // convert from linkGwei to linkWei // Uncomment next line to compute the remaining gas cost after above gasleft(). // See OffchainAggregatorBilling.accountingGasCost docstring for more information. // // gasUsedInAccounting = gasLeft - gasleft(); } /* * Payee management */ /** * @notice emitted when a transfer of an oracle's payee address has been initiated * @param transmitter address from which the oracle sends reports to the transmit method * @param current the payeee address for the oracle, prior to this setting * @param proposed the proposed new payee address for the oracle */ event PayeeshipTransferRequested( address indexed transmitter, address indexed current, address indexed proposed ); /** * @notice emitted when a transfer of an oracle's payee address has been completed * @param transmitter address from which the oracle sends reports to the transmit method * @param current the payeee address for the oracle, prior to this setting */ event PayeeshipTransferred( address indexed transmitter, address indexed previous, address indexed current ); /** * @notice sets the payees for transmitting addresses * @param _transmitters addresses oracles use to transmit the reports * @param _payees addresses of payees corresponding to list of transmitters * @dev must be called by owner * @dev cannot be used to change payee addresses, only to initially populate them */ function setPayees( address[] calldata _transmitters, address[] calldata _payees ) external onlyOwner() { require(_transmitters.length == _payees.length, "transmitters.size != payees.size"); for (uint i = 0; i < _transmitters.length; i++) { address transmitter = _transmitters[i]; address payee = _payees[i]; address currentPayee = s_payees[transmitter]; bool zeroedOut = currentPayee == address(0); require(zeroedOut || currentPayee == payee, "payee already set"); s_payees[transmitter] = payee; if (currentPayee != payee) { emit PayeeshipTransferred(transmitter, currentPayee, payee); } } } /** * @notice first step of payeeship transfer (safe transfer pattern) * @param _transmitter transmitter address of oracle whose payee is changing * @param _proposed new payee address * @dev can only be called by payee address */ function transferPayeeship( address _transmitter, address _proposed ) external { require(msg.sender == s_payees[_transmitter], "only current payee can update"); require(msg.sender != _proposed, "cannot transfer to self"); address previousProposed = s_proposedPayees[_transmitter]; s_proposedPayees[_transmitter] = _proposed; if (previousProposed != _proposed) { emit PayeeshipTransferRequested(_transmitter, msg.sender, _proposed); } } /** * @notice second step of payeeship transfer (safe transfer pattern) * @param _transmitter transmitter address of oracle whose payee is changing * @dev can only be called by proposed new payee address */ function acceptPayeeship( address _transmitter ) external { require(msg.sender == s_proposedPayees[_transmitter], "only proposed payees can accept"); address currentPayee = s_payees[_transmitter]; s_payees[_transmitter] = msg.sender; s_proposedPayees[_transmitter] = address(0); emit PayeeshipTransferred(_transmitter, currentPayee, msg.sender); } /* * Helper functions */ function saturatingAddUint16(uint16 _x, uint16 _y) internal pure returns (uint16) { return uint16(min(uint256(_x)+uint256(_y), maxUint16)); } function min(uint256 a, uint256 b) internal pure returns (uint256) { if (a < b) { return a; } return b; } } // File contract/src/TypeAndVersionInterface.sol pragma solidity ^0.7.0; abstract contract TypeAndVersionInterface{ function typeAndVersion() external pure virtual returns (string memory); } // File contract/src/OffchainAggregator.sol pragma solidity ^0.7.0; /** * @notice Onchain verification of reports from the offchain reporting protocol * @dev For details on its operation, see the offchain reporting protocol design * @dev doc, which refers to this contract as simply the "contract". */ contract OffchainAggregator is Owned, OffchainAggregatorBilling, AggregatorV2V3Interface, TypeAndVersionInterface { uint256 constant private maxUint32 = (1 << 32) - 1; // Storing these fields used on the hot path in a HotVars variable reduces the // retrieval of all of them to a single SLOAD. If any further fields are // added, make sure that storage of the struct still takes at most 32 bytes. struct HotVars { // Provides 128 bits of security against 2nd pre-image attacks, but only // 64 bits against collisions. This is acceptable, since a malicious owner has // easier way of messing up the protocol than to find hash collisions. bytes16 latestConfigDigest; uint40 latestEpochAndRound; // 32 most sig bits for epoch, 8 least sig bits for round // Current bound assumed on number of faulty/dishonest oracles participating // in the protocol, this value is referred to as f in the design uint8 threshold; // Chainlink Aggregators expose a roundId to consumers. The offchain reporting // protocol does not use this id anywhere. We increment it whenever a new // transmission is made to provide callers with contiguous ids for successive // reports. uint32 latestAggregatorRoundId; } HotVars internal s_hotVars; // Transmission records the median answer from the transmit transaction at // time timestamp struct Transmission { int192 answer; // 192 bits ought to be enough for anyone uint64 timestamp; } mapping(uint32 /* aggregator round ID */ => Transmission) internal s_transmissions; // incremented each time a new config is posted. This count is incorporated // into the config digest, to prevent replay attacks. uint32 internal s_configCount; uint32 internal s_latestConfigBlockNumber; // makes it easier for offchain systems // to extract config from logs. // Lowest answer the system is allowed to report in response to transmissions int192 immutable public minAnswer; // Highest answer the system is allowed to report in response to transmissions int192 immutable public maxAnswer; /* * @param _maximumGasPrice highest gas price for which transmitter will be compensated * @param _reasonableGasPrice transmitter will receive reward for gas prices under this value * @param _microLinkPerEth reimbursement per ETH of gas cost, in 1e-6LINK units * @param _linkGweiPerObservation reward to oracle for contributing an observation to a successfully transmitted report, in 1e-9LINK units * @param _linkGweiPerTransmission reward to transmitter of a successful report, in 1e-9LINK units * @param _link address of the LINK contract * @param _minAnswer lowest answer the median of a report is allowed to be * @param _maxAnswer highest answer the median of a report is allowed to be * @param _billingAccessController access controller for billing admin functions * @param _requesterAccessController access controller for requesting new rounds * @param _decimals answers are stored in fixed-point format, with this many digits of precision * @param _description short human-readable description of observable this contract's answers pertain to */ constructor( uint32 _maximumGasPrice, uint32 _reasonableGasPrice, uint32 _microLinkPerEth, uint32 _linkGweiPerObservation, uint32 _linkGweiPerTransmission, address _link, int192 _minAnswer, int192 _maxAnswer, AccessControllerInterface _billingAccessController, AccessControllerInterface _requesterAccessController, uint8 _decimals, string memory _description ) OffchainAggregatorBilling(_maximumGasPrice, _reasonableGasPrice, _microLinkPerEth, _linkGweiPerObservation, _linkGweiPerTransmission, _link, _billingAccessController ) { decimals = _decimals; s_description = _description; setRequesterAccessController(_requesterAccessController); setValidatorConfig(AggregatorValidatorInterface(0x0), 0); minAnswer = _minAnswer; maxAnswer = _maxAnswer; } /* * Versioning */ function typeAndVersion() external override pure virtual returns (string memory) { return "OffchainAggregator 2.0.0"; } /* * Config logic */ /** * @notice triggers a new run of the offchain reporting protocol * @param previousConfigBlockNumber block in which the previous config was set, to simplify historic analysis * @param configCount ordinal number of this config setting among all config settings over the life of this contract * @param signers ith element is address ith oracle uses to sign a report * @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method * @param threshold maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly * @param encodedConfigVersion version of the serialization format used for "encoded" parameter * @param encoded serialized data used by oracles to configure their offchain operation */ event ConfigSet( uint32 previousConfigBlockNumber, uint64 configCount, address[] signers, address[] transmitters, uint8 threshold, uint64 encodedConfigVersion, bytes encoded ); // Reverts transaction if config args are invalid modifier checkConfigValid ( uint256 _numSigners, uint256 _numTransmitters, uint256 _threshold ) { require(_numSigners <= maxNumOracles, "too many signers"); require(_threshold > 0, "threshold must be positive"); require( _numSigners == _numTransmitters, "oracle addresses out of registration" ); require(_numSigners > 3*_threshold, "faulty-oracle threshold too high"); _; } /** * @notice sets offchain reporting protocol configuration incl. participating oracles * @param _signers addresses with which oracles sign the reports * @param _transmitters addresses oracles use to transmit the reports * @param _threshold number of faulty oracles the system can tolerate * @param _encodedConfigVersion version number for offchainEncoding schema * @param _encoded encoded off-chain oracle configuration */ function setConfig( address[] calldata _signers, address[] calldata _transmitters, uint8 _threshold, uint64 _encodedConfigVersion, bytes calldata _encoded ) external checkConfigValid(_signers.length, _transmitters.length, _threshold) onlyOwner() { while (s_signers.length != 0) { // remove any old signer/transmitter addresses uint lastIdx = s_signers.length - 1; address signer = s_signers[lastIdx]; address transmitter = s_transmitters[lastIdx]; payOracle(transmitter); delete s_oracles[signer]; delete s_oracles[transmitter]; s_signers.pop(); s_transmitters.pop(); } for (uint i = 0; i < _signers.length; i++) { // add new signer/transmitter addresses require( s_oracles[_signers[i]].role == Role.Unset, "repeated signer address" ); s_oracles[_signers[i]] = Oracle(uint8(i), Role.Signer); require(s_payees[_transmitters[i]] != address(0), "payee must be set"); require( s_oracles[_transmitters[i]].role == Role.Unset, "repeated transmitter address" ); s_oracles[_transmitters[i]] = Oracle(uint8(i), Role.Transmitter); s_signers.push(_signers[i]); s_transmitters.push(_transmitters[i]); } s_hotVars.threshold = _threshold; uint32 previousConfigBlockNumber = s_latestConfigBlockNumber; s_latestConfigBlockNumber = uint32(block.number); s_configCount += 1; uint64 configCount = s_configCount; { s_hotVars.latestConfigDigest = configDigestFromConfigData( address(this), configCount, _signers, _transmitters, _threshold, _encodedConfigVersion, _encoded ); s_hotVars.latestEpochAndRound = 0; } emit ConfigSet( previousConfigBlockNumber, configCount, _signers, _transmitters, _threshold, _encodedConfigVersion, _encoded ); } function configDigestFromConfigData( address _contractAddress, uint64 _configCount, address[] calldata _signers, address[] calldata _transmitters, uint8 _threshold, uint64 _encodedConfigVersion, bytes calldata _encodedConfig ) internal pure returns (bytes16) { return bytes16(keccak256(abi.encode(_contractAddress, _configCount, _signers, _transmitters, _threshold, _encodedConfigVersion, _encodedConfig ))); } /** * @notice information about current offchain reporting protocol configuration * @return configCount ordinal number of current config, out of all configs applied to this contract so far * @return blockNumber block at which this config was set * @return configDigest domain-separation tag for current config (see configDigestFromConfigData) */ function latestConfigDetails() external view returns ( uint32 configCount, uint32 blockNumber, bytes16 configDigest ) { return (s_configCount, s_latestConfigBlockNumber, s_hotVars.latestConfigDigest); } /** * @return list of addresses permitted to transmit reports to this contract * @dev The list will match the order used to specify the transmitter during setConfig */ function transmitters() external view returns(address[] memory) { return s_transmitters; } /* * On-chain validation logc */ // Configuration for validator struct ValidatorConfig { AggregatorValidatorInterface validator; uint32 gasLimit; } ValidatorConfig private s_validatorConfig; /** * @notice indicates that the validator configuration has been set * @param previousValidator previous validator contract * @param previousGasLimit previous gas limit for validate calls * @param currentValidator current validator contract * @param currentGasLimit current gas limit for validate calls */ event ValidatorConfigSet( AggregatorValidatorInterface indexed previousValidator, uint32 previousGasLimit, AggregatorValidatorInterface indexed currentValidator, uint32 currentGasLimit ); /** * @notice validator configuration * @return validator validator contract * @return gasLimit gas limit for validate calls */ function validatorConfig() external view returns (AggregatorValidatorInterface validator, uint32 gasLimit) { ValidatorConfig memory vc = s_validatorConfig; return (vc.validator, vc.gasLimit); } /** * @notice sets validator configuration * @dev set _newValidator to 0x0 to disable validate calls * @param _newValidator address of the new validator contract * @param _newGasLimit new gas limit for validate calls */ function setValidatorConfig(AggregatorValidatorInterface _newValidator, uint32 _newGasLimit) public onlyOwner() { ValidatorConfig memory previous = s_validatorConfig; if (previous.validator != _newValidator || previous.gasLimit != _newGasLimit) { s_validatorConfig = ValidatorConfig({ validator: _newValidator, gasLimit: _newGasLimit }); emit ValidatorConfigSet(previous.validator, previous.gasLimit, _newValidator, _newGasLimit); } } function validateAnswer( uint32 _aggregatorRoundId, int256 _answer ) private { ValidatorConfig memory vc = s_validatorConfig; if (address(vc.validator) == address(0)) { return; } uint32 prevAggregatorRoundId = _aggregatorRoundId - 1; int256 prevAggregatorRoundAnswer = s_transmissions[prevAggregatorRoundId].answer; // We do not want the validator to ever prevent reporting, so we limit its // gas usage and catch any errors that may arise. try vc.validator.validate{gas: vc.gasLimit}( prevAggregatorRoundId, prevAggregatorRoundAnswer, _aggregatorRoundId, _answer ) {} catch {} } /* * requestNewRound logic */ AccessControllerInterface internal s_requesterAccessController; /** * @notice emitted when a new requester access controller contract is set * @param old the address prior to the current setting * @param current the address of the new access controller contract */ event RequesterAccessControllerSet(AccessControllerInterface old, AccessControllerInterface current); /** * @notice emitted to immediately request a new round * @param requester the address of the requester * @param configDigest the latest transmission's configDigest * @param epoch the latest transmission's epoch * @param round the latest transmission's round */ event RoundRequested(address indexed requester, bytes16 configDigest, uint32 epoch, uint8 round); /** * @notice address of the requester access controller contract * @return requester access controller address */ function requesterAccessController() external view returns (AccessControllerInterface) { return s_requesterAccessController; } /** * @notice sets the requester access controller * @param _requesterAccessController designates the address of the new requester access controller */ function setRequesterAccessController(AccessControllerInterface _requesterAccessController) public onlyOwner() { AccessControllerInterface oldController = s_requesterAccessController; if (_requesterAccessController != oldController) { s_requesterAccessController = AccessControllerInterface(_requesterAccessController); emit RequesterAccessControllerSet(oldController, _requesterAccessController); } } /** * @notice immediately requests a new round * @return the aggregatorRoundId of the next round. Note: The report for this round may have been * transmitted (but not yet mined) *before* requestNewRound() was even called. There is *no* * guarantee of causality between the request and the report at aggregatorRoundId. */ function requestNewRound() external returns (uint80) { require(msg.sender == owner || s_requesterAccessController.hasAccess(msg.sender, msg.data), "Only owner&requester can call"); HotVars memory hotVars = s_hotVars; emit RoundRequested( msg.sender, hotVars.latestConfigDigest, uint32(s_hotVars.latestEpochAndRound >> 8), uint8(s_hotVars.latestEpochAndRound) ); return hotVars.latestAggregatorRoundId + 1; } /* * Transmission logic */ /** * @notice indicates that a new report was transmitted * @param aggregatorRoundId the round to which this report was assigned * @param answer median of the observations attached this report * @param transmitter address from which the report was transmitted * @param observations observations transmitted with this report * @param rawReportContext signature-replay-prevention domain-separation tag */ event NewTransmission( uint32 indexed aggregatorRoundId, int192 answer, address transmitter, int192[] observations, bytes observers, bytes32 rawReportContext ); // decodeReport is used to check that the solidity and go code are using the // same format. See TestOffchainAggregator.testDecodeReport and TestReportParsing function decodeReport(bytes memory _report) internal pure returns ( bytes32 rawReportContext, bytes32 rawObservers, int192[] memory observations ) { (rawReportContext, rawObservers, observations) = abi.decode(_report, (bytes32, bytes32, int192[])); } // Used to relieve stack pressure in transmit struct ReportData { HotVars hotVars; // Only read from storage once bytes observers; // ith element is the index of the ith observer int192[] observations; // ith element is the ith observation bytes vs; // jth element is the v component of the jth signature bytes32 rawReportContext; } /* * @notice details about the most recent report * @return configDigest domain separation tag for the latest report * @return epoch epoch in which the latest report was generated * @return round OCR round in which the latest report was generated * @return latestAnswer median value from latest report * @return latestTimestamp when the latest report was transmitted */ function latestTransmissionDetails() external view returns ( bytes16 configDigest, uint32 epoch, uint8 round, int192 latestAnswer, uint64 latestTimestamp ) { require(msg.sender == tx.origin, "Only callable by EOA"); return ( s_hotVars.latestConfigDigest, uint32(s_hotVars.latestEpochAndRound >> 8), uint8(s_hotVars.latestEpochAndRound), s_transmissions[s_hotVars.latestAggregatorRoundId].answer, s_transmissions[s_hotVars.latestAggregatorRoundId].timestamp ); } // The constant-length components of the msg.data sent to transmit. // See the "If we wanted to call sam" example on for example reasoning // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT = 4 + // function selector 32 + // word containing start location of abiencoded _report value 32 + // word containing location start of abiencoded _rs value 32 + // word containing start location of abiencoded _ss value 32 + // _rawVs value 32 + // word containing length of _report 32 + // word containing length _rs 32 + // word containing length of _ss 0; // placeholder function expectedMsgDataLength( bytes calldata _report, bytes32[] calldata _rs, bytes32[] calldata _ss ) private pure returns (uint256 length) { // calldata will never be big enough to make this overflow return uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) + _report.length + // one byte pure entry in _report _rs.length * 32 + // 32 bytes per entry in _rs _ss.length * 32 + // 32 bytes per entry in _ss 0; // placeholder } /** * @notice transmit is called to post a new report to the contract * @param _report serialized report, which the signatures are signing. See parsing code below for format. The ith element of the observers component must be the index in s_signers of the address for the ith signature * @param _rs ith element is the R components of the ith signature on report. Must have at most maxNumOracles entries * @param _ss ith element is the S components of the ith signature on report. Must have at most maxNumOracles entries * @param _rawVs ith element is the the V component of the ith signature */ function transmit( // NOTE: If these parameters are changed, expectedMsgDataLength and/or // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly bytes calldata _report, bytes32[] calldata _rs, bytes32[] calldata _ss, bytes32 _rawVs // signatures ) external { uint256 initialGas = gasleft(); // This line must come first // Make sure the transmit message-length matches the inputs. Otherwise, the // transmitter could append an arbitrarily long (up to gas-block limit) // string of 0 bytes, which we would reimburse at a rate of 16 gas/byte, but // which would only cost the transmitter 4 gas/byte. (Appendix G of the // yellow paper, p. 25, for G_txdatazero and EIP 2028 for G_txdatanonzero.) // This could amount to reimbursement profit of 36 million gas, given a 3MB // zero tail. require(msg.data.length == expectedMsgDataLength(_report, _rs, _ss), "transmit message too long"); ReportData memory r; // Relieves stack pressure { r.hotVars = s_hotVars; // cache read from storage bytes32 rawObservers; (r.rawReportContext, rawObservers, r.observations) = abi.decode( _report, (bytes32, bytes32, int192[]) ); // rawReportContext consists of: // 11-byte zero padding // 16-byte configDigest // 4-byte epoch // 1-byte round bytes16 configDigest = bytes16(r.rawReportContext << 88); require( r.hotVars.latestConfigDigest == configDigest, "configDigest mismatch" ); uint40 epochAndRound = uint40(uint256(r.rawReportContext)); // direct numerical comparison works here, because // // ((e,r) <= (e',r')) implies (epochAndRound <= epochAndRound') // // because alphabetic ordering implies e <= e', and if e = e', then r<=r', // so e*256+r <= e'*256+r', because r, r' < 256 require(r.hotVars.latestEpochAndRound < epochAndRound, "stale report"); require(_rs.length > r.hotVars.threshold, "not enough signatures"); require(_rs.length <= maxNumOracles, "too many signatures"); require(_ss.length == _rs.length, "signatures out of registration"); require(r.observations.length <= maxNumOracles, "num observations out of bounds"); require(r.observations.length > 2 * r.hotVars.threshold, "too few values to trust median"); // Copy signature parities in bytes32 _rawVs to bytes r.v r.vs = new bytes(_rs.length); for (uint8 i = 0; i < _rs.length; i++) { r.vs[i] = _rawVs[i]; } // Copy observer identities in bytes32 rawObservers to bytes r.observers r.observers = new bytes(r.observations.length); bool[maxNumOracles] memory seen; for (uint8 i = 0; i < r.observations.length; i++) { uint8 observerIdx = uint8(rawObservers[i]); require(!seen[observerIdx], "observer index repeated"); seen[observerIdx] = true; r.observers[i] = rawObservers[i]; } Oracle memory transmitter = s_oracles[msg.sender]; require( // Check that sender is authorized to report transmitter.role == Role.Transmitter && msg.sender == s_transmitters[transmitter.index], "unauthorized transmitter" ); // record epochAndRound here, so that we don't have to carry the local // variable in transmit. The change is reverted if something fails later. r.hotVars.latestEpochAndRound = epochAndRound; } { // Verify signatures attached to report bytes32 h = keccak256(_report); bool[maxNumOracles] memory signed; Oracle memory o; for (uint i = 0; i < _rs.length; i++) { address signer = ecrecover(h, uint8(r.vs[i])+27, _rs[i], _ss[i]); o = s_oracles[signer]; require(o.role == Role.Signer, "address not authorized to sign"); require(!signed[o.index], "non-unique signature"); signed[o.index] = true; } } { // Check the report contents, and record the result for (uint i = 0; i < r.observations.length - 1; i++) { bool inOrder = r.observations[i] <= r.observations[i+1]; require(inOrder, "observations not sorted"); } int192 median = r.observations[r.observations.length/2]; require(minAnswer <= median && median <= maxAnswer, "median is out of min-max range"); r.hotVars.latestAggregatorRoundId++; s_transmissions[r.hotVars.latestAggregatorRoundId] = Transmission(median, uint64(block.timestamp)); emit NewTransmission( r.hotVars.latestAggregatorRoundId, median, msg.sender, r.observations, r.observers, r.rawReportContext ); // Emit these for backwards compatability with offchain consumers // that only support legacy events emit NewRound( r.hotVars.latestAggregatorRoundId, address(0x0), // use zero address since we don't have anybody "starting" the round here block.timestamp ); emit AnswerUpdated( median, r.hotVars.latestAggregatorRoundId, block.timestamp ); validateAnswer(r.hotVars.latestAggregatorRoundId, median); } s_hotVars = r.hotVars; assert(initialGas < maxUint32); reimburseAndRewardOracles(uint32(initialGas), r.observers); } /* * v2 Aggregator interface */ /** * @notice median from the most recent report */ function latestAnswer() public override view virtual returns (int256) { return s_transmissions[s_hotVars.latestAggregatorRoundId].answer; } /** * @notice timestamp of block in which last report was transmitted */ function latestTimestamp() public override view virtual returns (uint256) { return s_transmissions[s_hotVars.latestAggregatorRoundId].timestamp; } /** * @notice Aggregator round (NOT OCR round) in which last report was transmitted */ function latestRound() public override view virtual returns (uint256) { return s_hotVars.latestAggregatorRoundId; } /** * @notice median of report from given aggregator round (NOT OCR round) * @param _roundId the aggregator round of the target report */ function getAnswer(uint256 _roundId) public override view virtual returns (int256) { if (_roundId > 0xFFFFFFFF) { return 0; } return s_transmissions[uint32(_roundId)].answer; } /** * @notice timestamp of block in which report from given aggregator round was transmitted * @param _roundId aggregator round (NOT OCR round) of target report */ function getTimestamp(uint256 _roundId) public override view virtual returns (uint256) { if (_roundId > 0xFFFFFFFF) { return 0; } return s_transmissions[uint32(_roundId)].timestamp; } /* * v3 Aggregator interface */ string constant private V3_NO_DATA_ERROR = "No data present"; /** * @return answers are stored in fixed-point format, with this many digits of precision */ uint8 immutable public override decimals; /** * @notice aggregator contract version */ uint256 constant public override version = 4; string internal s_description; /** * @notice human-readable description of observable this contract is reporting on */ function description() public override view virtual returns (string memory) { return s_description; } /** * @notice details for the given aggregator round * @param _roundId target aggregator round (NOT OCR round). Must fit in uint32 * @return roundId _roundId * @return answer median of report from given _roundId * @return startedAt timestamp of block in which report from given _roundId was transmitted * @return updatedAt timestamp of block in which report from given _roundId was transmitted * @return answeredInRound _roundId */ function getRoundData(uint80 _roundId) public override view virtual returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { require(_roundId <= 0xFFFFFFFF, V3_NO_DATA_ERROR); Transmission memory transmission = s_transmissions[uint32(_roundId)]; return ( _roundId, transmission.answer, transmission.timestamp, transmission.timestamp, _roundId ); } /** * @notice aggregator details for the most recently transmitted report * @return roundId aggregator round of latest report (NOT OCR round) * @return answer median of latest report * @return startedAt timestamp of block containing latest report * @return updatedAt timestamp of block containing latest report * @return answeredInRound aggregator round of latest report */ function latestRoundData() public override view virtual returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { roundId = s_hotVars.latestAggregatorRoundId; // Skipped for compatability with existing FluxAggregator in which latestRoundData never reverts. // require(roundId != 0, V3_NO_DATA_ERROR); Transmission memory transmission = s_transmissions[uint32(roundId)]; return ( roundId, transmission.answer, transmission.timestamp, transmission.timestamp, roundId ); } } // File contract/src/SimpleWriteAccessController.sol pragma solidity ^0.7.0; /** * @title SimpleWriteAccessController * @notice Gives access to accounts explicitly added to an access list by the * controller's owner. * @dev does not make any special permissions for externally, see * SimpleReadAccessController for that. */ contract SimpleWriteAccessController is AccessControllerInterface, Owned { bool public checkEnabled; mapping(address => bool) internal accessList; event AddedAccess(address user); event RemovedAccess(address user); event CheckAccessEnabled(); event CheckAccessDisabled(); constructor() { checkEnabled = true; } /** * @notice Returns the access of an address * @param _user The address to query */ function hasAccess( address _user, bytes memory ) public view virtual override returns (bool) { return accessList[_user] || !checkEnabled; } /** * @notice Adds an address to the access list * @param _user The address to add */ function addAccess(address _user) external onlyOwner() { addAccessInternal(_user); } function addAccessInternal(address _user) internal { if (!accessList[_user]) { accessList[_user] = true; emit AddedAccess(_user); } } /** * @notice Removes an address from the access list * @param _user The address to remove */ function removeAccess(address _user) external onlyOwner() { if (accessList[_user]) { accessList[_user] = false; emit RemovedAccess(_user); } } /** * @notice makes the access check enforced */ function enableAccessCheck() external onlyOwner() { if (!checkEnabled) { checkEnabled = true; emit CheckAccessEnabled(); } } /** * @notice makes the access check unenforced */ function disableAccessCheck() external onlyOwner() { if (checkEnabled) { checkEnabled = false; emit CheckAccessDisabled(); } } /** * @dev reverts if the caller does not have access */ modifier checkAccess() { require(hasAccess(msg.sender, msg.data), "No access"); _; } } // File contract/src/SimpleReadAccessController.sol pragma solidity ^0.7.1; /** * @title SimpleReadAccessController * @notice Gives access to: * - any externally owned account (note that offchain actors can always read * any contract storage regardless of onchain access control measures, so this * does not weaken the access control while improving usability) * - accounts explicitly added to an access list * @dev SimpleReadAccessController is not suitable for access controlling writes * since it grants any externally owned account access! See * SimpleWriteAccessController for that. */ contract SimpleReadAccessController is SimpleWriteAccessController { /** * @notice Returns the access of an address * @param _user The address to query */ function hasAccess( address _user, bytes memory _calldata ) public view virtual override returns (bool) { return super.hasAccess(_user, _calldata) || _user == tx.origin; } } // File contract/src/AccessControlledOffchainAggregator.sol pragma solidity ^0.7.1; /** * @notice Wrapper of OffchainAggregator which checks read access on Aggregator-interface methods */ contract AccessControlledOffchainAggregator is OffchainAggregator, SimpleReadAccessController { constructor( uint32 _maximumGasPrice, uint32 _reasonableGasPrice, uint32 _microLinkPerEth, uint32 _linkGweiPerObservation, uint32 _linkGweiPerTransmission, address _link, int192 _minAnswer, int192 _maxAnswer, AccessControllerInterface _billingAccessController, AccessControllerInterface _requesterAccessController, uint8 _decimals, string memory description ) OffchainAggregator( _maximumGasPrice, _reasonableGasPrice, _microLinkPerEth, _linkGweiPerObservation, _linkGweiPerTransmission, _link, _minAnswer, _maxAnswer, _billingAccessController, _requesterAccessController, _decimals, description ) { } /* * Versioning */ function typeAndVersion() external override pure virtual returns (string memory) { return "AccessControlledOffchainAggregator 2.0.0"; } /* * v2 Aggregator interface */ /// @inheritdoc OffchainAggregator function latestAnswer() public override view checkAccess() returns (int256) { return super.latestAnswer(); } /// @inheritdoc OffchainAggregator function latestTimestamp() public override view checkAccess() returns (uint256) { return super.latestTimestamp(); } /// @inheritdoc OffchainAggregator function latestRound() public override view checkAccess() returns (uint256) { return super.latestRound(); } /// @inheritdoc OffchainAggregator function getAnswer(uint256 _roundId) public override view checkAccess() returns (int256) { return super.getAnswer(_roundId); } /// @inheritdoc OffchainAggregator function getTimestamp(uint256 _roundId) public override view checkAccess() returns (uint256) { return super.getTimestamp(_roundId); } /* * v3 Aggregator interface */ /// @inheritdoc OffchainAggregator function description() public override view checkAccess() returns (string memory) { return super.description(); } /// @inheritdoc OffchainAggregator function getRoundData(uint80 _roundId) public override view checkAccess() returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return super.getRoundData(_roundId); } /// @inheritdoc OffchainAggregator function latestRoundData() public override view checkAccess() returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return super.latestRoundData(); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint32","name":"_maximumGasPrice","type":"uint32"},{"internalType":"uint32","name":"_reasonableGasPrice","type":"uint32"},{"internalType":"uint32","name":"_microLinkPerEth","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerObservation","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerTransmission","type":"uint32"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"int192","name":"_minAnswer","type":"int192"},{"internalType":"int192","name":"_maxAnswer","type":"int192"},{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"},{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"string","name":"description","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"AddedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"current","type":"int256"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"updatedAt","type":"uint256"}],"name":"AnswerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","name":"current","type":"address"}],"name":"BillingAccessControllerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"maximumGasPrice","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"reasonableGasPrice","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"microLinkPerEth","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"linkGweiPerObservation","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"linkGweiPerTransmission","type":"uint32"}],"name":"BillingSet","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessDisabled","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"threshold","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"encodedConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":true,"internalType":"address","name":"startedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"startedAt","type":"uint256"}],"name":"NewRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"aggregatorRoundId","type":"uint32"},{"indexed":false,"internalType":"int192","name":"answer","type":"int192"},{"indexed":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"int192[]","name":"observations","type":"int192[]"},{"indexed":false,"internalType":"bytes","name":"observers","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"rawReportContext","type":"bytes32"}],"name":"NewTransmission","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OraclePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"},{"indexed":true,"internalType":"address","name":"proposed","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"RemovedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","name":"current","type":"address"}],"name":"RequesterAccessControllerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"bytes16","name":"configDigest","type":"bytes16"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"round","type":"uint8"}],"name":"RoundRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract AggregatorValidatorInterface","name":"previousValidator","type":"address"},{"indexed":false,"internalType":"uint32","name":"previousGasLimit","type":"uint32"},{"indexed":true,"internalType":"contract AggregatorValidatorInterface","name":"currentValidator","type":"address"},{"indexed":false,"internalType":"uint32","name":"currentGasLimit","type":"uint32"}],"name":"ValidatorConfigSet","type":"event"},{"inputs":[],"name":"LINK","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"addAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"billingAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBilling","outputs":[{"internalType":"uint32","name":"maximumGasPrice","type":"uint32"},{"internalType":"uint32","name":"reasonableGasPrice","type":"uint32"},{"internalType":"uint32","name":"microLinkPerEth","type":"uint32"},{"internalType":"uint32","name":"linkGweiPerObservation","type":"uint32"},{"internalType":"uint32","name":"linkGweiPerTransmission","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"hasAccess","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes16","name":"configDigest","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTransmissionDetails","outputs":[{"internalType":"bytes16","name":"configDigest","type":"bytes16"},{"internalType":"uint32","name":"epoch","type":"uint32"},{"internalType":"uint8","name":"round","type":"uint8"},{"internalType":"int192","name":"latestAnswer","type":"int192"},{"internalType":"uint64","name":"latestTimestamp","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"availableBalance","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_signerOrTransmitter","type":"address"}],"name":"oracleObservationCount","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"owedPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"removeAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestNewRound","outputs":[{"internalType":"uint80","name":"","type":"uint80"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requesterAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_maximumGasPrice","type":"uint32"},{"internalType":"uint32","name":"_reasonableGasPrice","type":"uint32"},{"internalType":"uint32","name":"_microLinkPerEth","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerObservation","type":"uint32"},{"internalType":"uint32","name":"_linkGweiPerTransmission","type":"uint32"}],"name":"setBilling","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"}],"name":"setBillingAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_signers","type":"address[]"},{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"uint8","name":"_threshold","type":"uint8"},{"internalType":"uint64","name":"_encodedConfigVersion","type":"uint64"},{"internalType":"bytes","name":"_encoded","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"address[]","name":"_payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"}],"name":"setRequesterAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AggregatorValidatorInterface","name":"_newValidator","type":"address"},{"internalType":"uint32","name":"_newGasLimit","type":"uint32"}],"name":"setValidatorConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"},{"internalType":"address","name":"_proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_report","type":"bytes"},{"internalType":"bytes32[]","name":"_rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_ss","type":"bytes32[]"},{"internalType":"bytes32","name":"_rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transmitters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"validatorConfig","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"validator","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620062cb380380620062cb83398181016040526101808110156200003957600080fd5b815160208301516040808501516060860151608087015160a088015160c089015160e08a01516101008b01516101208c01516101408d01516101608e0180519a519c9e9b9d999c989b979a969995989497939692959194939182019284640100000000821115620000a957600080fd5b908301906020820185811115620000bf57600080fd5b8251640100000000811182820188101715620000da57600080fd5b82525081516020918201929091019080838360005b8381101562000109578181015183820152602001620000ef565b50505050905090810190601f168015620001375780820380516001836020036101000a031916815260200191505b506040525050600080546001600160a01b03191633179055508b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b89620001728787878787620002b9565b6200017d81620003ab565b6001600160601b0319606083901b166080526200019962000642565b620001a362000642565b60005b601f8160ff161015620001f3576001838260ff16601f8110620001c557fe5b61ffff909216602092909202015260018260ff8316601f8110620001e557fe5b6020020152600101620001a6565b5062000203600483601f62000661565b5062000213600882601f620006fe565b505050505060f887901b7fff000000000000000000000000000000000000000000000000000000000000001660e052505083516200025c9350602f92506020850191506200072f565b50620002688362000424565b62000275600080620004fc565b50505050601791820b820b604090811b60a05290820b90910b901b60c05250506030805460ff1916600117905550620007c89e505050505050505050505050505050565b6040805160a0808201835263ffffffff88811680845288821660208086018290528984168688018190528985166060808901829052958a1660809889018190526002805463ffffffff1916871763ffffffff60201b191664010000000087021763ffffffff60401b19166801000000000000000085021763ffffffff60601b19166c0100000000000000000000000084021763ffffffff60801b1916600160801b830217905589519586529285019390935283880152928201529283015291517fd0d9486a2c673e2a4b57fc82e4c8a556b3e2b82dd5db07e2c04a920ca0f469b6929181900390910190a15050505050565b6003546001600160a01b0390811690821681146200042057600380546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d489129281900390910190a15b5050565b6000546001600160a01b0316331462000484576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602e546001600160a01b0390811690821681146200042057602e80546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae6349281900390910190a15050565b6000546001600160a01b031633146200055c576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60408051808201909152602d546001600160a01b03808216808452600160a01b90920463ffffffff1660208401528416141580620005aa57508163ffffffff16816020015163ffffffff1614155b156200063d576040805180820182526001600160a01b0385811680835263ffffffff8681166020948501819052602d80546001600160a01b031916841763ffffffff60a01b1916600160a01b8302179055865187860151875193168352948201528451919493909216927fb04e3a37abe9c0fcdfebdeae019a8e2b12ddf53f5d55ffb0caccc1bedaca1541928290030190a35b505050565b604051806103e00160405280601f906020820280368337509192915050565b600283019183908215620006ec5791602002820160005b83821115620006ba57835183826101000a81548161ffff021916908361ffff160217905550926020019260020160208160010104928301926001030262000678565b8015620006ea5782816101000a81549061ffff0219169055600201602081600101049283019260010302620006ba565b505b50620006fa929150620007b1565b5090565b82601f8101928215620006ec579160200282015b82811115620006ec57825182559160200191906001019062000712565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620007675760008555620006ec565b82601f106200078257805160ff1916838001178555620006ec565b82800160010185558215620006ec5791820182811115620006ec57825182559160200191906001019062000712565b5b80821115620006fa5760008155600101620007b2565b60805160601c60a05160401c60c05160401c60e05160f81c615a9e6200082d60003980610fc1525080611b2a52806138c6525080610f205280613899525080610efc5280612bff5280612cef5280613d0052806145225280614da15250615a9e6000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c80638da5cb5b1161019c578063bd824706116100ee578063e5fe457711610097578063f2fde38b11610071578063f2fde38b14610c7d578063fbffd2c114610ca3578063feaf968c14610cc9576102ff565b8063e5fe457714610bb3578063eb45716314610c1d578063eb5dcd6c14610c4f576102ff565b8063d09dc339116100c8578063d09dc33914610b66578063dc7f012414610b6e578063e4902f8214610b76576102ff565b8063bd824706146109e1578063c107532914610a26578063c980753914610a52576102ff565b80639c849b3011610150578063b121e1471161012a578063b121e14714610981578063b5ab58dc146109a7578063b633620c146109c4576102ff565b80639c849b30146108735780639e3ceeab14610935578063a118f2491461095b576102ff565b806398e5b12a1161018157806398e5b12a146107d1578063996e8298146107f85780639a6fc8f514610800576102ff565b80638da5cb5b146107995780638e0566de146107a1576102ff565b80636b14daf8116102555780638038e4a1116102095780638205bf6a116101e35780638205bf6a146107455780638823da6c1461074d5780638ac28d5a14610773576102ff565b80638038e4a114610694578063814118341461069c57806381ff7048146106f4576102ff565b806370efdf2d1161023a57806370efdf2d1461067c5780637284e4161461068457806379ba50971461068c576102ff565b80636b14daf8146105aa57806370da2f6714610674576102ff565b806329937268116102b757806354fd4d501161029157806354fd4d501461046d578063585aa7de14610475578063668a0f02146105a2576102ff565b80632993726814610406578063313ce5671461044757806350d25bcd14610465576102ff565b8063181f5a77116102e8578063181f5a77146103465780631b6b6d23146103c357806322adbc78146103e7576102ff565b80630a756983146103045780630eafb25b1461030e575b600080fd5b61030c610cd1565b005b6103346004803603602081101561032457600080fd5b50356001600160a01b0316610d8f565b60408051918252519081900360200190f35b61034e610eda565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610388578181015183820152602001610370565b50505050905090810190601f1680156103b55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103cb610efa565b604080516001600160a01b039092168252519081900360200190f35b6103ef610f1e565b6040805160179290920b8252519081900360200190f35b61040e610f42565b6040805163ffffffff96871681529486166020860152928516848401529084166060840152909216608082015290519081900360a00190f35b61044f610fbf565b6040805160ff9092168252519081900360200190f35b610334610fe3565b610334611084565b61030c600480360360a081101561048b57600080fd5b8101906020810181356401000000008111156104a657600080fd5b8201836020820111156104b857600080fd5b803590602001918460208302840111640100000000831117156104da57600080fd5b9193909290916020810190356401000000008111156104f857600080fd5b82018360208201111561050a57600080fd5b8035906020019184602083028401116401000000008311171561052c57600080fd5b9193909260ff8335169267ffffffffffffffff60208201351692919060608101906040013564010000000081111561056357600080fd5b82018360208201111561057557600080fd5b8035906020019184600183028401116401000000008311171561059757600080fd5b509092509050611089565b610334611a64565b610660600480360360408110156105c057600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156105eb57600080fd5b8201836020820111156105fd57600080fd5b8035906020019184600183028401116401000000008311171561061f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611b00945050505050565b604080519115158252519081900360200190f35b6103ef611b28565b6103cb611b4c565b61034e611b5b565b61030c611bf7565b61030c611cc5565b6106a4611d84565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106e05781810151838201526020016106c8565b505050509050019250505060405180910390f35b6106fc611de6565b6040805163ffffffff94851681529290931660208301527fffffffffffffffffffffffffffffffff00000000000000000000000000000000168183015290519081900360600190f35b610334611e07565b61030c6004803603602081101561076357600080fd5b50356001600160a01b0316611ea3565b61030c6004803603602081101561078957600080fd5b50356001600160a01b0316611f9a565b6103cb612011565b6107a9612020565b604080516001600160a01b03909316835263ffffffff90911660208301528051918290030190f35b6107d9612064565b6040805169ffffffffffffffffffff9092168252519081900360200190f35b6103cb6122b8565b6108296004803603602081101561081657600080fd5b503569ffffffffffffffffffff166122c7565b604051808669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1681526020019550505050505060405180910390f35b61030c6004803603604081101561088957600080fd5b8101906020810181356401000000008111156108a457600080fd5b8201836020820111156108b657600080fd5b803590602001918460208302840111640100000000831117156108d857600080fd5b9193909290916020810190356401000000008111156108f657600080fd5b82018360208201111561090857600080fd5b8035906020019184602083028401116401000000008311171561092a57600080fd5b50909250905061237c565b61030c6004803603602081101561094b57600080fd5b50356001600160a01b03166125b5565b61030c6004803603602081101561097157600080fd5b50356001600160a01b03166126a4565b61030c6004803603602081101561099757600080fd5b50356001600160a01b031661270c565b610334600480360360208110156109bd57600080fd5b5035612805565b610334600480360360208110156109da57600080fd5b50356128a2565b61030c600480360360a08110156109f757600080fd5b5063ffffffff81358116916020810135821691604082013581169160608101358216916080909101351661293f565b61030c60048036036040811015610a3c57600080fd5b506001600160a01b038135169060200135612aa5565b61030c60048036036080811015610a6857600080fd5b810190602081018135640100000000811115610a8357600080fd5b820183602082011115610a9557600080fd5b80359060200191846001830284011164010000000083111715610ab757600080fd5b919390929091602081019035640100000000811115610ad557600080fd5b820183602082011115610ae757600080fd5b80359060200191846020830284011164010000000083111715610b0957600080fd5b919390929091602081019035640100000000811115610b2757600080fd5b820183602082011115610b3957600080fd5b80359060200191846020830284011164010000000083111715610b5b57600080fd5b919350915035612df2565b610334613cfb565b610660613dac565b610b9c60048036036020811015610b8c57600080fd5b50356001600160a01b0316613db5565b6040805161ffff9092168252519081900360200190f35b610bbb613e62565b604080517fffffffffffffffffffffffffffffffff00000000000000000000000000000000909616865263ffffffff909416602086015260ff9092168484015260170b606084015267ffffffffffffffff166080830152519081900360a00190f35b61030c60048036036040811015610c3357600080fd5b5080356001600160a01b0316906020013563ffffffff16613f51565b61030c60048036036040811015610c6557600080fd5b506001600160a01b03813581169160200135166140e6565b61030c60048036036020811015610c9357600080fd5b50356001600160a01b0316614241565b61030c60048036036020811015610cb957600080fd5b50356001600160a01b0316614309565b610829614371565b6000546001600160a01b03163314610d30576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60305460ff1615610d8d57603080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b6001600160a01b03811660009081526027602090815260408083208151808301909252805460ff808216845285948401916101009004166002811115610dd157fe5b6002811115610ddc57fe5b9052509050600081602001516002811115610df357fe5b1415610e03576000915050610ed5565b6040805160a08101825260025463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c01000000000000000000000000810483166060830181905270010000000000000000000000000000000090910490921660808201528251909160009160019060049060ff16601f8110610e8e57fe5b601091828204019190066002029054906101000a900461ffff160361ffff1602633b9aca0002905060016008846000015160ff16601f8110610ecc57fe5b01540301925050505b919050565b6060604051806060016040528060288152602001615a4160289139905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6040805160a08101825260025463ffffffff808216808452640100000000830482166020850181905268010000000000000000840483169585018690526c01000000000000000000000000840483166060860181905270010000000000000000000000000000000090940490921660809094018490529490939290565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000611026336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b611077576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61107f614424565b905090565b600481565b868560ff8616601f8311156110e5576040805162461bcd60e51b815260206004820152601060248201527f746f6f206d616e79207369676e65727300000000000000000000000000000000604482015290519081900360640190fd5b6000811161113a576040805162461bcd60e51b815260206004820152601a60248201527f7468726573686f6c64206d75737420626520706f736974697665000000000000604482015290519081900360640190fd5b8183146111785760405162461bcd60e51b8152600401808060200182810382526024815260200180615a1d6024913960400191505060405180910390fd5b8060030283116111cf576040805162461bcd60e51b815260206004820181905260248201527f6661756c74792d6f7261636c65207468726573686f6c6420746f6f2068696768604482015290519081900360640190fd5b6000546001600160a01b0316331461122e576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602854156113d257602880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101916000918390811061126b57fe5b6000918252602082200154602980546001600160a01b039092169350908490811061129257fe5b6000918252602090912001546001600160a01b031690506112b281614460565b6001600160a01b0380831660009081526027602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009081169091559284168252902080549091169055602880548061130e57fe5b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055602980548061137157fe5b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190555061122e915050565b60005b8a8110156117e0576000602760008e8e858181106113ef57fe5b602090810292909201356001600160a01b031683525081019190915260400160002054610100900460ff16600281111561142557fe5b14611477576040805162461bcd60e51b815260206004820152601760248201527f7265706561746564207369676e65722061646472657373000000000000000000604482015290519081900360640190fd5b6040805180820190915260ff8216815260016020820152602760008e8e8581811061149e57fe5b602090810292909201356001600160a01b031683525081810192909252604001600020825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff9091161780825591830151909182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600281111561152957fe5b02179055506000915060069050818c8c8581811061154357fe5b6001600160a01b03602091820293909301358316845283019390935260409091016000205416919091141590506115c1576040805162461bcd60e51b815260206004820152601160248201527f7061796565206d75737420626520736574000000000000000000000000000000604482015290519081900360640190fd5b6000602760008c8c858181106115d357fe5b602090810292909201356001600160a01b031683525081019190915260400160002054610100900460ff16600281111561160957fe5b1461165b576040805162461bcd60e51b815260206004820152601c60248201527f7265706561746564207472616e736d6974746572206164647265737300000000604482015290519081900360640190fd5b6040805180820190915260ff8216815260026020820152602760008c8c8581811061168257fe5b602090810292909201356001600160a01b031683525081810192909252604001600020825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff9091161780825591830151909182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010083600281111561170d57fe5b021790555090505060288c8c8381811061172357fe5b835460018101855560009485526020948590200180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03959092029390930135939093169290921790555060298a8a8381811061178557fe5b835460018181018655600095865260209586902090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03969093029490940135949094161790915550016113d5565b50602a805460ff89167501000000000000000000000000000000000000000000027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff909116179055602c80544363ffffffff9081166401000000009081027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff84161780831660010183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009091161793849055909104811691166118ac30828f8f8f8f8f8f8f8f61468a565b602a60000160006101000a8154816fffffffffffffffffffffffffffffffff021916908360801c02179055506000602a60000160106101000a81548164ffffffffff021916908364ffffffffff1602179055507f25d719d88a4512dd76c7442b910a83360845505894eb444ef299409e180f8fb982828f8f8f8f8f8f8f8f604051808b63ffffffff1681526020018a67ffffffffffffffff16815260200180602001806020018760ff1681526020018667ffffffffffffffff1681526020018060200184810384528c8c82818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810384528a8152602090810191508b908b0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810383528681526020019050868680828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039f50909d5050505050505050505050505050a150505050505050505050505050565b6000611aa7336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b611af8576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61107f6147ca565b6000611b0c83836147f0565b80611b1f57506001600160a01b03831632145b90505b92915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b602e546001600160a01b031690565b6060611b9e336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b611bef576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61107f614820565b6001546001600160a01b03163314611c56576040805162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000546001600160a01b03163314611d24576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60305460ff16610d8d57603080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b60606029805480602002602001604051908101604052809291908181526020018280548015611ddc57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611dbe575b5050505050905090565b602c54602a5463ffffffff808316926401000000009004169060801b909192565b6000611e4a336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b611e9b576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61107f6148cb565b6000546001600160a01b03163314611f02576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6001600160a01b03811660009081526031602052604090205460ff1615611f97576001600160a01b03811660008181526031602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055815192835290517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d19281900390910190a15b50565b6001600160a01b03818116600090815260066020526040902054163314612008576040805162461bcd60e51b815260206004820152601760248201527f4f6e6c792070617965652063616e207769746864726177000000000000000000604482015290519081900360640190fd5b611f9781614460565b6000546001600160a01b031681565b60408051808201909152602d546001600160a01b0381168083527401000000000000000000000000000000000000000090910463ffffffff16602090920182905291565b600080546001600160a01b031633148061215e5750602e54604080517f6b14daf800000000000000000000000000000000000000000000000000000000815233600482018181526024830193845236604484018190526001600160a01b0390951694636b14daf894929360009391929190606401848480828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201965060209550909350505081840390508186803b15801561213157600080fd5b505afa158015612145573d6000803e3d6000fd5b505050506040513d602081101561215b57600080fd5b50515b6121af576040805162461bcd60e51b815260206004820152601d60248201527f4f6e6c79206f776e6572267265717565737465722063616e2063616c6c000000604482015290519081900360640190fd5b6040805160808082018352602a549081901b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016808352700100000000000000000000000000000000820464ffffffffff81166020808601919091527501000000000000000000000000000000000000000000840460ff9081168688015276010000000000000000000000000000000000000000000090940463ffffffff9081166060808801919091528751948552600884901c909116918401919091529216818501529251919233927f3ea16a923ff4b1df6526e854c9e3a995c43385d70e73359e10623c74f0b52037929181900390910190a2806060015160010163ffffffff1691505090565b6003546001600160a01b031690565b6000806000806000612310336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b612361576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b61236a86614926565b939a9299509097509550909350915050565b6000546001600160a01b031633146123db576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b82811461242f576040805162461bcd60e51b815260206004820181905260248201527f7472616e736d6974746572732e73697a6520213d207061796565732e73697a65604482015290519081900360640190fd5b60005b838110156125ae57600085858381811061244857fe5b905060200201356001600160a01b03169050600084848481811061246857fe5b6001600160a01b0385811660009081526006602090815260409091205492029390930135831693509091169050801580806124b45750826001600160a01b0316826001600160a01b0316145b612505576040805162461bcd60e51b815260206004820152601160248201527f706179656520616c726561647920736574000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b03848116600090815260066020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168583169081179091559083161461259e57826001600160a01b0316826001600160a01b0316856001600160a01b03167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a45b5050600190920191506124329050565b5050505050565b6000546001600160a01b03163314612614576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b602e546001600160a01b0390811690821681146126a057602e80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03848116918217909255604080519284168352602083019190915280517f27b89aede8b560578baaa25ee5ce3852c5eecad1e114b941bbd89e1eb4bae6349281900390910190a15b5050565b6000546001600160a01b03163314612703576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b611f9781614a71565b6001600160a01b0381811660009081526007602052604090205416331461277a576040805162461bcd60e51b815260206004820152601f60248201527f6f6e6c792070726f706f736564207061796565732063616e2061636365707400604482015290519081900360640190fd5b6001600160a01b0381811660008181526006602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556007909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b6000612848336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b612899576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611b2282614b0a565b60006128e5336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b612936576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611b2282614b40565b6003546000546001600160a01b039182169116331480612a375750604080517f6b14daf800000000000000000000000000000000000000000000000000000000815233600482018181526024830193845236604484018190526001600160a01b03861694636b14daf8946000939190606401848480828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201965060209550909350505081840390508186803b158015612a0a57600080fd5b505afa158015612a1e573d6000803e3d6000fd5b505050506040513d6020811015612a3457600080fd5b50515b612a88576040805162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c604482015290519081900360640190fd5b612a90614b95565b612a9d8686868686614f5a565b505050505050565b6000546001600160a01b0316331480612b9e5750600354604080517f6b14daf800000000000000000000000000000000000000000000000000000000815233600482018181526024830193845236604484018190526001600160a01b0390951694636b14daf894929360009391929190606401848480828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909201965060209550909350505081840390508186803b158015612b7157600080fd5b505afa158015612b85573d6000803e3d6000fd5b505050506040513d6020811015612b9b57600080fd5b50515b612bef576040805162461bcd60e51b815260206004820181905260248201527f4f6e6c79206f776e65722662696c6c696e6741646d696e2063616e2063616c6c604482015290519081900360640190fd5b6000612bf96150d4565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612c6a57600080fd5b505afa158015612c7e573d6000803e3d6000fd5b505050506040513d6020811015612c9457600080fd5b5051905081811015612ced576040805162461bcd60e51b815260206004820152601460248201527f696e73756666696369656e742062616c616e6365000000000000000000000000604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb85612d29858503876152a4565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612d6f57600080fd5b505af1158015612d83573d6000803e3d6000fd5b505050506040513d6020811015612d9957600080fd5b5051612dec576040805162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b50505050565b60005a9050612e058888888888886152bb565b3614612e58576040805162461bcd60e51b815260206004820152601960248201527f7472616e736d6974206d65737361676520746f6f206c6f6e6700000000000000604482015290519081900360640190fd5b612e606158b2565b6040805160808082018352602a549081901b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252700100000000000000000000000000000000810464ffffffffff1660208301527501000000000000000000000000000000000000000000810460ff169282019290925276010000000000000000000000000000000000000000000090910463ffffffff166060808301919091529082526000908a908a90811015612f1957600080fd5b813591602081013591810190606081016040820135640100000000811115612f4057600080fd5b820183602082011115612f5257600080fd5b80359060200191846020830284011164010000000083111715612f7457600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050505060408801525050506080840182905283515190925060589190911b907fffffffffffffffffffffffffffffffff0000000000000000000000000000000080831691161461303b576040805162461bcd60e51b815260206004820152601560248201527f636f6e666967446967657374206d69736d617463680000000000000000000000604482015290519081900360640190fd5b608083015183516020015164ffffffffff8083169116106130a3576040805162461bcd60e51b815260206004820152600c60248201527f7374616c65207265706f72740000000000000000000000000000000000000000604482015290519081900360640190fd5b83516040015160ff1689116130ff576040805162461bcd60e51b815260206004820152601560248201527f6e6f7420656e6f756768207369676e6174757265730000000000000000000000604482015290519081900360640190fd5b601f891115613155576040805162461bcd60e51b815260206004820152601360248201527f746f6f206d616e79207369676e61747572657300000000000000000000000000604482015290519081900360640190fd5b8689146131a9576040805162461bcd60e51b815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e0000604482015290519081900360640190fd5b601f8460400151511115613204576040805162461bcd60e51b815260206004820152601e60248201527f6e756d206f62736572766174696f6e73206f7574206f6620626f756e64730000604482015290519081900360640190fd5b83600001516040015160020260ff168460400151511161326b576040805162461bcd60e51b815260206004820152601e60248201527f746f6f206665772076616c75657320746f207472757374206d656469616e0000604482015290519081900360640190fd5b8867ffffffffffffffff8111801561328257600080fd5b506040519080825280601f01601f1916602001820160405280156132ad576020820181803683370190505b50606085015260005b60ff81168a111561331e57868160ff16602081106132d057fe5b1a60f81b85606001518260ff16815181106132e757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016132b6565b5083604001515167ffffffffffffffff8111801561333b57600080fd5b506040519080825280601f01601f191660200182016040528015613366576020820181803683370190505b5060208501526133746158e6565b60005b8560400151518160ff16101561347a576000858260ff166020811061339857fe5b1a90508281601f81106133a757fe5b6020020151156133fe576040805162461bcd60e51b815260206004820152601760248201527f6f6273657276657220696e646578207265706561746564000000000000000000604482015290519081900360640190fd5b6001838260ff16601f811061340f57fe5b91151560209283029190910152869060ff841690811061342b57fe5b1a60f81b87602001518360ff168151811061344257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050600101613377565b503360009081526027602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156134b857fe5b60028111156134c357fe5b90525090506002816020015160028111156134da57fe5b14801561350e57506029816000015160ff16815481106134f657fe5b6000918252602090912001546001600160a01b031633145b61355f576040805162461bcd60e51b815260206004820152601860248201527f756e617574686f72697a6564207472616e736d69747465720000000000000000604482015290519081900360640190fd5b5050835164ffffffffff90911660209091015250506040516000908a908a9080838380828437604051920182900390912094506135a093506158e692505050565b6135a8615905565b60005b898110156137bf576000600185876060015184815181106135c857fe5b60209101015160f81c601b018e8e868181106135e057fe5b905060200201358d8d878181106135f357fe5b9050602002013560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561364e573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101516001600160a01b03811660009081526027602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156136bb57fe5b60028111156136c657fe5b90525092506001836020015160028111156136dd57fe5b1461372f576040805162461bcd60e51b815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e0000604482015290519081900360640190fd5b8251849060ff16601f811061374057fe5b602002015115613797576040805162461bcd60e51b815260206004820152601460248201527f6e6f6e2d756e69717565207369676e6174757265000000000000000000000000604482015290519081900360640190fd5b600184846000015160ff16601f81106137ac57fe5b91151560209092020152506001016135ab565b5050505060005b600182604001515103811015613870576000826040015182600101815181106137eb57fe5b602002602001015160170b8360400151838151811061380657fe5b602002602001015160170b1315905080613867576040805162461bcd60e51b815260206004820152601760248201527f6f62736572766174696f6e73206e6f7420736f72746564000000000000000000604482015290519081900360640190fd5b506001016137c6565b5060408101518051600091906002810490811061388957fe5b602002602001015190508060170b7f000000000000000000000000000000000000000000000000000000000000000060170b131580156138ef57507f000000000000000000000000000000000000000000000000000000000000000060170b8160170b13155b613940576040805162461bcd60e51b815260206004820152601e60248201527f6d656469616e206973206f7574206f66206d696e2d6d61782072616e67650000604482015290519081900360640190fd5b81516060908101805163ffffffff60019091018116909152604080518082018252601785810b80835267ffffffffffffffff42811660208086019182528a5189015188166000908152602b82528781209651875493519094167801000000000000000000000000000000000000000000000000029390950b77ffffffffffffffffffffffffffffffffffffffffffffffff9081167fffffffffffffffff0000000000000000000000000000000000000000000000009093169290921790911691909117909355875186015184890151848a01516080808c015188519586523386890181905291860181905260a0988601898152845199870199909952835194909916997ff6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451998c999298949793969095909492939185019260c086019289820192909102908190849084905b83811015613aa3578181015183820152602001613a8b565b50505050905001838103825285818151815260200191508051906020019080838360005b83811015613adf578181015183820152602001613ac7565b50505050905090810190601f168015613b0c5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a281516060015160408051428152905160009263ffffffff16917f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271919081900360200190a381600001516060015163ffffffff168160170b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a3613bc18260000151606001518260170b6152d3565b5080518051602a8054602084015160408501516060909501517fffffffffffffffffffffffffffffffff0000000000000000000000000000000090921660809490941c939093177fffffffffffffffffffffff0000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000064ffffffffff90941693909302929092177fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000060ff90941693909302929092177fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff1676010000000000000000000000000000000000000000000063ffffffff92831602179091558210613ce257fe5b613cf0828260200151615413565b505050505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613d6b57600080fd5b505afa158015613d7f573d6000803e3d6000fd5b505050506040513d6020811015613d9557600080fd5b505190506000613da36150d4565b90910391505090565b60305460ff1681565b6001600160a01b03811660009081526027602090815260408083208151808301909252805460ff808216845285948401916101009004166002811115613df757fe5b6002811115613e0257fe5b9052509050600081602001516002811115613e1957fe5b1415613e29576000915050610ed5565b60016004826000015160ff16601f8110613e3f57fe5b601091828204019190066002029054906101000a900461ffff1603915050919050565b600080808080333214613ebc576040805162461bcd60e51b815260206004820152601460248201527f4f6e6c792063616c6c61626c6520627920454f41000000000000000000000000604482015290519081900360640190fd5b5050602a5463ffffffff760100000000000000000000000000000000000000000000820481166000908152602b6020526040902054608083901b96700100000000000000000000000000000000909304600881901c909216955064ffffffffff9091169350601781900b92507801000000000000000000000000000000000000000000000000900467ffffffffffffffff1690565b6000546001600160a01b03163314613fb0576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60408051808201909152602d546001600160a01b038082168084527401000000000000000000000000000000000000000090920463ffffffff166020840152841614158061400e57508163ffffffff16816020015163ffffffff1614155b156140e1576040805180820182526001600160a01b0385811680835263ffffffff8681166020948501819052602d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001684177fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000008302179055865187860151875193168352948201528451919493909216927fb04e3a37abe9c0fcdfebdeae019a8e2b12ddf53f5d55ffb0caccc1bedaca1541928290030190a35b505050565b6001600160a01b03828116600090815260066020526040902054163314614154576040805162461bcd60e51b815260206004820152601d60248201527f6f6e6c792063757272656e742070617965652063616e20757064617465000000604482015290519081900360640190fd5b336001600160a01b03821614156141b2576040805162461bcd60e51b815260206004820152601760248201527f63616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b6001600160a01b03808316600090815260076020526040902080548383167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092559091169081146140e1576040516001600160a01b038084169133918616907f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836790600090a4505050565b6000546001600160a01b031633146142a0576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000546001600160a01b03163314614368576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b611f9781615660565b60008060008060006143ba336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b0092505050565b61440b576040805162461bcd60e51b815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6144136156ef565b945094509450945094509091929394565b602a54760100000000000000000000000000000000000000000000900463ffffffff166000908152602b6020526040902054601790810b900b90565b6001600160a01b03811660009081526027602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156144a657fe5b60028111156144b157fe5b905250905060006144c183610d8f565b905080156140e1576001600160a01b0380841660009081526006602090815260408083205481517fa9059cbb0000000000000000000000000000000000000000000000000000000081529085166004820181905260248201879052915191947f0000000000000000000000000000000000000000000000000000000000000000169363a9059cbb9360448084019491939192918390030190829087803b15801561456a57600080fd5b505af115801561457e573d6000803e3d6000fd5b505050506040513d602081101561459457600080fd5b50516145e7576040805162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b60016004846000015160ff16601f81106145fd57fe5b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060016008846000015160ff16601f811061463857fe5b0155604080516001600160a01b0380871682528316602082015280820184905290517fe8ec50e5150ae28ae37e493ff389ffab7ffaec2dc4dccfca03f12a3de29d12b29181900360600190a150505050565b60008a8a8a8a8a8a8a8a8a8a604051602001808b6001600160a01b031681526020018a67ffffffffffffffff16815260200180602001806020018760ff1681526020018667ffffffffffffffff1681526020018060200184810384528c8c82818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810384528a8152602090810191508b908b0280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910185810383528681526020019050868680828437600081840152601f19601f8201169050808301925050509d50505050505050505050505050506040516020818303038152906040528051906020012090509a9950505050505050505050565b602a54760100000000000000000000000000000000000000000000900463ffffffff1690565b6001600160a01b03821660009081526031602052604081205460ff1680611b1f57505060305460ff161592915050565b602f8054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015611ddc5780601f1061489f57610100808354040283529160200191611ddc565b820191906000526020600020905b8154815290600101906020018083116148ad57509395945050505050565b602a54760100000000000000000000000000000000000000000000900463ffffffff166000908152602b60205260409020547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1690565b600080600080600063ffffffff8669ffffffffffffffffffff1611156040518060400160405280600f81526020017f4e6f20646174612070726573656e74000000000000000000000000000000000081525090614a015760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156149c65781810151838201526020016149ae565b50505050905090810190601f1680156149f35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5050505063ffffffff83166000908152602b6020908152604091829020825180840190935254601781810b810b810b808552780100000000000000000000000000000000000000000000000090920467ffffffffffffffff1693909201839052949594900b939092508291508490565b6001600160a01b03811660009081526031602052604090205460ff16611f97576001600160a01b03811660008181526031602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055815192835290517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49281900390910190a150565b600063ffffffff821115614b2057506000610ed5565b5063ffffffff166000908152602b6020526040902054601790810b900b90565b600063ffffffff821115614b5657506000610ed5565b5063ffffffff166000908152602b60205260409020547801000000000000000000000000000000000000000000000000900467ffffffffffffffff1690565b6040805160a08101825260025463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000082048116606084015270010000000000000000000000000000000090910416608082015281516103e0810192839052909160009190600490601f908285855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411614c1a575050604080516103e0810191829052959650600095945060089350601f9250905082845b815481526020019060010190808311614c74575050505050905060006029805480602002602001604051908101604052809291908181526020018280548015614ce657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311614cc8575b5050505050905060005b8151811015614f3e57600060018483601f8110614d0957fe5b6020020151039050600060018684601f8110614d2157fe5b60200201510361ffff169050600082886060015163ffffffff168302633b9aca00020190506000811115614f3357600060066000878781518110614d6157fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b031690507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb82846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015614e1657600080fd5b505af1158015614e2a573d6000803e3d6000fd5b505050506040513d6020811015614e4057600080fd5b5051614e93576040805162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b60018886601f8110614ea157fe5b61ffff909216602092909202015260018786601f8110614ebd57fe5b602002015285517fe8ec50e5150ae28ae37e493ff389ffab7ffaec2dc4dccfca03f12a3de29d12b290879087908110614ef257fe5b6020026020010151828460405180846001600160a01b03168152602001836001600160a01b03168152602001828152602001935050505060405180910390a1505b505050600101614cf0565b50614f4c600484601f61591c565b506125ae600883601f6159b2565b6040805160a0808201835263ffffffff88811680845288821660208086018290528984168688018190528985166060808901829052958a166080988901819052600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001687177fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff166401000000008702177fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff16680100000000000000008502177fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c010000000000000000000000008402177fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000830217905589519586529285019390935283880152928201529283015291517fd0d9486a2c673e2a4b57fc82e4c8a556b3e2b82dd5db07e2c04a920ca0f469b6929181900390910190a15050505050565b604080516103e0810191829052600091829190600490601f908285855b82829054906101000a900461ffff1661ffff16815260200190600201906020826001010492830192600103820291508084116150f15790505050505050905060005b601f8110156151615760018282601f811061514a57fe5b60200201510361ffff169290920191600101615133565b506040805160a08101825260025463ffffffff8082168352640100000000820481166020808501919091526801000000000000000083048216848601526c01000000000000000000000000830482166060850181905270010000000000000000000000000000000090930490911660808401526029805485518184028101840190965280865296909202633b9aca000295929360009390929183018282801561523357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311615215575b5050604080516103e0810191829052949550600094935060089250601f915082845b815481526020019060010190808311615255575050505050905060005b825181101561529c5760018282601f811061528957fe5b6020020151039590950194600101615272565b505050505090565b6000818310156152b5575081611b22565b50919050565b602083810286019082020160e4019695505050505050565b60408051808201909152602d546001600160a01b0381168083527401000000000000000000000000000000000000000090910463ffffffff16602083015261531b57506126a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830163ffffffff8181166000818152602b602090815260408083205487518884015183517fbeed9b510000000000000000000000000000000000000000000000000000000081526004810197909752601792830b90920b602487018190528b88166044880152606487018b9052925192966001600160a01b039091169563beed9b51959290911693608480830194919391928390030190829088803b1580156153e457600080fd5b5087f19350505050801561540a57506040513d602081101561540557600080fd5b505160015b612a9d576125ae565b3360009081526027602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561545057fe5b600281111561545b57fe5b9052506040805160a08101825260025463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c0100000000000000000000000082048116606084015270010000000000000000000000000000000090910416608082015281516103e08101928390529293509161552b91859190600490601f90826000855b82829054906101000a900461ffff1661ffff16815260200190600201906020826001010492830192600103820291508084116154e95790505050505050615773565b61553990600490601f61591c565b5060028260200151600281111561554c57fe5b1461559e576040805162461bcd60e51b815260206004820181905260248201527f73656e7420627920756e64657369676e61746564207472616e736d6974746572604482015290519081900360640190fd5b60006155c5633b9aca003a04836020015163ffffffff16846000015163ffffffff166157e8565b90506010360260005a905060006155e48863ffffffff1685858561580e565b6fffffffffffffffffffffffffffffffff1690506000620f4240866040015163ffffffff1683028161561257fe5b049050856080015163ffffffff16633b9aca0002816008896000015160ff16601f811061563b57fe5b015401016008886000015160ff16601f811061565357fe5b0155505050505050505050565b6003546001600160a01b0390811690821681146126a057600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03848116918217909255604080519284168352602083019190915280517f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d489129281900390910190a15050565b602a54760100000000000000000000000000000000000000000000900463ffffffff166000818152602b6020908152604091829020825180840190935254601781810b810b810b808552780100000000000000000000000000000000000000000000000090920467ffffffffffffffff1693909201839052929392900b9181908490565b61577b6158e6565b60005b83518110156157e057600084828151811061579557fe5b016020015160f81c90506157ba8482601f81106157ae57fe5b6020020151600161589a565b848260ff16601f81106157c957fe5b61ffff90921660209290920201525060010161577e565b509092915050565b600083838110156157fb57600285850304015b61580581846152a4565b95945050505050565b600081851015615865576040805162461bcd60e51b815260206004820181905260248201527f6761734c6566742063616e6e6f742065786365656420696e697469616c476173604482015290519081900360640190fd5b818503830161179301633b9aca00858202026fffffffffffffffffffffffffffffffff811061589057fe5b9695505050505050565b6000611b1f8261ffff168461ffff160161ffff6152a4565b6040518060a001604052806158c56159e0565b81526060602082018190526040820181905280820152600060809091015290565b604051806103e00160405280601f906020820280368337509192915050565b604080518082019091526000808252602082015290565b6002830191839082156159a25791602002820160005b8382111561597257835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302615932565b80156159a05782816101000a81549061ffff0219169055600201602081600101049283019260010302615972565b505b506159ae929150615a07565b5090565b82601f81019282156159a2579160200282015b828111156159a25782518255916020019190600101906159c5565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b808211156159ae5760008155600101615a0856fe6f7261636c6520616464726573736573206f7574206f6620726567697374726174696f6e416363657373436f6e74726f6c6c65644f6666636861696e41676772656761746f7220322e302e30a2646970667358221220ecb65e2069c65f54ce04dfa871092389f10ea3417b6b718ee60553278f7cca8a64736f6c6343000706003300000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000ed020000000000000000000000000000000000000000000000000000000000007148000000000000000000000000000000000000000000000000000000000002ab98000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000494e19780c3fe5b2a61ee6d6380fea4b408a2c070000000000000000000000006a9f4359350172ac4b1d4132639fe23f9562d778000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000009455448202f205553440000000000000000000000000000000000000000000000
Deployed ByteCode Sourcemap
66968:3011:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65395:168;;;:::i;:::-;;17071:494;;;;;;;;;;;;;;;;-1:-1:-1;17071:494:0;-1:-1:-1;;;;;17071:494:0;;:::i;:::-;;;;;;;;;;;;;;;;67870:171;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7363:40;;;:::i;:::-;;;;-1:-1:-1;;;;;7363:40:0;;;;;;;;;;;;;;36342:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;14692:489;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60944:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;68132:144;;;:::i;61047:44::-;;;:::i;40689:2024::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40689:2024:0;;-1:-1:-1;40689:2024:0;-1:-1:-1;40689:2024:0;:::i;68515:143::-;;;:::i;66536:220::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66536:220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66536:220:0;;-1:-1:-1;66536:220:0;;-1:-1:-1;;;;;66536:220:0:i;:::-;;;;;;;;;;;;;;;;;;36462:33;;;:::i;47700:152::-;;;:::i;69166:149::-;;;:::i;4318:264::-;;;:::i;65161:166::-;;;:::i;44009:118::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43564:254;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68320:151;;;:::i;64911:184::-;;;;;;;;;;;;;;;;-1:-1:-1;64911:184:0;-1:-1:-1;;;;;64911:184:0;;:::i;16761:179::-;;;;;;;;;;;;;;;;-1:-1:-1;16761:179:0;-1:-1:-1;;;;;16761:179:0;;:::i;3658:28::-;;;:::i;45058:224::-;;;:::i;:::-;;;;-1:-1:-1;;;;;45058:224:0;;;;;;;;;;;;;;;;;;;;;;48821:474;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16415:148;;;:::i;69359:294::-;;;;;;;;;;;;;;;;-1:-1:-1;69359:294:0;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31286:705;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31286:705:0;;-1:-1:-1;31286:705:0;-1:-1:-1;31286:705:0;:::i;48025:446::-;;;;;;;;;;;;;;;;-1:-1:-1;48025:446:0;-1:-1:-1;;;;;48025:446:0;;:::i;64538:92::-;;;;;;;;;;;;;;;;-1:-1:-1;64538:92:0;-1:-1:-1;;;;;64538:92:0;;:::i;32996:395::-;;;;;;;;;;;;;;;;-1:-1:-1;32996:395:0;-1:-1:-1;;;;;32996:395:0;;:::i;68702:162::-;;;;;;;;;;;;;;;;-1:-1:-1;68702:162:0;;:::i;68908:169::-;;;;;;;;;;;;;;;;-1:-1:-1;68908:169:0;;:::i;13563:562::-;;;;;;;;;;;;;;;;-1:-1:-1;13563:562:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;24482:481::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;24482:481:0;;;;;;;;:::i;53612:5508::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53612:5508:0;-1:-1:-1;53612:5508:0;;:::i;26626:511::-;;;:::i;63867:24::-;;;:::i;27322:286::-;;;;;;;;;;;;;;;;-1:-1:-1;27322:286:0;-1:-1:-1;;;;;27322:286:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;51226:572;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45531:508;;;;;;;;;;;;;;;;-1:-1:-1;45531:508:0;;-1:-1:-1;;;;;45531:508:0;;;;;;;;:::i;32250:514::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;32250:514:0;;;;;;;;;;:::i;4067:157::-;;;;;;;;;;;;;;;;-1:-1:-1;4067:157:0;-1:-1:-1;;;;;4067:157:0;;:::i;16101:193::-;;;;;;;;;;;;;;;;-1:-1:-1;16101:193:0;-1:-1:-1;;;;;16101:193:0;;:::i;69697:277::-;;;:::i;65395:168::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;65470:12:::1;::::0;::::1;;65466:92;;;65493:12;:20:::0;;;::::1;::::0;;65529:21:::1;::::0;::::1;::::0;65508:5:::1;::::0;65529:21:::1;65466:92;65395:168::o:0;17071:494::-;-1:-1:-1;;;;;17192:23:0;;17150:7;17192:23;;;:9;:23;;;;;;;;17169:46;;;;;;;;;;;;;;;;17150:7;;17169:46;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17169:46:0;-1:-1:-1;17241:10:0;17226:6;:11;;;:25;;;;;;;;;17222:44;;;17262:1;17255:8;;;;;17222:44;17272:34;;;;;;;;17297:9;17272:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17379:12;;17272:34;;:22;;:34;;;;17352:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;17344:53;;:102;17457:6;17344:120;17313:151;;17531:1;17488:26;17515:6;:12;;;17488:40;;;;;;;;;;;:44;17471:61;;-1:-1:-1;;;17071:494:0;;;;:::o;67870:171::-;67961:13;67986:49;;;;;;;;;;;;;;;;;;;67870:171;:::o;7363:40::-;;;:::o;36342:33::-;;;:::o;14692:489::-;14942:34;;;;;;;;14967:9;14942:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14692:489::o;60944:40::-;;;:::o;68132:144::-;68225:6;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;68250:20:::1;:18;:20::i;:::-;68243:27;;68132:144:::0;:::o;61047:44::-;61090:1;61047:44;:::o;40689:2024::-;40910:8;40927:13;39799:428;;;6649:2;39918:28;;;39910:57;;;;;-1:-1:-1;;;39910:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;39995:1;39982:10;:14;39974:53;;;;;-1:-1:-1;;;39974:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;40065:16;40050:11;:31;40034:101;;;;-1:-1:-1;;;40034:101:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40166:10;40164:1;:12;40150:11;:26;40142:71;;;;;-1:-1:-1;;;40142:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4722:5:::1;::::0;-1:-1:-1;;;;;4722:5:0::1;4708:10;:19;4700:54;;;::::0;;-1:-1:-1;;;4700:54:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;40995:9:::2;:16:::0;:21;40988:382:::2;;41089:9;:16:::0;;:20;;;;41074:12:::2;::::0;41089:20;;41135:18;::::2;;;;;;::::0;;;::::2;::::0;;::::2;::::0;41184:14:::2;:23:::0;;-1:-1:-1;;;;;41135:18:0;;::::2;::::0;-1:-1:-1;41184:14:0;41199:7;;41184:23;::::2;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;-1:-1:-1;;;;;41184:23:0::2;::::0;-1:-1:-1;41216:22:0::2;41184:23:::0;41216:9:::2;:22::i;:::-;-1:-1:-1::0;;;;;41254:17:0;;::::2;;::::0;;;:9:::2;:17;::::0;;;;;41247:24;;;;;;;;;41287:22;;::::2;::::0;;;;41280:29;;;;;;;41318:9:::2;:15:::0;;;::::2;;;;;::::0;;;::::2;::::0;;;;;;;;;;;::::2;::::0;;;;;41342:14:::2;:20:::0;;;::::2;;;;;::::0;;;::::2;::::0;;;;;;;;;;;::::2;::::0;;;;;-1:-1:-1;40988:382:0::2;::::0;-1:-1:-1;;40988:382:0::2;;41383:6;41378:624;41395:19:::0;;::::2;41378:624;;;41519:10;41488:9;:22;41498:8;;41507:1;41498:11;;;;;;;;::::0;;::::2;::::0;;;::::2;;-1:-1:-1::0;;;;;41498:11:0::2;41488:22:::0;;-1:-1:-1;41488:22:0;::::2;::::0;;;;;;-1:-1:-1;41488:22:0;:27;::::2;::::0;::::2;;;:41;::::0;::::2;;;;;;;41470:104;;;::::0;;-1:-1:-1;;;41470:104:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;41608:29;::::0;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;;41625:11:::2;41608:29;::::0;::::2;::::0;41583:9:::2;-1:-1:-1::0;41593:8:0;;41608:29;41593:11;;::::2;;;;;;::::0;;::::2;::::0;;;::::2;;-1:-1:-1::0;;;;;41593:11:0::2;41583:22:::0;;-1:-1:-1;41583:22:0;;::::2;::::0;;;;;;-1:-1:-1;41583:22:0;:54;;;;;::::2;;::::0;;::::2;;::::0;;;;;::::2;::::0;:22;;;;:54;::::2;;::::0;::::2;::::0;::::2;;;;;;;;::::0;;-1:-1:-1;41692:1:0::2;::::0;-1:-1:-1;41654:8:0::2;::::0;-1:-1:-1;41692:1:0;41663:13;;41677:1;41663:16;;::::2;;;;;-1:-1:-1::0;;;;;41663:16:0::2;::::0;;::::2;::::0;;;::::2;;::::0;::::2;41654:26:::0;;;::::2;::::0;;;;;;;;-1:-1:-1;41654:26:0;;::::2;:40:::0;;;::::2;;::::0;-1:-1:-1;41646:70:0::2;;;::::0;;-1:-1:-1;;;41646:70:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;41779:10;41743:9;:27;41753:13;;41767:1;41753:16;;;;;;;;::::0;;::::2;::::0;;;::::2;;-1:-1:-1::0;;;;;41753:16:0::2;41743:27:::0;;-1:-1:-1;41743:27:0;::::2;::::0;;;;;;-1:-1:-1;41743:27:0;:32;::::2;::::0;::::2;;;:46;::::0;::::2;;;;;;;41725:114;;;::::0;;-1:-1:-1;;;41725:114:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;41878:34;::::0;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;;41895:16:::2;41878:34;::::0;::::2;::::0;41848:9:::2;-1:-1:-1::0;41858:13:0;;41878:34;41858:16;;::::2;;;;;;::::0;;::::2;::::0;;;::::2;;-1:-1:-1::0;;;;;41858:16:0::2;41848:27:::0;;-1:-1:-1;41848:27:0;;::::2;::::0;;;;;;-1:-1:-1;41848:27:0;:64;;;;;::::2;;::::0;;::::2;;::::0;;;;;::::2;::::0;:27;;;;:64;::::2;;::::0;::::2;::::0;::::2;;;;;;;;;;;;;;41921:9;41936:8;;41945:1;41936:11;;;;;;;41921:27:::0;;::::2;::::0;::::2;::::0;;-1:-1:-1;41921:27:0;;;41936:11:::2;41921:27:::0;;;;::::2;::::0;;;::::2;-1:-1:-1::0;;;;;41936:11:0;;;::::2;::::0;;;::::2;;::::0;;;::::2;41921:27:::0;;;::::2;::::0;;-1:-1:-1;41957:14:0::2;41977:13:::0;;41991:1;41977:16;;::::2;;;;;41957:37:::0;;::::2;::::0;;::::2;::::0;;-1:-1:-1;41957:37:0;;;41977:16:::2;41957:37:::0;;;;;;::::2;::::0;;;::::2;-1:-1:-1::0;;;;;41977:16:0;;;::::2;::::0;;;::::2;;::::0;;;::::2;41957:37;::::0;;;-1:-1:-1;41416:3:0::2;41378:624;;;-1:-1:-1::0;42008:9:0::2;:32:::0;;::::2;::::0;::::2;::::0;::::2;::::0;;;::::2;;::::0;;42082:25:::2;::::0;;42149:12:::2;42082:25;42114:48:::0;;::::2;42082:25:::0;42114:48;;::::2;::::0;;::::2;;42169:18:::0;;::::2;-1:-1:-1::0;42169:18:0::2;::::0;::::2;::::0;;;::::2;;::::0;;;;42082:25;;::::2;::::0;::::2;::::0;42215:13:::2;42275:196;42320:4;42215:13:::0;42358:8;;42377:13;;42030:10;42422:21;42454:8;;42275:26:::2;:196::i;:::-;42244:9;:28;;;:227;;;;;;;;;;;;;;;;;;42512:1;42480:9;:29;;;:33;;;;;;;;;;;;;;;;;;42532:175;42550:25;42584:11;42604:8;;42621:13;;42643:10;42662:21;42692:8;;42532:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;;::::0;::::2;::::0;;::::2;::::0;;::::2;::::0;;;;;::::2;::::0;;::::2;::::0;-1:-1:-1;42532:175:0;;;::::2;::::0;;;::::2;;::::0;;::::2;::::0;::::2;;::::0;::::2;::::0;;::::2;::::0;;::::2;::::0;;;;;::::2;;::::0;-1:-1:-1;42532:175:0;;;;;::::2;;::::0;;::::2;::::0;::::2;::::0;::::2;::::0;;::::2;::::0;::::2;::::0;;::::2;::::0;;::::2;::::0;-1:-1:-1;42532:175:0;;-1:-1:-1;;;;;;;;;;;;;;42532:175:0::2;4761:1;;40689:2024:::0;;;;;;;;;;;:::o;68515:143::-;68607:7;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;68633:19:::1;:17;:19::i;66536:220::-:0;66672:4;66695:33;66711:5;66718:9;66695:15;:33::i;:::-;:55;;;-1:-1:-1;;;;;;66732:18:0;;66741:9;66732:18;66695:55;66688:62;;66536:220;;;;;:::o;36462:33::-;;;:::o;47700:152::-;47819:27;;-1:-1:-1;;;;;47819:27:0;47700:152;:::o;69166:149::-;69258:13;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;69290:19:::1;:17;:19::i;4318:264::-:0;4391:12;;-1:-1:-1;;;;;4391:12:0;4377:10;:26;4369:61;;;;;-1:-1:-1;;;4369:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;4439:16;4458:5;;4478:10;4470:18;;;;;;;;-1:-1:-1;4495:25:0;;;;;;;4534:42;;-1:-1:-1;;;;;4458:5:0;;;;4478:10;;4458:5;;4534:42;;;4318:264;:::o;65161:166::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;65236:12:::1;::::0;::::1;;65231:91;;65259:12;:19:::0;;;::::1;65274:4;65259:19;::::0;;65294:20:::1;::::0;::::1;::::0;65259:12:::1;::::0;65294:20:::1;65161:166::o:0;44009:118::-;44070:16;44107:14;44100:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;44100:21:0;;;;;;;;;;;;;;;;;;;;;;;44009:118;:::o;43564:254::-;43741:13;;43783:9;:28;43741:13;;;;;43756:25;;;;;43783:28;;43564:254;;;:::o;68320:151::-;68416:7;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;68442:23:::1;:21;:23::i;64911:184::-:0;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64993:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;::::1;;64989:101;;;-1:-1:-1::0;;;;;65021:17:0;::::1;65041:5;65021:17:::0;;;:10:::1;:17;::::0;;;;;;;;:25;;;::::1;::::0;;65062:20;;;;;;;::::1;::::0;;;;;;;;::::1;64989:101;64911:184:::0;:::o;16761:179::-;-1:-1:-1;;;;;16854:22:0;;;;;;;:8;:22;;;;;;;16840:10;:36;16832:72;;;;;-1:-1:-1;;;16832:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;16911:23;16921:12;16911:9;:23::i;3658:28::-;;;-1:-1:-1;;;;;3658:28:0;;:::o;45058:224::-;45190:45;;;;;;;;;45218:17;45190:45;-1:-1:-1;;;;;45190:45:0;;;;;;;;;;;;;;;;;;;45058:224::o;48821:474::-;48866:6;48903:5;;-1:-1:-1;;;;;48903:5:0;48889:10;:19;;:82;;-1:-1:-1;48912:27:0;;:59;;;;;;48950:10;48912:59;;;;;;;;;;;;48962:8;48912:59;;;;;;-1:-1:-1;;;;;48912:27:0;;;;:37;;48950:10;;48912:27;;48962:8;;48912:59;;;;:27;48962:8;;48912:27;:59;;;;;;;;;;;;;;;;;;;-1:-1:-1;48912:59:0;;-1:-1:-1;48912:59:0;;-1:-1:-1;;;48912:59:0;;;;-1:-1:-1;48912:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48912:59:0;48889:82;48881:131;;;;;-1:-1:-1;;;48881:131:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;49021:34;;;;;;;;;49046:9;49021:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49069:171;;;;;49186:1;49153:34;;;;;;49069:171;;;;;;;;;;;;;;;49021:34;;49092:10;;49069:171;;;;;;;;;;;49254:7;:31;;;49288:1;49254:35;49247:42;;;;;48821:474;:::o;16415:148::-;16532:25;;-1:-1:-1;;;;;16532:25:0;16415:148;:::o;69359:294::-;69475:14;69498:13;69520:17;69546;69572:22;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;69619:28:::1;69638:8;69619:18;:28::i;:::-;69612:35:::0;;;;-1:-1:-1;69612:35:0;;-1:-1:-1;69612:35:0;-1:-1:-1;69612:35:0;;-1:-1:-1;69359:294:0;-1:-1:-1;;69359:294:0:o;31286:705::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;31431:38;;::::1;31423:83;;;::::0;;-1:-1:-1;;;31423:83:0;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;31520:6;31515:471;31532:24:::0;;::::1;31515:471;;;31572:19;31594:13;;31608:1;31594:16;;;;;;;;;;;;;-1:-1:-1::0;;;;;31594:16:0::1;31572:38;;31619:13;31635:7;;31643:1;31635:10;;;;;;;-1:-1:-1::0;;;;;31677:21:0;;::::1;31654:20;31677:21:::0;;;:8:::1;31635:10;31677:21:::0;;;;;;;;31635:10;::::1;::::0;;;::::1;;::::0;::::1;::::0;-1:-1:-1;31677:21:0;;::::1;::::0;-1:-1:-1;31724:26:0;;;;31767:34:::1;;;31796:5;-1:-1:-1::0;;;;;31780:21:0::1;:12;-1:-1:-1::0;;;;;31780:21:0::1;;31767:34;31759:64;;;::::0;;-1:-1:-1;;;31759:64:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;31832:21:0;;::::1;;::::0;;;:8:::1;:21;::::0;;;;:29;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;31876:21;;::::1;;31872:107;;31963:5;-1:-1:-1::0;;;;;31915:54:0::1;31949:12;-1:-1:-1::0;;;;;31915:54:0::1;31936:11;-1:-1:-1::0;;;;;31915:54:0::1;;;;;;;;;;;31872:107;-1:-1:-1::0;;31558:3:0::1;::::0;;::::1;::::0;-1:-1:-1;31515:471:0::1;::::0;-1:-1:-1;31515:471:0::1;;;31286:705:::0;;;;:::o;48025:446::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48198:27:::1;::::0;-1:-1:-1;;;;;48198:27:0;;::::1;::::0;48236:43;::::1;::::0;::::1;48232:234;;48290:27;:83:::0;;;::::1;-1:-1:-1::0;;;;;48290:83:0;;::::1;::::0;;::::1;::::0;;;48387:71:::1;::::0;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;;;;;;;::::1;48232:234;4761:1;48025:446:::0;:::o;64538:92::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;64600:24:::1;64618:5;64600:17;:24::i;32996:395::-:0;-1:-1:-1;;;;;33099:30:0;;;;;;;:16;:30;;;;;;;33085:10;:44;33077:88;;;;;-1:-1:-1;;;33077:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33197:22:0;;;33174:20;33197:22;;;:8;:22;;;;;;;;;;33251:10;33226:35;;;;;;;;;33268:16;:30;;;;;;:43;;;;;;;;33325:60;;33197:22;;;33251:10;;33197:22;;;;33325:60;;33174:20;33325:60;32996:395;;:::o;68702:162::-;68808:6;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;68833:25:::1;68849:8;68833:15;:25::i;68908:169::-:0;69017:7;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;69043:28:::1;69062:8;69043:18;:28::i;13563:562::-:0;13815:25;;13780:32;13869:5;-1:-1:-1;;;;;13815:25:0;;;;13869:5;13855:10;:19;;:61;;-1:-1:-1;13878:38:0;;;;;;13895:10;13878:38;;;;;;;;;;;;13907:8;13878:38;;;;;;-1:-1:-1;;;;;13878:16:0;;;;;13907:8;;13878:38;;;;13907:8;;;;13878:38;;;;;;;;;;;;;;;;;;;-1:-1:-1;13878:38:0;;-1:-1:-1;13878:38:0;;-1:-1:-1;;;13878:38:0;;;;-1:-1:-1;13878:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13878:38:0;13855:61;13847:113;;;;;-1:-1:-1;;;13847:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13967:12;:10;:12::i;:::-;13986:133;14005:16;14023:19;14044:16;14069:23;14094:24;13986:18;:133::i;:::-;13563:562;;;;;;:::o;24482:481::-;24588:5;;-1:-1:-1;;;;;24588:5:0;24574:10;:19;;:80;;-1:-1:-1;24597:25:0;;:57;;;;;;24633:10;24597:57;;;;;;;;;;;;24645:8;24597:57;;;;;;-1:-1:-1;;;;;24597:25:0;;;;:35;;24633:10;;24597:25;;24645:8;;24597:57;;;;:25;24645:8;;24597:25;:57;;;;;;;;;;;;;;;;;;;-1:-1:-1;24597:57:0;;-1:-1:-1;24597:57:0;;-1:-1:-1;;;24597:57:0;;;;-1:-1:-1;24597:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24597:57:0;24574:80;24566:132;;;;;-1:-1:-1;;;24566:132:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24705:15;24723:14;:12;:14::i;:::-;24705:32;;24744:19;24766:4;-1:-1:-1;;;;;24766:14:0;;24789:4;24766:29;;;;;;;;;;;;;-1:-1:-1;;;;;24766:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24766:29:0;;-1:-1:-1;24810:22:0;;;;24802:55;;;;;-1:-1:-1;;;24802:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;24872:4;-1:-1:-1;;;;;24872:13:0;;24886:10;24898:35;24916:7;24902:11;:21;24925:7;24898:3;:35::i;:::-;24872:62;;;;;;;;;;;;;-1:-1:-1;;;;;24872:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24872:62:0;24864:93;;;;;-1:-1:-1;;;24864:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;24482:481;;;;:::o;53612:5508::-;53929:18;53950:9;53929:30;;54520:40;54542:7;;54551:3;;54556;;54520:21;:40::i;:::-;54501:8;:59;54493:104;;;;;-1:-1:-1;;;54493:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54604:19;;:::i;:::-;54666:21;;;;;;;;;54678:9;54666:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54828:7:0;;;;54807:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;54789:14:0;;;54754:120;-1:-1:-1;;;54755:18:0;;;54754:120;;;55118:9;;:28;54754:120;;-1:-1:-1;55088:2:0;55066:24;;;;;55118:44;;;;;;;55100:105;;;;;-1:-1:-1;;;55100:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55254:18;;;;55581:9;;:29;;;:45;;;;;;;55573:70;;;;;-1:-1:-1;;;55573:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55675:9;;:19;;;55662:32;;;;55654:66;;;;;-1:-1:-1;;;55654:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6649:2;55737:27;;;55729:59;;;;;-1:-1:-1;;;55729:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55805:24;;;55797:67;;;;;-1:-1:-1;;;55797:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;6649:2;55881:1;:14;;;:21;:38;;55873:96;;;;;-1:-1:-1;;;55873:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56014:1;:9;;;:19;;;56010:1;:23;55986:47;;:1;:14;;;:21;:47;55978:105;;;;;-1:-1:-1;;;55978:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56176:3;56166:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56166:21:0;-1:-1:-1;56159:4:0;;;:28;56201:7;56196:79;56214:14;;;;-1:-1:-1;56196:79:0;;;56256:6;56263:1;56256:9;;;;;;;;;;;;56246:1;:4;;;56251:1;56246:7;;;;;;;;;;;;;:19;;;;;;;;;;-1:-1:-1;56230:3:0;;56196:79;;;;56389:1;:14;;;:21;56379:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56379:32:0;-1:-1:-1;56365:11:0;;;:46;56420:31;;:::i;:::-;56465:7;56460:256;56482:1;:14;;;:21;56478:1;:25;;;56460:256;;;56521:17;56547:12;56560:1;56547:15;;;;;;;;;;;-1:-1:-1;56583:4:0;56547:15;56583:17;;;;;;;;;;;56582:18;56574:54;;;;;-1:-1:-1;;;56574:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56659:4;56639;56644:11;56639:17;;;;;;;;;:24;;;:17;;;;;;;;:24;56691:12;;:15;;;;;;;;;;;;;56674:1;:11;;;56686:1;56674:14;;;;;;;;;;;;;:32;;;;;;;;;;-1:-1:-1;;56505:3:0;;56460:256;;;-1:-1:-1;56764:10:0;56726:25;56754:21;;;:9;:21;;;;;;;;56726:49;;;;;;;;;;;;;;;;;;56754:21;;56726:49;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56726:49:0;-1:-1:-1;56867:16:0;56847:11;:16;;;:36;;;;;;;;;:96;;;;;56910:14;56925:11;:17;;;56910:33;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56910:33:0;56896:10;:47;56847:96;56784:205;;;;;-1:-1:-1;;;56784:205:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57157:9:0;;:45;;;;:29;;;;:45;-1:-1:-1;;57279:18:0;;57157:9;;57289:7;;;;57279:18;57289:7;;;;57279:18;;;;;;;;;;;;;-1:-1:-1;57306:33:0;;-1:-1:-1;57306:33:0;;-1:-1:-1;;;57306:33:0:i;:::-;57350:15;;:::i;:::-;57379:6;57374:323;57391:14;;;57374:323;;;57423:14;57440:47;57450:1;57459;:4;;;57464:1;57459:7;;;;;;;;;;;;;;;57468:2;57453:17;57472:3;;57476:1;57472:6;;;;;;;;;;;;;57480:3;;57484:1;57480:6;;;;;;;;;;;;;57440:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57440:47:0;;;;;;;-1:-1:-1;;;;;57502:17:0;;;;;;:9;57440:47;57502:17;;;;;;;57498:21;;;;;;;;;;;;;;57440:47;;-1:-1:-1;57440:47:0;;-1:-1:-1;57498:21:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57498:21:0;-1:-1:-1;57548:11:0;57538:1;:6;;;:21;;;;;;;;;57530:64;;;;;-1:-1:-1;;;57530:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57621:7;;57614:6;;:15;;;;;;;;;;;;;57613:16;57605:49;;;;;-1:-1:-1;;;57605:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57683:4;57665:6;57672:1;:7;;;57665:15;;;;;;;;;:22;;;:15;;;;;:22;-1:-1:-1;57407:3:0;;57374:323;;;;53612:5508;;;57778:6;57773:183;57818:1;57794;:14;;;:21;:25;57790:1;:29;57773:183;;;57837:12;57873:1;:14;;;57888:1;57890;57888:3;57873:19;;;;;;;;;;;;;;57852:40;;:1;:14;;;57867:1;57852:17;;;;;;;;;;;;;;:40;;;;57837:55;;57911:7;57903:43;;;;;-1:-1:-1;;;57903:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57821:3:0;;57773:183;;;-1:-1:-1;57982:14:0;;;;57997:21;;57966:13;;57982:14;58019:1;57997:23;;;57982:39;;;;;;;;;;;;57966:55;;58051:6;58038:19;;:9;:19;;;;:42;;;;;58071:9;58061:19;;:6;:19;;;;58038:42;58030:85;;;;;-1:-1:-1;;;58030:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;58124:9;;:33;;;;:35;;;;;;;;;;;;58230:45;;;;;;;;;;;;;;;;58258:15;58230:45;;-1:-1:-1;58230:45:0;;;;;;58184:9;;:33;;;58168:50;;58124:9;58168:50;;;:15;:50;;;;;:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58317:9;;:33;;;58399:14;;;;58424:11;;;;58446:18;;;;;58291:182;;;;;58378:10;58291:182;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58243:6;;58378:10;;58399:14;;58424:11;;58446:18;;58291:182;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58621:9;;:33;;;58602:184;;;58762:15;58602:184;;;;58673:3;;58602:184;;;;;;;;;;;;;58841:1;:9;;;:33;;;58800:109;;58824:6;58800:109;;;58885:15;58800:109;;;;;;;;;;;;;;;;;;58920:57;58935:1;:9;;;:33;;;58970:6;58920:57;;:14;:57::i;:::-;-1:-1:-1;59003:9:0;;58991:21;;:9;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59026:22;;59019:30;;;;59056:58;59089:10;59102:1;:11;;;59056:25;:58::i;:::-;53612:5508;;;;;;;;;:::o;26626:511::-;26699:23;26799:14;26823:4;-1:-1:-1;;;;;26823:14:0;;26846:4;26823:29;;;;;;;;;;;;;-1:-1:-1;;;;;26823:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26823:29:0;;-1:-1:-1;27001:10:0;27021:14;:12;:14::i;:::-;27102:29;;;;-1:-1:-1;;26626:511:0;:::o;63867:24::-;;;;;;:::o;27322:286::-;-1:-1:-1;;;;;27463:31:0;;27422:6;27463:31;;;:9;:31;;;;;;;;27440:54;;;;;;;;;;;;;;;;27422:6;;27440:54;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27440:54:0;-1:-1:-1;27520:10:0;27505:6;:11;;;:25;;;;;;;;;27501:44;;;27541:1;27534:8;;;;;27501:44;27601:1;27558:26;27585:6;:12;;;27558:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;27551:51;;;27322:286;;;:::o;51226:572::-;51309:20;;;;;51455:10;51469:9;51455:23;51447:56;;;;;-1:-1:-1;;;51447:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51526:9:0;:28;51570:34;51675:33;;;;;51526:28;51659:50;;;:15;:50;;;;;:57;51526:28;;;;;51570:29;;;;51603:1;51570:34;;;;;;;-1:-1:-1;51570:29:0;;;;;-1:-1:-1;51659:57:0;;;;;-1:-1:-1;51725:60:0;;;;;;51226:572::o;45531:508::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45663:51:::1;::::0;;;;::::1;::::0;;;45697:17:::1;45663:51:::0;-1:-1:-1;;;;;45663:51:0;;::::1;::::0;;;;;;::::1;;;;::::0;::::1;::::0;45727:35;::::1;;;::::0;:72:::1;;;45787:12;45766:33;;:8;:17;;;:33;;;;45727:72;45723:311;;;45830:94;::::0;;;;::::1;::::0;;-1:-1:-1;;;;;45830:94:0;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;;::::1;::::0;;;45810:17:::1;:114:::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;::::0;;45959:18;;45979:17;;::::1;::::0;45940:86;;;::::1;::::0;;;;::::1;::::0;;;45830:94;;45940:86;;;::::1;::::0;::::1;::::0;;;;;;::::1;45723:311;4761:1;45531:508:::0;;:::o;32250:514::-;-1:-1:-1;;;;;32381:22:0;;;;;;;:8;:22;;;;;;;32367:10;:36;32359:78;;;;;-1:-1:-1;;;32359:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;32454:10;-1:-1:-1;;;;;32454:23:0;;;;32446:59;;;;;-1:-1:-1;;;32446:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32543:30:0;;;32516:24;32543:30;;;:16;:30;;;;;;;32582:42;;;;;;;;;;;32543:30;;;;32639:29;;32635:124;;32686:63;;-1:-1:-1;;;;;32686:63:0;;;;32727:10;;32686:63;;;;;;;;32250:514;;;:::o;4067:157::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;4148:12:::1;:18:::0;;;::::1;-1:-1:-1::0;;;;;4148:18:0;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;4207:5:0;;4180:38:::1;::::0;4148:18;;4207:5:::1;::::0;4180:38:::1;::::0;-1:-1:-1;4180:38:0::1;4067:157:::0;:::o;16101:193::-;4722:5;;-1:-1:-1;;;;;4722:5:0;4708:10;:19;4700:54;;;;;-1:-1:-1;;;4700:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;16228:60:::1;16263:24;16228:34;:60::i;69697:277::-:0;69801:14;69824:13;69846:17;69872;69898:22;65675:31;65685:10;65697:8;;65675:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65675:9:0;;-1:-1:-1;;;65675:31:0:i;:::-;65667:53;;;;;-1:-1:-1;;;65667:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;69945:23:::1;:21;:23::i;:::-;69938:30;;;;;;;;;;69697:277:::0;;;;;:::o;59234:175::-;59362:9;:33;;;;;;59321:6;59346:50;;;:15;:50;;;;;:57;;;;;59339:64;;;59234:175::o;17997:682::-;-1:-1:-1;;;;;18085:23:0;;18062:20;18085:23;;;:9;:23;;;;;;;;18062:46;;;;;;;;;;;;;;;;;;18085:23;;18062:46;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18062:46:0;-1:-1:-1;18115:21:0;18139:25;18151:12;18139:11;:25::i;:::-;18115:49;-1:-1:-1;18175:17:0;;18171:503;;-1:-1:-1;;;;;18219:22:0;;;18203:13;18219:22;;;:8;:22;;;;;;;;;18358:35;;;;;18219:22;;;18358:35;;;;;;;;;;;;;;18219:22;;18358:4;:13;;;;:35;;;;;18219:22;;18358:35;;;;;;;;;;:13;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18358:35:0;18350:66;;;;;-1:-1:-1;;;18350:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;18468:1;18425:26;18452:6;:12;;;18425:40;;;;;;;;;;;;;;;;;;;;:44;;;;;;;;;;;;;;;;;;18563:1;18520:26;18547:6;:12;;;18520:40;;;;;;;;;;:44;18620:46;;;-1:-1:-1;;;;;18620:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;18171:503;17997:682;;;:::o;42719:468::-;43007:7;43059:16;43077:12;43098:8;;43108:13;;43123:10;43135:21;43158:14;;43048:131;;;;;;-1:-1:-1;;;;;43048:131:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43048:131:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43048:131:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43038:142;;;;;;43023:158;;42719:468;;;;;;;;;;;;:::o;59785:151::-;59897:9;:33;;;;;;;59785:151::o;64242:189::-;-1:-1:-1;;;;;64391:17:0;;64368:4;64391:17;;;:10;:17;;;;;;;;;:34;;-1:-1:-1;;64413:12:0;;;;64412:13;;64242:189;-1:-1:-1;;64242:189:0:o;61233:137::-;61351:13;61344:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61319:13;;61344:20;;61351:13;;61344:20;;61351:13;61344:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61344:20:0;;61233:137;-1:-1:-1;;;;;61233:137:0:o;59499:182::-;59631:9;:33;;;;;;59589:7;59615:50;;;:15;:50;;;;;:60;;;;;;;59499:182::o;61843:522::-;61953:14;61976:13;61998:17;62024;62050:22;62110:10;62098:8;:22;;;;62122:16;;;;;;;;;;;;;;;;;62090:49;;;;;-1:-1:-1;;;62090:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;62181:33:0;;;62146:32;62181:33;;;:15;:33;;;;;;;;;62146:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62181:33;;62221:138;;;;62146:68;;-1:-1:-1;62146:68:0;;-1:-1:-1;62181:33:0;;61843:522::o;64636:160::-;-1:-1:-1;;;;;64699:17:0;;;;;;:10;:17;;;;;;;;64694:97;;-1:-1:-1;;;;;64727:17:0;;;;;;:10;:17;;;;;;;;;:24;;;;64747:4;64727:24;;;64765:18;;;;;;;;;;;;;;;;;64636:160;:::o;60095:217::-;60195:6;60228:10;60217:8;:21;60213:40;;;-1:-1:-1;60249:1:0;60242:8;;60213:40;-1:-1:-1;60266:33:0;;;;;;:15;:33;;;;;:40;;;;;60259:47;;;60095:217::o;60497:224::-;60600:7;60634:10;60623:8;:21;60619:40;;;-1:-1:-1;60655:1:0;60648:8;;60619:40;-1:-1:-1;60672:33:0;;;;;;:15;:33;;;;;:43;;;;;;;60497:224::o;18875:1404::-;18921:34;;;;;;;;18946:9;18921:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18962:76;;;;;;;;;18921:34;;-1:-1:-1;;18962:76:0;18921:34;;18962:76;;18921:34;-1:-1:-1;18962:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;19045:90:0;;;;;;;;;;18962:76;;-1:-1:-1;;;19045:90:0;-1:-1:-1;19109:26:0;;-1:-1:-1;19045:90:0;;-1:-1:-1;19045:90:0;-1:-1:-1;19109:26:0;19045:90;;;;;;;;;;;;;;;;;;;;;;;;19142:29;19174:14;19142:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19142:46:0;;;;;;;;;;;;;;;;;;;;;;;19200:19;19195:917;19242:12;:19;19225:14;:36;19195:917;;;19290:34;19370:1;19327:24;19352:14;19327:40;;;;;;;;;;;:44;19290:81;;19380:16;19436:1;19399:18;19418:14;19399:34;;;;;;;;;;;:38;19380:57;;;;19446:21;19543:26;19498:7;:30;;;19490:39;;19479:8;:50;19533:6;19479:61;:90;19446:123;;19598:1;19582:13;:17;19578:527;;;19614:13;19630:8;:38;19639:12;19652:14;19639:28;;;;;;;;;;;;;;-1:-1:-1;;;;;19630:38:0;-1:-1:-1;;;;;19630:38:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19630:38:0;19614:54;;19797:4;-1:-1:-1;;;;;19797:13:0;;19811:5;19818:13;19797:35;;;;;;;;;;;;;-1:-1:-1;;;;;19797:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19797:35:0;19789:66;;;;;-1:-1:-1;;;19789:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;19905:1;19868:18;19887:14;19868:34;;;;;;;:38;;;;:34;;;;;;:38;19990:1;19947:24;19972:14;19947:40;;;;;;;;;;:44;20042:28;;20031:62;;20042:12;;20055:14;;20042:28;;;;;;;;;;;;20072:5;20079:13;20031:62;;;;-1:-1:-1;;;;;20031:62:0;;;;;;-1:-1:-1;;;;;20031:62:0;;;;;;;;;;;;;;;;;;;;;;19578:527;;-1:-1:-1;;;19263:16:0;;19195:917;;;-1:-1:-1;20166:47:0;:26;20195:18;20166:47;;:::i;:::-;-1:-1:-1;20220:53:0;:26;20249:24;20220:53;;:::i;12427:502::-;12664:122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12652:9;:134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12798:125;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12427:502;;;;;:::o;25023:1373::-;25670:75;;;;;;;;;;-1:-1:-1;;;;25670:75:0;25719:26;;25670:75;;25719:26;-1:-1:-1;25670:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25757:6;25752:142;6649:2;25769:1;:17;25752:142;;;25836:1;25813:17;25831:1;25813:20;;;;;;;;;;;:24;25802:35;;;;;;;25788:3;;25752:142;;;-1:-1:-1;25900:34:0;;;;;;;;25925:9;25900:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26111:14;26079:46;;;;;;;;;;;;;;;;;26011:61;;;;26065:6;26011:61;;25900:34;;:22;;26079:46;;26111:14;26079:46;;26111:14;26079:46;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26079:46:0;;;;;;;;;;;;;;;;-1:-1:-1;;26132:90:0;;;;;;;;;;26079:46;;-1:-1:-1;;;26132:90:0;-1:-1:-1;26196:26:0;;-1:-1:-1;26132:90:0;;-1:-1:-1;26196:26:0;26132:90;;;;;;;;;;;;;;;;;;;;;;;;26234:6;26229:162;26250:12;:19;26246:1;:23;26229:162;;;26332:1;26304:24;26329:1;26304:27;;;;;;;;;;;:29;26285:49;;;;;26271:3;;26229:162;;;;25023:1373;;;;;:::o;33608:136::-;33681:7;33708:1;33704;:5;33700:24;;;-1:-1:-1;33720:1:0;33713:8;;33700:24;-1:-1:-1;33737:1:0;33608:136;-1:-1:-1;33608:136:0:o;52503:481::-;52921:2;52854:15;;;52735:134;;52908:15;;;52735:188;52085:396;52735:188;52503:481;;;;;;;;:::o;46045:687::-;46150:45;;;;;;;;;46178:17;46150:45;-1:-1:-1;;;;;46150:45:0;;;;;;;;;;;;;;;46204:64;;46254:7;;;46204:64;46307:22;;;46371:38;;;;46276:28;46371:38;;;:15;:38;;;;;;;;:45;46562:12;;46589:11;;;;46562:153;;;;;;;;;;;;46371:45;;;;46336:80;;;46562:153;;;;;;;;;;;;;;;;;;;;;46336:80;;-1:-1:-1;;;;;46562:21:0;;;;;;:153;;;;;;;;;;46371:38;;46562:153;;;;;;;;;:21;:153;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46562:153:0;;;46558:169;;;;27616:2403;27768:10;27733:22;27758:21;;;:9;:21;;;;;;;;27733:46;;;;;;;;;;;;;;;;;;27758:21;;27733:46;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27786:34:0;;;;;;;;27811:9;27786:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28010:52;;;;;;;;;27733:46;;-1:-1:-1;27786:34:0;28010:52;;28024:9;;28010:52;27786:34;;28010:52;;27786:34;-1:-1:-1;28010:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:52::i;:::-;27974:88;;:26;;:88;;:::i;:::-;-1:-1:-1;28152:16:0;28135:8;:13;;;:33;;;;;;;;;28127:91;;;;;-1:-1:-1;;;28127:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28225:16;28244:149;28283:6;28268:11;:22;28328:7;:26;;;28244:149;;28363:7;:23;;;28244:149;;:15;:149::i;:::-;28225:168;-1:-1:-1;28583:2:0;28588:8;28583:20;28557:23;28736:9;28718:27;;28752:21;28776:116;28817:10;28809:19;;28837:8;28854:15;28878:7;28776:24;:116::i;:::-;28752:140;;;;29279:22;29347:3;29321:7;:23;;;29305:39;;:13;:39;29304:46;;;;;;29279:71;;29700:7;:31;;;29692:40;;29736:6;29692:51;29668:14;29623:26;29650:8;:14;;;29623:42;;;;;;;;;;;:59;:120;29571:26;29598:8;:14;;;29571:42;;;;;;;;;;:172;-1:-1:-1;;;;;;;;;27616:2403:0:o;15496:423::-;15658:25;;-1:-1:-1;;;;;15658:25:0;;;;15694:41;;;;15690:224;;15746:25;:52;;;;-1:-1:-1;;;;;15746:52:0;;;;;;;;;15812:94;;;;;;;;;;;;;;;;;;;;;;;;;;;15496:423;;:::o;62776:657::-;63021:9;:33;;;;;;62874:14;63252:32;;;:15;:32;;;;;;;;;63217:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63021:33;;63291:136;;;;63217:67;;63021:33;;62776:657::o;20285:477::-;20428:28;;:::i;:::-;20539:11;20534:197;20565:9;:16;20556:6;:25;20534:197;;;20602:14;20625:9;20635:6;20625:17;;;;;;;;;;;;;;;-1:-1:-1;20677:46:0;20697:12;20625:17;20697:22;;;;;;;;;;;20721:1;20677:19;:46::i;:::-;20652:12;20665:8;20652:22;;;;;;;;;:71;;;;:22;;;;;;:71;-1:-1:-1;20583:8:0;;20534:197;;;-1:-1:-1;20744:12:0;;20285:477;-1:-1:-1;;20285:477:0:o;22367:848::-;22601:7;22893:10;22914:31;;;22910:192;;;23093:1;23058:31;;;23057:37;23045:49;22910:192;23179:30;23183:8;23193:15;23179:3;:30::i;:::-;23172:37;22367:848;-1:-1:-1;;;;;22367:848:0:o;23382:748::-;23591:21;23646:7;23632:10;:21;;23624:66;;;;;-1:-1:-1;;;23624:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23735:20;;;:64;;22017:4;23735:84;23986:6;23964:18;;;:29;10765:14;24007:30;;24000:38;;;;24106:17;23382:748;-1:-1:-1;;;;;;23382:748:0:o;33435:167::-;33524:6;33556:39;33580:2;33572:11;;33568:2;33560:11;;:23;10708:13;33556:3;:39::i;-1:-1:-1:-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;
Swarm Source
ipfs://ecb65e2069c65f54ce04dfa871092389f10ea3417b6b718ee60553278f7cca8a
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.