Source Code
Overview
ETH Balance
0.001 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 23 from a total of 23 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Settle | 6494273 | 62 days ago | IN | 0 ETH | 0.00044898 | ||||
Bid For Coverage | 6494269 | 62 days ago | IN | 0.002 ETH | 0.00023966 | ||||
Apply For Covera... | 6494267 | 62 days ago | IN | 0.001 ETH | 0.0005313 | ||||
Apply For Covera... | 6494229 | 62 days ago | IN | 0.001 ETH | 0.00050208 | ||||
Settle | 6439017 | 71 days ago | IN | 0 ETH | 0.00083805 | ||||
Bid For Coverage | 6439012 | 71 days ago | IN | 0.002 ETH | 0.0005077 | ||||
Apply For Covera... | 6438987 | 71 days ago | IN | 0.001 ETH | 0.00094855 | ||||
Settle | 6436555 | 71 days ago | IN | 0 ETH | 0.00086541 | ||||
Bid For Coverage | 6436554 | 71 days ago | IN | 0.002 ETH | 0.00048433 | ||||
Apply For Covera... | 6436552 | 71 days ago | IN | 0.001 ETH | 0.00116519 | ||||
Settle | 6433246 | 72 days ago | IN | 0 ETH | 0.00032283 | ||||
Bid For Coverage | 6433203 | 72 days ago | IN | 0.002 ETH | 0.00011049 | ||||
Apply For Covera... | 6433202 | 72 days ago | IN | 0.001 ETH | 0.00024405 | ||||
Settle | 6433196 | 72 days ago | IN | 0 ETH | 0.00021554 | ||||
Bid For Coverage | 6433195 | 72 days ago | IN | 0.002 ETH | 0.00013411 | ||||
Apply For Covera... | 6433189 | 72 days ago | IN | 0.001 ETH | 0.00037673 | ||||
Settle | 6432784 | 72 days ago | IN | 0 ETH | 0.00068301 | ||||
Bid For Coverage | 6432782 | 72 days ago | IN | 0.002 ETH | 0.00036415 | ||||
Apply For Covera... | 6432780 | 72 days ago | IN | 0.001 ETH | 0.00078239 | ||||
Settle | 6432760 | 72 days ago | IN | 0 ETH | 0.00063355 | ||||
Bid For Coverage | 6432758 | 72 days ago | IN | 0.002 ETH | 0.00029494 | ||||
Apply For Covera... | 6432756 | 72 days ago | IN | 0.001 ETH | 0.00064573 | ||||
0x60806040 | 6432751 | 72 days ago | IN | 0 ETH | 0.01166914 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
InsuranceBroker
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 10000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.25; import {OdfRequest, OdfResponse, IOdfClient, CborReader} from "@opendatafabric/contracts/src/Odf.sol"; // import { console2 } from "forge-std/src/console2.sol"; // Example weather insurance broker contract contract InsuranceBroker { event CoverageApplication( uint64 indexed policyId, address indexed holder, uint holderDeposit ); event PolicyCreated( uint64 indexed policyId, address indexed holder, address indexed insurer, uint holderDeposit, uint insurerDeposit ); event PolicySettlementInitiated( uint64 indexed policyId, address indexed holder, address indexed insurer, uint holderDeposit, uint insurerDeposit, uint64 dataRequestId ); event PolicySettled( uint64 indexed policyId, address indexed holder, address indexed insurer, uint holderDeposit, uint insurerDeposit, uint64 dataRequestId, bool holderClaims ); struct Policy { // Identifies the insurance policy uint64 policyId; // Applicant / beneficiary of the insurance payment and their deposit / premium / cost of the insurance address payable holder; uint holderDeposit; // Underwriter of the insurance and their deposit / settlement amount address payable insurer; uint insurerDeposit; // Whether this policy already settled one way or another bool settled; // Minimal amount of rainfall that has to be observed for policy to settle in insurer's favor uint64 precipitationThreshold; // ID of the dataset to use for querying string datasetId; } address private _owner; IOdfClient private _oracle; uint64 private _lastPolicyId = 0; mapping(uint64 policyId => Policy policy) private _policies; mapping(uint64 requestId => uint64 policyId) private _dataRequests; // Initialize contract with the oracle address constructor(address oracleAddr) { _owner = msg.sender; _oracle = IOdfClient(oracleAddr); } function applyForCoverage( uint64 precipitationThreshold, string memory datasetId ) external payable returns (uint64) { require(msg.value != 0, "need to provide a deposit"); _lastPolicyId += 1; Policy memory policy; policy.policyId = _lastPolicyId; policy.holder = payable(msg.sender); policy.holderDeposit = msg.value; policy.precipitationThreshold = precipitationThreshold; policy.datasetId = datasetId; _policies[policy.policyId] = policy; emit CoverageApplication( policy.policyId, policy.holder, policy.holderDeposit ); return policy.policyId; } function bidForCoverage(uint64 policyId) external payable { Policy memory policy = _policies[policyId]; require(policy.holder != address(0), "policy does not exist"); require(policy.insurer == address(0), "policy was already accepted"); require(!policy.settled, "policy was already settled"); require( msg.value > policy.holderDeposit, "need to provide sufficient deposit" ); policy.insurer = payable(msg.sender); policy.insurerDeposit = msg.value; _policies[policyId] = policy; emit PolicyCreated( policyId, policy.holder, policy.insurer, policy.holderDeposit, policy.insurerDeposit ); } function settle(uint64 policyId) external returns (uint64) { Policy memory policy = _policies[policyId]; require(policy.holder != address(0), "policy does not exist"); require(!policy.settled, "policy was already settled"); // policy was not accepted by an insusrer? if (policy.insurer == address(0)) { // Return the deposit to the applicant policy.settled = true; _policies[policyId] = policy; policy.holder.transfer(policy.holderDeposit); return 0; } // Request data from the oracle OdfRequest.Req memory req = OdfRequest.init(); // Specify ID of the dataset(s) we will be querying. // Repeat this call for multiple inputs. req.dataset("weather_stations", policy.datasetId); // Specify an arbitrary complex SQL query. // Queries can include even JOINs req.sql( "select " "cast(floor(avg(precipitation_accumulated)) as bigint) " "from ( " "select " "device_id, max(precipitation_accumulated) as precipitation_accumulated " "from weather_stations " "group by device_id " ") " ); // Send request to the oracle and specify a callback uint64 dataRequestId = _oracle.sendRequest(req, this.onResult); _dataRequests[dataRequestId] = policyId; emit PolicySettlementInitiated( policy.policyId, policy.holder, policy.insurer, policy.holderDeposit, policy.insurerDeposit, dataRequestId ); return dataRequestId; } // This function will be called by the oracle when request is fulfilled function onResult(OdfResponse.Res memory result) external { require(msg.sender == address(_oracle), "Can only be called by oracle"); uint64 policyId = _dataRequests[result.requestId()]; require(policyId != 0, "corresponding policy not found"); Policy memory policy = _policies[policyId]; require( policy.holder != address(0) && policy.insurer != address(0), "policy is in invalid state" ); require(!policy.settled, "policy already settled"); require(result.numRecords() == 1, "Expected one record"); CborReader.CBOR[] memory record = result.record(0); uint64 precipitationActual = uint64(int64(record[0].readInt())); bool holderClaims = precipitationActual < policy.precipitationThreshold; policy.settled = true; _policies[policyId] = policy; emit PolicySettled( policy.policyId, policy.holder, policy.insurer, policy.holderDeposit, policy.insurerDeposit, result.requestId(), holderClaims ); if (holderClaims) { policy.holder.transfer( policy.holderDeposit + policy.insurerDeposit ); } else { policy.insurer.transfer( policy.holderDeposit + policy.insurerDeposit ); } } function withdraw() external { require(msg.sender == _owner, "Only owner can withdraw"); payable(_owner).transfer(address(this).balance); } using OdfRequest for OdfRequest.Req; using OdfResponse for OdfResponse.Res; using CborReader for CborReader.CBOR; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.25; import { OdfRequest, CborWriter } from "./OdfRequest.sol"; import { OdfResponse, CborReader } from "./OdfResponse.sol"; //////////////////////////////////////////////////////////////////////////////////////// // Interface used by client contracts interface IOdfClient { // Current contract was disabled and you need to upgrade to a new one error ContractDisabled(); // Called by the clients to request off-chain data function sendRequest( OdfRequest.Req memory request, function(OdfResponse.Res memory) external callback ) external payable returns (uint64); } //////////////////////////////////////////////////////////////////////////////////////// // Interface used by data providers interface IOdfProvider { // Emitted when client request was made and awaits a response event SendRequest(uint64 indexed requestId, address indexed consumerAddr, bytes request); // Emitted when a provider fulfills a pending request. // // Fields: // - requestId - unique identifier of the request // - consumerAddr - address of the contract that sent request and awaits the response // - providerAddr - address of the provider that fulfilled the request // - response - response data, see `OdfResponse` // - requestError - indicates that response contained an unrecoverable error instead of data // - consumerError - indicates that consumer callback has failed when processing the result // - consumerErrorData - will contain the details of consumer-side error event ProvideResult( uint64 indexed requestId, address indexed consumerAddr, address indexed providerAddr, bytes response, bool requestError, bool consumerError, bytes consumerErrorData ); // Returned when provider was not registered to provide results to the oracle error UnauthorizedProvider(address providerAddr); // Returned when pending request by this ID is not found error RequestNotFound(uint64 requestId); // Returns true/false whether `addr` is authorized to provide results to this oracle function canProvideResults(address addr) external view returns (bool); // Called to fulfill a pending request // See `OdfResponse` for explanation of the `result` function provideResult(uint64 requestId, bytes calldata result) external; } //////////////////////////////////////////////////////////////////////////////////////// // Interface used by oracle admins interface IOdfAdmin { // Emitted when a provider is authorized event AddProvider(address indexed providerAddr); // Emitted when a provider authorization is revoked event RemoveProvider(address indexed providerAddr); // Authorizes a provider to supply results function addProvider(address providerAddr) external; // Revoke the authorization from a provider to supply results function removeProvider(address providerAddr) external; } ////////////////////////////////////////////////////////////////////////////////////////
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.25; import { CborWriter } from "./CborWriter.sol"; //////////////////////////////////////////////////////////////////////////////////////// // ODF Oracle request builder. // // Example use: // // using OdfRequest for OdfRequest.Req; // // OdfRequest.Req memory req = OdfRequest.init(); // req.dataset( // "my_temp_sensor", // "did:odf:fed014895afeb476d5d94c1af0668f30ab661c8561760bba6744e43225ba52e099595" // ); // req.sql( // "select event_time, value " // "from my_temp_sensor " // "order by offset desc " // "limit 1" // ); // oracle.sendRequest(req, this.callback); // // Requests are represented as a CBOR-encoded flat array that carries all the parameters: // // [ // version, // "ds", "alias1", b"did:odf:x", // "ds", "alias2", b"did:odf:y", // "sql", "select ...", // ... // ] // // The `dataset` method MUST be used to associate all intput aliases with their IDs to // both avoid the risks of getting wrong data is dataset is renamed, and to allow // providers quickly test in they have necessary data to satisfy the request. // // Note that DIDs are encoded as binaries to save space. // library OdfRequest { using CborWriter for CborWriter.CBORBuffer; // Protocol version - always written as the first element of the CBOR array. uint16 public constant VERSION = 1; struct Req { CborWriter.CBORBuffer _buf; } // Creates a new empty request with protocol version set function init() internal pure returns (Req memory) { CborWriter.CBORBuffer memory buf = CborWriter.create(1024); buf.startArray(); buf.writeUInt64(VERSION); return Req(buf); } // Finishes construction of the request returning the bytes representation function intoBytes(Req memory self) internal pure returns (bytes memory) { self._buf.endSequence(); return self._buf.data(); } // Specifies the SQL query (only one query is allowed per request) function sql(Req memory self, string memory _sql) internal pure { self._buf.writeString("sql"); self._buf.writeString(_sql); } // Associates an alias used in the query with a specific ODF dataset ID. // // Example: // // req.dataset( // "foo", // "did:odf:fed014895afeb476d5d94c1af0668f30ab661c8561760bba6744e43225ba52e099595" // ) // // If you don't want to pay for the cost of DID parsing - use `datasetRaw()` function. function dataset(Req memory self, string memory _alias, string memory _did) internal pure { bytes memory didBin = didToBytes(_did); datasetRaw(self, _alias, didBin); } // Associates an alias used in the query with a specific ODF dataset ID given in binary form. // // Example: // // req.datasetRaw( // "foo", // hex"ed014895afeb476d5d94c1af0668f30ab661c8561760bba6744e43225ba52e099595" // ) // // If you don't want to pay for the cost of DID parsing - use `datasetRaw()` function. function datasetRaw(Req memory self, string memory _alias, bytes memory _did) internal pure { self._buf.writeString("ds"); self._buf.writeString(_alias); self._buf.writeBytes(_did); } // solhint-disable custom-errors function didToBytes(string memory _did) private pure returns (bytes memory) { bytes memory bin = bytes(_did); require(bin.length == 77, "Invalid DID"); require(bytes9(bin) == "did:odf:f", "Invalid DID"); bytes memory result = new bytes(34); for (uint16 i = 0; i < 34; i++) { uint16 s = i * 2 + 9; result[i] = bytes1((hexToInt(bin[s]) << 4) + hexToInt(bin[s + 1])); } return result; } // solhint-disable custom-errors function hexToInt(bytes1 c) public pure returns (uint8) { if (c >= bytes1("0") && c <= bytes1("9")) { return uint8(c) - uint8(bytes1("0")); } if (bytes1(c) >= bytes1("a") && bytes1(c) <= bytes1("f")) { return 10 + uint8(c) - uint8(bytes1("a")); } if (bytes1(c) >= bytes1("A") && bytes1(c) <= bytes1("F")) { return 10 + uint8(c) - uint8(bytes1("A")); } revert("Not a hex char"); } } ////////////////////////////////////////////////////////////////////////////////////////
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.25; import { CborReader } from "./CborReader.sol"; import { CborWriter } from "./CborWriter.sol"; //////////////////////////////////////////////////////////////////////////////////////// // Responses are deserialized from CBOR with data using the Array-of-Arrays // representation. State information is included that makes requests reproducible // and verifiable. // // The successful response structure is as follows: // // [ // 1, // version // true, // success // [ // [<row1-col1>, <row1-col2>, ...], // [<row2-col1>, <row2-col2>, ...], // ... // ], // b"data-logical-multihash", // [ // b"odf:did:x", b"block1-multihash", // b"odf:did:y", b"block2-multihash", // ... // ] // ] // // The unsuccessful response structure is: // // [ // 1, // version // false, // error // "SQL query error ..." // error message // ] // // Note that DIDs and Multihashes are encoded as binaries to save space. // library OdfResponse { using CborReader for CborReader.CBOR; using CborWriter for CborWriter.CBORBuffer; uint16 public constant VERSION = 1; struct Res { uint64 _requestId; bool _ok; CborReader.CBOR[] _data; string _errorMessage; } // solhint-disable custom-errors function fromBytes(uint64 reqId, bytes memory data) internal pure returns (Res memory) { Res memory res; res._requestId = reqId; CborReader.CBOR[] memory root = CborReader.fromBytes(data).readArray(); // NOTE: witnet library adds extra item to the end require(root.length == 5 + 1 || root.length == 3 + 1, "Invalid length"); uint256 version = root[0].readUint(); require(version == VERSION, "Unsupported response version"); res._ok = root[1].readBool(); if (res._ok) { res._data = root[2].readArray(); } else { res._errorMessage = root[2].readString(); } return res; } function requestId(Res memory self) internal pure returns (uint64) { return self._requestId; } // Tells whether result was successful and contains data or an error function ok(Res memory self) internal pure returns (bool) { return self._ok; } // Error message associated with unsuccessful response function errorMessage(Res memory self) internal pure returns (string memory) { return self._errorMessage; } function numRecords(Res memory self) internal pure returns (uint64) { // NOTE: witnet library adds extra item to the end return uint64(self._data.length - 1); } function records(Res memory self) internal pure returns (CborReader.CBOR[] memory) { return self._data; } function record(Res memory self, uint64 i) internal pure returns (CborReader.CBOR[] memory) { return self._data[i].readArray(); } // For testing: constructs an empty successful response function empty(uint64 reqId) internal pure returns (Res memory) { Res memory res; res._requestId = reqId; res._ok = true; // NOTE: witnet library adds extra item to the end res._data = new CborReader.CBOR[](1); return res; } // For testing: constructs an unsuccessful response with specified error message function error(uint64 reqId, string memory errMessage) internal pure returns (Res memory) { Res memory res; res._requestId = reqId; res._ok = false; res._errorMessage = errMessage; return res; } // For testing: converts a response to bytes function intoBytes(Res memory self) internal pure returns (bytes memory) { CborWriter.CBORBuffer memory buf = CborWriter.create(1024); buf.startArray(); buf.writeBool(self._ok); if (self._ok) { // Only supports empty data, hash, and state buf.startArray(); buf.endSequence(); buf.writeString(""); buf.startArray(); buf.endSequence(); } else { buf.writeString(self._errorMessage); } buf.endSequence(); return buf.data(); } } ////////////////////////////////////////////////////////////////////////////////////////
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; /** * @dev Vendored CBOR writing utils. Copied from * [solidity-cborutils](https://github.com/smartcontractkit/solidity-cborutils). * */ library CborWriter { using Buffer for Buffer.buffer; struct CBORBuffer { Buffer.buffer buf; uint256 depth; } uint8 private constant MAJOR_TYPE_INT = 0; uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1; uint8 private constant MAJOR_TYPE_BYTES = 2; uint8 private constant MAJOR_TYPE_STRING = 3; uint8 private constant MAJOR_TYPE_ARRAY = 4; uint8 private constant MAJOR_TYPE_MAP = 5; uint8 private constant MAJOR_TYPE_TAG = 6; uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7; uint8 private constant TAG_TYPE_BIGNUM = 2; uint8 private constant TAG_TYPE_NEGATIVE_BIGNUM = 3; uint8 private constant CBOR_FALSE = 20; uint8 private constant CBOR_TRUE = 21; uint8 private constant CBOR_NULL = 22; uint8 private constant CBOR_UNDEFINED = 23; function create(uint256 capacity) internal pure returns (CBORBuffer memory cbor) { Buffer.init(cbor.buf, capacity); cbor.depth = 0; return cbor; } function data(CBORBuffer memory buf) internal pure returns (bytes memory) { require(buf.depth == 0, "Invalid CBOR"); return buf.buf.buf; } function writeUInt256(CBORBuffer memory buf, uint256 value) internal pure { buf.buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_BIGNUM)); writeBytes(buf, abi.encode(value)); } function writeInt256(CBORBuffer memory buf, int256 value) internal pure { if (value < 0) { buf.buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_NEGATIVE_BIGNUM)); writeBytes(buf, abi.encode(uint256(-1 - value))); } else { writeUInt256(buf, uint256(value)); } } function writeUInt64(CBORBuffer memory buf, uint64 value) internal pure { writeFixedNumeric(buf, MAJOR_TYPE_INT, value); } function writeInt64(CBORBuffer memory buf, int64 value) internal pure { if (value >= 0) { writeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(value)); } else { writeFixedNumeric(buf, MAJOR_TYPE_NEGATIVE_INT, uint64(-1 - value)); } } function writeBytes(CBORBuffer memory buf, bytes memory value) internal pure { writeFixedNumeric(buf, MAJOR_TYPE_BYTES, uint64(value.length)); buf.buf.append(value); } function writeString(CBORBuffer memory buf, string memory value) internal pure { writeFixedNumeric(buf, MAJOR_TYPE_STRING, uint64(bytes(value).length)); buf.buf.append(bytes(value)); } function writeBool(CBORBuffer memory buf, bool value) internal pure { writeContentFree(buf, value ? CBOR_TRUE : CBOR_FALSE); } function writeNull(CBORBuffer memory buf) internal pure { writeContentFree(buf, CBOR_NULL); } function writeUndefined(CBORBuffer memory buf) internal pure { writeContentFree(buf, CBOR_UNDEFINED); } function startArray(CBORBuffer memory buf) internal pure { writeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY); buf.depth += 1; } function startFixedArray(CBORBuffer memory buf, uint64 length) internal pure { writeDefiniteLengthType(buf, MAJOR_TYPE_ARRAY, length); } function startMap(CBORBuffer memory buf) internal pure { writeIndefiniteLengthType(buf, MAJOR_TYPE_MAP); buf.depth += 1; } function startFixedMap(CBORBuffer memory buf, uint64 length) internal pure { writeDefiniteLengthType(buf, MAJOR_TYPE_MAP, length); } function endSequence(CBORBuffer memory buf) internal pure { writeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE); buf.depth -= 1; } function writeKVString( CBORBuffer memory buf, string memory key, string memory value ) internal pure { writeString(buf, key); writeString(buf, value); } function writeKVBytes( CBORBuffer memory buf, string memory key, bytes memory value ) internal pure { writeString(buf, key); writeBytes(buf, value); } function writeKVUInt256( CBORBuffer memory buf, string memory key, uint256 value ) internal pure { writeString(buf, key); writeUInt256(buf, value); } function writeKVInt256(CBORBuffer memory buf, string memory key, int256 value) internal pure { writeString(buf, key); writeInt256(buf, value); } function writeKVUInt64(CBORBuffer memory buf, string memory key, uint64 value) internal pure { writeString(buf, key); writeUInt64(buf, value); } function writeKVInt64(CBORBuffer memory buf, string memory key, int64 value) internal pure { writeString(buf, key); writeInt64(buf, value); } function writeKVBool(CBORBuffer memory buf, string memory key, bool value) internal pure { writeString(buf, key); writeBool(buf, value); } function writeKVNull(CBORBuffer memory buf, string memory key) internal pure { writeString(buf, key); writeNull(buf); } function writeKVUndefined(CBORBuffer memory buf, string memory key) internal pure { writeString(buf, key); writeUndefined(buf); } function writeKVMap(CBORBuffer memory buf, string memory key) internal pure { writeString(buf, key); startMap(buf); } function writeKVArray(CBORBuffer memory buf, string memory key) internal pure { writeString(buf, key); startArray(buf); } function writeFixedNumeric(CBORBuffer memory buf, uint8 major, uint64 value) private pure { if (value <= 23) { buf.buf.appendUint8(uint8((major << 5) | value)); } else if (value <= 0xFF) { buf.buf.appendUint8(uint8((major << 5) | 24)); buf.buf.appendInt(value, 1); } else if (value <= 0xFFFF) { buf.buf.appendUint8(uint8((major << 5) | 25)); buf.buf.appendInt(value, 2); } else if (value <= 0xFFFFFFFF) { buf.buf.appendUint8(uint8((major << 5) | 26)); buf.buf.appendInt(value, 4); } else { buf.buf.appendUint8(uint8((major << 5) | 27)); buf.buf.appendInt(value, 8); } } function writeIndefiniteLengthType(CBORBuffer memory buf, uint8 major) private pure { buf.buf.appendUint8(uint8((major << 5) | 31)); } function writeDefiniteLengthType( CBORBuffer memory buf, uint8 major, uint64 length ) private pure { writeFixedNumeric(buf, major, length); } function writeContentFree(CBORBuffer memory buf, uint8 value) private pure { buf.buf.appendUint8(uint8((MAJOR_TYPE_CONTENT_FREE << 5) | value)); } } /** * @dev A library for working with mutable byte buffers in Solidity. * * Copied from https://github.com/ensdomains/buffer * */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint256 capacity; } /** * @dev Initializes a buffer with an initial capacity. * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint256 capacity) internal pure returns (buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) let fpm := add(32, add(ptr, capacity)) if lt(fpm, ptr) { revert(0, 0) } mstore(0x40, fpm) } return buf; } /** * @dev Initializes a new buffer from an existing bytes object. * Changes to the buffer may mutate the original value. * @param b The bytes object to initialize the buffer with. * @return A new buffer. */ function fromBytes(bytes memory b) internal pure returns (buffer memory) { buffer memory buf; buf.buf = b; buf.capacity = b.length; return buf; } function resize(buffer memory buf, uint256 capacity) private pure { bytes memory oldbuf = buf.buf; init(buf, capacity); append(buf, oldbuf); } /** * @dev Sets buffer length to 0. * @param buf The buffer to truncate. * @return The original buffer, for chaining.. */ function truncate(buffer memory buf) internal pure returns (buffer memory) { assembly { let bufptr := mload(buf) mstore(bufptr, 0) } return buf; } /** * @dev Appends len bytes of a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function append( buffer memory buf, bytes memory data, uint256 len ) internal pure returns (buffer memory) { require(len <= data.length); uint256 off = buf.buf.length; uint256 newCapacity = off + len; if (newCapacity > buf.capacity) { resize(buf, newCapacity * 2); } uint256 dest; uint256 src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(newCapacity, buflen) { mstore(bufptr, newCapacity) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes unchecked { uint256 mask = (256 ** (32 - len)) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } return buf; } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return append(buf, data, data.length); } /** * @dev Appends a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendUint8(buffer memory buf, uint8 data) internal pure returns (buffer memory) { uint256 off = buf.buf.length; uint256 offPlusOne = off + 1; if (off >= buf.capacity) { resize(buf, offPlusOne * 2); } assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + off let dest := add(add(bufptr, off), 32) mstore8(dest, data) // Update buffer length if we extended it if gt(offPlusOne, mload(bufptr)) { mstore(bufptr, offPlusOne) } } return buf; } /** * @dev Appends len bytes of bytes32 to a buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to write (left-aligned). * @return The original buffer, for chaining. */ function append( buffer memory buf, bytes32 data, uint256 len ) private pure returns (buffer memory) { uint256 off = buf.buf.length; uint256 newCapacity = len + off; if (newCapacity > buf.capacity) { resize(buf, newCapacity * 2); } unchecked { uint256 mask = (256 ** len) - 1; // Right-align data data = data >> (8 * (32 - len)); assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + newCapacity let dest := add(bufptr, newCapacity) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(newCapacity, mload(bufptr)) { mstore(bufptr, newCapacity) } } } return buf; } /** * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chhaining. */ function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) { return append(buf, bytes32(data), 20); } /** * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) { return append(buf, data, 32); } /** * @dev Appends a byte to the end of the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to write (right-aligned). * @return The original buffer. */ function appendInt( buffer memory buf, uint256 data, uint256 len ) internal pure returns (buffer memory) { uint256 off = buf.buf.length; uint256 newCapacity = len + off; if (newCapacity > buf.capacity) { resize(buf, newCapacity * 2); } uint256 mask = (256 ** len) - 1; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + newCapacity let dest := add(bufptr, newCapacity) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(newCapacity, mload(bufptr)) { mstore(bufptr, newCapacity) } } return buf; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; /** * @dev Vendored CBOR reading utils. Copied from * [witnet-solidity-bridge](https://github.com/witnet/witnet-solidity-bridge/). */ library CborReader { using WitnetBuffer for WitnetBuffer.Buffer; using CborReader for CborReader.CBOR; /// Data struct following the RFC-7049 standard: Concise Binary Object Representation. struct CBOR { WitnetBuffer.Buffer buffer; uint8 initialByte; uint8 majorType; uint8 additionalInformation; uint64 len; uint64 tag; } uint8 internal constant MAJOR_TYPE_INT = 0; uint8 internal constant MAJOR_TYPE_NEGATIVE_INT = 1; uint8 internal constant MAJOR_TYPE_BYTES = 2; uint8 internal constant MAJOR_TYPE_STRING = 3; uint8 internal constant MAJOR_TYPE_ARRAY = 4; uint8 internal constant MAJOR_TYPE_MAP = 5; uint8 internal constant MAJOR_TYPE_TAG = 6; uint8 internal constant MAJOR_TYPE_CONTENT_FREE = 7; uint32 internal constant UINT32_MAX = type(uint32).max; uint64 internal constant UINT64_MAX = type(uint64).max; error EmptyArray(); error InvalidLengthEncoding(uint256 length); error UnexpectedMajorType(uint256 read, uint256 expected); error UnsupportedPrimitive(uint256 primitive); error UnsupportedMajorType(uint256 unexpected); modifier isMajorType(CborReader.CBOR memory cbor, uint8 expected) { if (cbor.majorType != expected) { revert UnexpectedMajorType(cbor.majorType, expected); } _; } modifier notEmpty(WitnetBuffer.Buffer memory buffer) { if (buffer.data.length == 0) { revert WitnetBuffer.EmptyBuffer(); } _; } function eof(CBOR memory cbor) internal pure returns (bool) { return cbor.buffer.cursor >= cbor.buffer.data.length; } /// @notice Decode a CBOR structure from raw bytes. /// @dev This is the main factory for CBOR instances, which can be later decoded into native EVM /// types. /// @param bytecode Raw bytes representing a CBOR-encoded value. /// @return A `CBOR` instance containing a partially decoded value. function fromBytes(bytes memory bytecode) internal pure returns (CBOR memory) { WitnetBuffer.Buffer memory buffer = WitnetBuffer.Buffer(bytecode, 0); return fromBuffer(buffer); } /// @notice Decode a CBOR structure from raw bytes. /// @dev This is an alternate factory for CBOR instances, which can be later decoded into native /// EVM types. /// @param buffer A Buffer structure representing a CBOR-encoded value. /// @return A `CBOR` instance containing a partially decoded value. function fromBuffer(WitnetBuffer.Buffer memory buffer) internal pure notEmpty(buffer) returns (CBOR memory) { uint8 initialByte; uint8 majorType = 255; uint8 additionalInformation; uint64 tag = UINT64_MAX; uint256 len; bool isTagged = true; while (isTagged) { // Extract basic CBOR properties from input bytes initialByte = buffer.readUint8(); len++; majorType = initialByte >> 5; additionalInformation = initialByte & 0x1f; // Early CBOR tag parsing. if (majorType == MAJOR_TYPE_TAG) { uint256 _cursor = buffer.cursor; tag = readLength(buffer, additionalInformation); len += buffer.cursor - _cursor; } else { isTagged = false; } } if (majorType > MAJOR_TYPE_CONTENT_FREE) { revert UnsupportedMajorType(majorType); } return CBOR(buffer, initialByte, majorType, additionalInformation, uint64(len), tag); } function fork(CborReader.CBOR memory self) internal pure returns (CborReader.CBOR memory) { return CBOR({ buffer: self.buffer.fork(), initialByte: self.initialByte, majorType: self.majorType, additionalInformation: self.additionalInformation, len: self.len, tag: self.tag }); } function settle(CBOR memory self) internal pure returns (CborReader.CBOR memory) { if (!self.eof()) { return fromBuffer(self.buffer); } else { return self; } } function skip(CBOR memory self) internal pure returns (CborReader.CBOR memory) { if ( self.majorType == MAJOR_TYPE_INT || self.majorType == MAJOR_TYPE_NEGATIVE_INT || ( self.majorType == MAJOR_TYPE_CONTENT_FREE && self.additionalInformation >= 25 && self.additionalInformation <= 27 ) ) { self.buffer.cursor += self.peekLength(); } else if (self.majorType == MAJOR_TYPE_STRING || self.majorType == MAJOR_TYPE_BYTES) { uint64 len = readLength(self.buffer, self.additionalInformation); self.buffer.cursor += len; } else if (self.majorType == MAJOR_TYPE_ARRAY || self.majorType == MAJOR_TYPE_MAP) { self.len = readLength(self.buffer, self.additionalInformation); } else if ( self.majorType != MAJOR_TYPE_CONTENT_FREE || (self.additionalInformation != 20 && self.additionalInformation != 21) ) { revert("CborReader.skip: unsupported major type"); } return self; } function peekLength(CBOR memory self) internal pure returns (uint64) { if (self.additionalInformation < 24) { return 0; } else if (self.additionalInformation < 28) { return uint64(1 << (self.additionalInformation - 24)); } else { revert InvalidLengthEncoding(self.additionalInformation); } } function readArray(CBOR memory self) internal pure isMajorType(self, MAJOR_TYPE_ARRAY) returns (CBOR[] memory items) { // read array's length and move self cursor forward to the first array element: uint64 len = readLength(self.buffer, self.additionalInformation); items = new CBOR[](len + 1); for (uint256 ix = 0; ix < len; ix++) { // settle next element in the array: self = self.settle(); // fork it and added to the list of items to be returned: items[ix] = self.fork(); if (self.majorType == MAJOR_TYPE_ARRAY) { CBOR[] memory _subitems = self.readArray(); // move forward to the first element after inner array: self = _subitems[_subitems.length - 1]; } else if (self.majorType == MAJOR_TYPE_MAP) { CBOR[] memory _subitems = self.readMap(); // move forward to the first element after inner map: self = _subitems[_subitems.length - 1]; } else { // move forward to the next element: self.skip(); } } // return self cursor as extra item at the end of the list, // as to optimize recursion when jumping over nested arrays: items[len] = self; } function readMap(CBOR memory self) internal pure isMajorType(self, MAJOR_TYPE_MAP) returns (CBOR[] memory items) { // read number of items within the map and move self cursor forward to the first inner // element: uint64 len = readLength(self.buffer, self.additionalInformation) * 2; items = new CBOR[](len + 1); for (uint256 ix = 0; ix < len; ix++) { // settle next element in the array: self = self.settle(); // fork it and added to the list of items to be returned: items[ix] = self.fork(); if (ix % 2 == 0 && self.majorType != MAJOR_TYPE_STRING) { revert UnexpectedMajorType(self.majorType, MAJOR_TYPE_STRING); } else if (self.majorType == MAJOR_TYPE_ARRAY || self.majorType == MAJOR_TYPE_MAP) { CBOR[] memory _subitems = (self.majorType == MAJOR_TYPE_ARRAY ? self.readArray() : self.readMap()); // move forward to the first element after inner array or map: self = _subitems[_subitems.length - 1]; } else { // move forward to the next element: self.skip(); } } // return self cursor as extra item at the end of the list, // as to optimize recursion when jumping over nested arrays: items[len] = self; } /// Reads the length of the settle CBOR item from a buffer, consuming a different number of /// bytes depending on the /// value of the `additionalInformation` argument. function readLength( WitnetBuffer.Buffer memory buffer, uint8 additionalInformation ) internal pure returns (uint64) { if (additionalInformation < 24) { return additionalInformation; } if (additionalInformation == 24) { return buffer.readUint8(); } if (additionalInformation == 25) { return buffer.readUint16(); } if (additionalInformation == 26) { return buffer.readUint32(); } if (additionalInformation == 27) { return buffer.readUint64(); } if (additionalInformation == 31) { return UINT64_MAX; } revert InvalidLengthEncoding(additionalInformation); } /// @notice Read a `CBOR` structure into a native `bool` value. /// @param cbor An instance of `CBOR`. /// @return The value represented by the input, as a `bool` value. function readBool(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE) returns (bool) { if (cbor.additionalInformation == 20) { return false; } else if (cbor.additionalInformation == 21) { return true; } else { revert UnsupportedPrimitive(cbor.additionalInformation); } } /// @notice Decode a `CBOR` structure into a native `bytes` value. /// @param cbor An instance of `CBOR`. /// @return output The value represented by the input, as a `bytes` value. function readBytes(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_BYTES) returns (bytes memory output) { cbor.len = readLength(cbor.buffer, cbor.additionalInformation); if (cbor.len == UINT32_MAX) { // These checks look repetitive but the equivalent loop would be more expensive. uint32 length = uint32(_readIndefiniteStringLength(cbor.buffer, cbor.majorType)); if (length < UINT32_MAX) { output = abi.encodePacked(cbor.buffer.read(length)); length = uint32(_readIndefiniteStringLength(cbor.buffer, cbor.majorType)); if (length < UINT32_MAX) { output = abi.encodePacked(output, cbor.buffer.read(length)); } } } else { return cbor.buffer.read(uint32(cbor.len)); } } /// @notice Decode a `CBOR` structure into a `fixed16` value. /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this /// method offsets all values /// by 5 decimal orders so as to get a fixed precision of 5 decimal positions, which should be /// OK for most `fixed16` /// use cases. In other words, the output of this method is 10,000 times the actual value, /// encoded into an `int32`. /// @param cbor An instance of `CBOR`. /// @return The value represented by the input, as an `int128` value. function readFloat16(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE) returns (int32) { if (cbor.additionalInformation == 25) { return cbor.buffer.readFloat16(); } else { revert UnsupportedPrimitive(cbor.additionalInformation); } } /// @notice Decode a `CBOR` structure into a `fixed32` value. /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this /// method offsets all values /// by 9 decimal orders so as to get a fixed precision of 9 decimal positions, which should be /// OK for most `fixed64` /// use cases. In other words, the output of this method is 10^9 times the actual value, encoded /// into an `int`. /// @param cbor An instance of `CBOR`. /// @return The value represented by the input, as an `int` value. function readFloat32(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE) returns (int256) { if (cbor.additionalInformation == 26) { return cbor.buffer.readFloat32(); } else { revert UnsupportedPrimitive(cbor.additionalInformation); } } /// @notice Decode a `CBOR` structure into a `fixed64` value. /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this /// method offsets all values /// by 15 decimal orders so as to get a fixed precision of 15 decimal positions, which should be /// OK for most `fixed64` /// use cases. In other words, the output of this method is 10^15 times the actual value, /// encoded into an `int`. /// @param cbor An instance of `CBOR`. /// @return The value represented by the input, as an `int` value. function readFloat64(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_CONTENT_FREE) returns (int256) { if (cbor.additionalInformation == 27) { return cbor.buffer.readFloat64(); } else { revert UnsupportedPrimitive(cbor.additionalInformation); } } /// @notice Decode a `CBOR` structure into a native `int128[]` value whose inner values follow /// the same convention /// @notice as explained in `decodeFixed16`. /// @param cbor An instance of `CBOR`. function readFloat16Array(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_ARRAY) returns (int32[] memory values) { uint64 length = readLength(cbor.buffer, cbor.additionalInformation); if (length < UINT64_MAX) { values = new int32[](length); for (uint64 i = 0; i < length;) { CBOR memory item = fromBuffer(cbor.buffer); values[i] = readFloat16(item); unchecked { i++; } } } else { revert InvalidLengthEncoding(length); } } /// @notice Decode a `CBOR` structure into a native `int128` value. /// @param cbor An instance of `CBOR`. /// @return The value represented by the input, as an `int128` value. function readInt(CBOR memory cbor) internal pure returns (int256) { if (cbor.majorType == 1) { uint64 _value = readLength(cbor.buffer, cbor.additionalInformation); return int256(-1) - int256(uint256(_value)); } else if (cbor.majorType == 0) { // Any `uint64` can be safely casted to `int128`, so this method supports majorType 1 as // well so as to have offer // a uniform API for positive and negative numbers return int256(readUint(cbor)); } else { revert UnexpectedMajorType(cbor.majorType, 1); } } /// @notice Decode a `CBOR` structure into a native `int[]` value. /// @param cbor instance of `CBOR`. /// @return array The value represented by the input, as an `int[]` value. function readIntArray(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_ARRAY) returns (int256[] memory array) { uint64 length = readLength(cbor.buffer, cbor.additionalInformation); if (length < UINT64_MAX) { array = new int256[](length); for (uint256 i = 0; i < length;) { CBOR memory item = fromBuffer(cbor.buffer); array[i] = readInt(item); unchecked { i++; } } } else { revert InvalidLengthEncoding(length); } } /// @notice Decode a `CBOR` structure into a native `string` value. /// @param cbor An instance of `CBOR`. /// @return text The value represented by the input, as a `string` value. function readString(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_STRING) returns (string memory text) { cbor.len = readLength(cbor.buffer, cbor.additionalInformation); if (cbor.len == UINT64_MAX) { bool _done; while (!_done) { uint64 length = _readIndefiniteStringLength(cbor.buffer, cbor.majorType); if (length < UINT64_MAX) { text = string(abi.encodePacked(text, cbor.buffer.readText(length / 4))); } else { _done = true; } } } else { return string(cbor.buffer.readText(cbor.len)); } } /// @notice Decode a `CBOR` structure into a native `string[]` value. /// @param cbor An instance of `CBOR`. /// @return strings The value represented by the input, as an `string[]` value. function readStringArray(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_ARRAY) returns (string[] memory strings) { uint256 length = readLength(cbor.buffer, cbor.additionalInformation); if (length < UINT64_MAX) { strings = new string[](length); for (uint256 i = 0; i < length;) { CBOR memory item = fromBuffer(cbor.buffer); strings[i] = readString(item); unchecked { i++; } } } else { revert InvalidLengthEncoding(length); } } /// @notice Decode a `CBOR` structure into a native `uint64` value. /// @param cbor An instance of `CBOR`. /// @return The value represented by the input, as an `uint64` value. function readUint(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_INT) returns (uint256) { return readLength(cbor.buffer, cbor.additionalInformation); } /// @notice Decode a `CBOR` structure into a native `uint64[]` value. /// @param cbor An instance of `CBOR`. /// @return values The value represented by the input, as an `uint64[]` value. function readUintArray(CBOR memory cbor) internal pure isMajorType(cbor, MAJOR_TYPE_ARRAY) returns (uint256[] memory values) { uint64 length = readLength(cbor.buffer, cbor.additionalInformation); if (length < UINT64_MAX) { values = new uint256[](length); for (uint256 ix = 0; ix < length;) { CBOR memory item = fromBuffer(cbor.buffer); values[ix] = readUint(item); unchecked { ix++; } } } else { revert InvalidLengthEncoding(length); } } /// Read the length of a CBOR indifinite-length item (arrays, maps, byte strings and text) from /// a buffer, consuming /// as many bytes as specified by the first byte. function _readIndefiniteStringLength( WitnetBuffer.Buffer memory buffer, uint8 majorType ) private pure returns (uint64 len) { uint8 initialByte = buffer.readUint8(); if (initialByte == 0xff) { return UINT64_MAX; } len = readLength(buffer, initialByte & 0x1f); if (len >= UINT64_MAX) { revert InvalidLengthEncoding(len); } else if (majorType != (initialByte >> 5)) { revert UnexpectedMajorType((initialByte >> 5), majorType); } } } /// @title A convenient wrapper around the `bytes memory` type that exposes a buffer-like interface /// @notice The buffer has an inner cursor that tracks the final offset of every read, i.e. any /// subsequent read will /// start with the byte that goes right after the last one in the previous read. /// @dev `uint32` is used here for `cursor` because `uint16` would only enable seeking up to 8KB, /// which could in some /// theoretical use cases be exceeded. Conversely, `uint32` supports up to 512MB, which cannot /// credibly be exceeded. /// @author The Witnet Foundation. library WitnetBuffer { error EmptyBuffer(); error IndexOutOfBounds(uint256 index, uint256 range); error MissingArgs(uint256 expected, uint256 given); /// Iterable bytes buffer. struct Buffer { bytes data; uint256 cursor; } // Ensures we access an existing index in an array modifier withinRange(uint256 index, uint256 _range) { if (index > _range) { revert IndexOutOfBounds(index, _range); } _; } /// @notice Concatenate undefinite number of bytes chunks. /// @dev Faster than looping on `abi.encodePacked(output, _buffs[ix])`. function concat(bytes[] memory _buffs) internal pure returns (bytes memory output) { unchecked { uint256 destinationPointer; uint256 destinationLength; assembly { // get safe scratch location output := mload(0x40) // set starting destination pointer destinationPointer := add(output, 32) } for (uint256 ix = 1; ix <= _buffs.length; ix++) { uint256 source; uint256 sourceLength; uint256 sourcePointer; assembly { // load source length pointer source := mload(add(_buffs, mul(ix, 32))) // load source length sourceLength := mload(source) // sets source memory pointer sourcePointer := add(source, 32) } memcpy(destinationPointer, sourcePointer, sourceLength); assembly { // increase total destination length destinationLength := add(destinationLength, sourceLength) // sets destination memory pointer destinationPointer := add(destinationPointer, sourceLength) } } assembly { // protect output bytes mstore(output, destinationLength) // set final output length mstore(0x40, add(mload(0x40), add(destinationLength, 32))) } } } function fork(WitnetBuffer.Buffer memory buffer) internal pure returns (WitnetBuffer.Buffer memory) { return Buffer(buffer.data, buffer.cursor); } function mutate( WitnetBuffer.Buffer memory buffer, uint256 length, bytes memory pokes ) internal pure withinRange(length, buffer.data.length - buffer.cursor + 1) { bytes[] memory parts = new bytes[](3); parts[0] = peek(buffer, 0, buffer.cursor); parts[1] = pokes; parts[2] = peek(buffer, buffer.cursor + length, buffer.data.length - buffer.cursor - length); buffer.data = concat(parts); } /// @notice Read and consume the next byte from the buffer. /// @param buffer An instance of `Buffer`. /// @return The next byte in the buffer counting from the cursor position. function next(Buffer memory buffer) internal pure withinRange(buffer.cursor, buffer.data.length) returns (bytes1) { // Return the byte at the position marked by the cursor and advance the cursor all at once return buffer.data[buffer.cursor++]; } function peek( WitnetBuffer.Buffer memory buffer, uint256 offset, uint256 length ) internal pure withinRange(offset + length, buffer.data.length) returns (bytes memory) { bytes memory data = buffer.data; bytes memory peeks = new bytes(length); uint256 destinationPointer; uint256 sourcePointer; assembly { destinationPointer := add(peeks, 32) sourcePointer := add(add(data, 32), offset) } memcpy(destinationPointer, sourcePointer, length); return peeks; } // @notice Extract bytes array from buffer starting from current cursor. /// @param buffer An instance of `Buffer`. /// @param length How many bytes to peek from the Buffer. // solium-disable-next-line security/no-assign-params function peek( WitnetBuffer.Buffer memory buffer, uint256 length ) internal pure withinRange(length, buffer.data.length - buffer.cursor) returns (bytes memory) { return peek(buffer, buffer.cursor, length); } /// @notice Read and consume a certain amount of bytes from the buffer. /// @param buffer An instance of `Buffer`. /// @param length How many bytes to read and consume from the buffer. /// @return output A `bytes memory` containing the first `length` bytes from the buffer, /// counting from the cursor position. function read( Buffer memory buffer, uint256 length ) internal pure withinRange(buffer.cursor + length, buffer.data.length) returns (bytes memory output) { // Create a new `bytes memory destination` value output = new bytes(length); // Early return in case that bytes length is 0 if (length > 0) { bytes memory input = buffer.data; uint256 offset = buffer.cursor; // Get raw pointers for source and destination uint256 sourcePointer; uint256 destinationPointer; assembly { sourcePointer := add(add(input, 32), offset) destinationPointer := add(output, 32) } // Copy `length` bytes from source to destination memcpy(destinationPointer, sourcePointer, length); // Move the cursor forward by `length` bytes seek(buffer, length, true); } } /// @notice Read and consume the next 2 bytes from the buffer as an IEEE 754-2008 floating point /// number enclosed in an /// `int32`. /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this /// method offsets all values /// by 5 decimal orders so as to get a fixed precision of 5 decimal positions, which should be /// OK for most `float16` /// use cases. In other words, the integer output of this method is 10,000 times the actual /// value. The input bytes are /// expected to follow the 16-bit base-2 format (a.k.a. `binary16`) in the IEEE 754-2008 /// standard. /// @param buffer An instance of `Buffer`. /// @return result The `int32` value of the next 4 bytes in the buffer counting from the cursor /// position. function readFloat16(Buffer memory buffer) internal pure returns (int32 result) { uint32 value = readUint16(buffer); // Get bit at position 0 uint32 sign = value & 0x8000; // Get bits 1 to 5, then normalize to the [-15, 16] range so as to counterweight the IEEE // 754 exponent bias int32 exponent = (int32(value & 0x7c00) >> 10) - 15; // Get bits 6 to 15 int32 fraction = int32(value & 0x03ff); // Add 2^10 to the fraction if exponent is not -15 if (exponent != -15) { fraction |= 0x400; } else if (exponent == 16) { revert( string( abi.encodePacked( "WitnetBuffer.readFloat16: ", sign != 0 ? "negative" : hex"", " infinity" ) ) ); } // Compute `2 ^ exponent · (1 + fraction / 1024)` if (exponent >= 0) { result = int32(int256(int256(1 << uint256(int256(exponent))) * 10_000 * fraction) >> 10); } else { result = int32( int256(int256(fraction) * 10_000 / int256(1 << uint256(int256(-exponent)))) >> 10 ); } // Make the result negative if the sign bit is not 0 if (sign != 0) { result *= -1; } } /// @notice Consume the next 4 bytes from the buffer as an IEEE 754-2008 floating point number /// enclosed into an `int`. /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this /// method offsets all values /// by 9 decimal orders so as to get a fixed precision of 9 decimal positions, which should be /// OK for most `float32` /// use cases. In other words, the integer output of this method is 10^9 times the actual value. /// The input bytes are /// expected to follow the 64-bit base-2 format (a.k.a. `binary32`) in the IEEE 754-2008 /// standard. /// @param buffer An instance of `Buffer`. /// @return result The `int` value of the next 8 bytes in the buffer counting from the cursor /// position. function readFloat32(Buffer memory buffer) internal pure returns (int256 result) { uint256 value = readUint32(buffer); // Get bit at position 0 uint256 sign = value & 0x80000000; // Get bits 1 to 8, then normalize to the [-127, 128] range so as to counterweight the IEEE // 754 exponent bias int256 exponent = (int256(value & 0x7f800000) >> 23) - 127; // Get bits 9 to 31 int256 fraction = int256(value & 0x007fffff); // Add 2^23 to the fraction if exponent is not -127 if (exponent != -127) { fraction |= 0x800000; } else if (exponent == 128) { revert( string( abi.encodePacked( "WitnetBuffer.readFloat32: ", sign != 0 ? "negative" : hex"", " infinity" ) ) ); } // Compute `2 ^ exponent · (1 + fraction / 2^23)` if (exponent >= 0) { result = (int256(1 << uint256(exponent)) * (10 ** 9) * fraction) >> 23; } else { result = (fraction * (10 ** 9) / int256(1 << uint256(-exponent))) >> 23; } // Make the result negative if the sign bit is not 0 if (sign != 0) { result *= -1; } } /// @notice Consume the next 8 bytes from the buffer as an IEEE 754-2008 floating point number /// enclosed into an `int`. /// @dev Due to the lack of support for floating or fixed point arithmetic in the EVM, this /// method offsets all values /// by 15 decimal orders so as to get a fixed precision of 15 decimal positions, which should be /// OK for most `float64` /// use cases. In other words, the integer output of this method is 10^15 times the actual /// value. The input bytes are /// expected to follow the 64-bit base-2 format (a.k.a. `binary64`) in the IEEE 754-2008 /// standard. /// @param buffer An instance of `Buffer`. /// @return result The `int` value of the next 8 bytes in the buffer counting from the cursor /// position. function readFloat64(Buffer memory buffer) internal pure returns (int256 result) { uint256 value = readUint64(buffer); // Get bit at position 0 uint256 sign = value & 0x8000000000000000; // Get bits 1 to 12, then normalize to the [-1023, 1024] range so as to counterweight the // IEEE 754 exponent bias int256 exponent = (int256(value & 0x7ff0000000000000) >> 52) - 1023; // Get bits 6 to 15 int256 fraction = int256(value & 0x000fffffffffffff); // Add 2^52 to the fraction if exponent is not -1023 if (exponent != -1023) { fraction |= 0x10000000000000; } else if (exponent == 1024) { revert( string( abi.encodePacked( "WitnetBuffer.readFloat64: ", sign != 0 ? "negative" : hex"", " infinity" ) ) ); } // Compute `2 ^ exponent · (1 + fraction / 1024)` if (exponent >= 0) { result = (int256(1 << uint256(exponent)) * (10 ** 15) * fraction) >> 52; } else { result = (fraction * (10 ** 15) / int256(1 << uint256(-exponent))) >> 52; } // Make the result negative if the sign bit is not 0 if (sign != 0) { result *= -1; } } // Read a text string of a given length from a buffer. Returns a `bytes memory` value for the // sake of genericness, /// but it can be easily casted into a string with `string(result)`. // solium-disable-next-line security/no-assign-params function readText( WitnetBuffer.Buffer memory buffer, uint64 length ) internal pure returns (bytes memory text) { text = new bytes(length); unchecked { for (uint64 index = 0; index < length; index++) { uint8 char = readUint8(buffer); if (char & 0x80 != 0) { if (char < 0xe0) { char = (char & 0x1f) << 6 | (readUint8(buffer) & 0x3f); length -= 1; } else if (char < 0xf0) { char = (char & 0x0f) << 12 | (readUint8(buffer) & 0x3f) << 6 | (readUint8(buffer) & 0x3f); length -= 2; } else { char = (char & 0x0f) << 18 | (readUint8(buffer) & 0x3f) << 12 | (readUint8(buffer) & 0x3f) << 6 | (readUint8(buffer) & 0x3f); length -= 3; } } text[index] = bytes1(char); } // Adjust text to actual length: assembly { mstore(text, length) } } } /// @notice Read and consume the next byte from the buffer as an `uint8`. /// @param buffer An instance of `Buffer`. /// @return value The `uint8` value of the next byte in the buffer counting from the cursor /// position. function readUint8(Buffer memory buffer) internal pure withinRange(buffer.cursor, buffer.data.length) returns (uint8 value) { bytes memory data = buffer.data; uint256 offset = buffer.cursor; assembly { value := mload(add(add(data, 1), offset)) } buffer.cursor++; } /// @notice Read and consume the next 2 bytes from the buffer as an `uint16`. /// @param buffer An instance of `Buffer`. /// @return value The `uint16` value of the next 2 bytes in the buffer counting from the cursor /// position. function readUint16(Buffer memory buffer) internal pure withinRange(buffer.cursor + 2, buffer.data.length) returns (uint16 value) { bytes memory data = buffer.data; uint256 offset = buffer.cursor; assembly { value := mload(add(add(data, 2), offset)) } buffer.cursor += 2; } /// @notice Read and consume the next 4 bytes from the buffer as an `uint32`. /// @param buffer An instance of `Buffer`. /// @return value The `uint32` value of the next 4 bytes in the buffer counting from the cursor /// position. function readUint32(Buffer memory buffer) internal pure withinRange(buffer.cursor + 4, buffer.data.length) returns (uint32 value) { bytes memory data = buffer.data; uint256 offset = buffer.cursor; assembly { value := mload(add(add(data, 4), offset)) } buffer.cursor += 4; } /// @notice Read and consume the next 8 bytes from the buffer as an `uint64`. /// @param buffer An instance of `Buffer`. /// @return value The `uint64` value of the next 8 bytes in the buffer counting from the cursor /// position. function readUint64(Buffer memory buffer) internal pure withinRange(buffer.cursor + 8, buffer.data.length) returns (uint64 value) { bytes memory data = buffer.data; uint256 offset = buffer.cursor; assembly { value := mload(add(add(data, 8), offset)) } buffer.cursor += 8; } /// @notice Read and consume the next 16 bytes from the buffer as an `uint128`. /// @param buffer An instance of `Buffer`. /// @return value The `uint128` value of the next 16 bytes in the buffer counting from the /// cursor position. function readUint128(Buffer memory buffer) internal pure withinRange(buffer.cursor + 16, buffer.data.length) returns (uint128 value) { bytes memory data = buffer.data; uint256 offset = buffer.cursor; assembly { value := mload(add(add(data, 16), offset)) } buffer.cursor += 16; } /// @notice Read and consume the next 32 bytes from the buffer as an `uint256`. /// @param buffer An instance of `Buffer`. /// @return value The `uint256` value of the next 32 bytes in the buffer counting from the /// cursor position. function readUint256(Buffer memory buffer) internal pure withinRange(buffer.cursor + 32, buffer.data.length) returns (uint256 value) { bytes memory data = buffer.data; uint256 offset = buffer.cursor; assembly { value := mload(add(add(data, 32), offset)) } buffer.cursor += 32; } /// @notice Count number of required parameters for given bytes arrays /// @dev Wildcard format: "\#\", with # in ["0".."9"]. /// @param input Bytes array containing strings. /// @param count Highest wildcard index found, plus 1. function argsCountOf(bytes memory input) internal pure returns (uint8 count) { if (input.length < 3) { return 0; } unchecked { uint256 ix = 0; uint256 length = input.length - 2; for (; ix < length;) { if ( input[ix] == bytes1("\\") && input[ix + 2] == bytes1("\\") && input[ix + 1] >= bytes1("0") && input[ix + 1] <= bytes1("9") ) { uint8 ax = uint8(uint8(input[ix + 1]) - uint8(bytes1("0")) + 1); if (ax > count) { count = ax; } ix += 3; } else { ix++; } } } } /// @notice Replace bytecode indexed wildcards by correspondent substrings. /// @dev Wildcard format: "\#\", with # in ["0".."9"]. /// @param input Bytes array containing strings. /// @param args Array of substring values for replacing indexed wildcards. /// @return output Resulting bytes array after replacing all wildcards. /// @return hits Total number of replaced wildcards. function replace( bytes memory input, string[] memory args ) internal pure returns (bytes memory output, uint256 hits) { uint256 ix = 0; uint256 lix = 0; uint256 inputLength; uint256 inputPointer; uint256 outputLength; uint256 outputPointer; uint256 source; uint256 sourceLength; uint256 sourcePointer; if (input.length < 3) { return (input, 0); } assembly { // set starting input pointer inputPointer := add(input, 32) // get safe output location output := mload(0x40) // set starting output pointer outputPointer := add(output, 32) } unchecked { uint256 length = input.length - 2; for (; ix < length;) { if ( input[ix] == bytes1("\\") && input[ix + 2] == bytes1("\\") && input[ix + 1] >= bytes1("0") && input[ix + 1] <= bytes1("9") ) { inputLength = (ix - lix); if (ix > lix) { memcpy(outputPointer, inputPointer, inputLength); inputPointer += inputLength + 3; outputPointer += inputLength; } else { inputPointer += 3; } uint256 ax = uint256(uint8(input[ix + 1]) - uint8(bytes1("0"))); if (ax >= args.length) { revert MissingArgs(ax + 1, args.length); } assembly { source := mload(add(args, mul(32, add(ax, 1)))) sourceLength := mload(source) sourcePointer := add(source, 32) } memcpy(outputPointer, sourcePointer, sourceLength); outputLength += inputLength + sourceLength; outputPointer += sourceLength; ix += 3; lix = ix; hits++; } else { ix++; } } ix = input.length; } if (outputLength > 0) { if (ix > lix) { memcpy(outputPointer, inputPointer, ix - lix); outputLength += (ix - lix); } assembly { // set final output length mstore(output, outputLength) // protect output bytes mstore(0x40, add(mload(0x40), add(outputLength, 32))) } } else { return (input, 0); } } /// @notice Replace string indexed wildcards by correspondent substrings. /// @dev Wildcard format: "\#\", with # in ["0".."9"]. /// @param input String potentially containing wildcards. /// @param args Array of substring values for replacing indexed wildcards. /// @return output Resulting string after replacing all wildcards. function replace( string memory input, string[] memory args ) internal pure returns (string memory) { (bytes memory _outputBytes,) = replace(bytes(input), args); return string(_outputBytes); } /// @notice Move the inner cursor of the buffer to a relative or absolute position. /// @param buffer An instance of `Buffer`. /// @param offset How many bytes to move the cursor forward. /// @param relative Whether to count `offset` from the last position of the cursor (`true`) or /// the beginning of the /// buffer (`true`). /// @return The final position of the cursor (will equal `offset` if `relative` is `false`). // solium-disable-next-line security/no-assign-params function seek( Buffer memory buffer, uint256 offset, bool relative ) internal pure withinRange(offset, buffer.data.length) returns (uint256) { // Deal with relative offsets if (relative) { offset += buffer.cursor; } buffer.cursor = offset; return offset; } /// @notice Move the inner cursor a number of bytes forward. /// @dev This is a simple wrapper around the relative offset case of `seek()`. /// @param buffer An instance of `Buffer`. /// @param relativeOffset How many bytes to move the cursor forward. /// @return The final position of the cursor. function seek(Buffer memory buffer, uint256 relativeOffset) internal pure returns (uint256) { return seek(buffer, relativeOffset, true); } /// @notice Copy bytes from one memory address into another. /// @dev This function was borrowed from Nick Johnson's `solidity-stringutils` lib, and /// reproduced here under the terms /// of [Apache License /// 2.0](https://github.com/Arachnid/solidity-stringutils/blob/master/LICENSE). /// @param dest Address of the destination memory. /// @param src Address to the source memory. /// @param len How many bytes to copy. // solium-disable-next-line security/no-assign-params function memcpy(uint256 dest, uint256 src, uint256 len) private pure { unchecked { // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } if (len > 0) { // Copy remaining bytes uint256 _mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(_mask)) let destpart := and(mload(dest), _mask) mstore(dest, or(destpart, srcpart)) } } } } }
{ "remappings": [ "@opendatafabric/=node_modules/@opendatafabric/", "@openzeppelin/=node_modules/@openzeppelin/", "forge-std/=node_modules/forge-std/" ], "optimizer": { "enabled": true, "runs": 10000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"oracleAddr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EmptyBuffer","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"range","type":"uint256"}],"name":"IndexOutOfBounds","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"InvalidLengthEncoding","type":"error"},{"inputs":[{"internalType":"uint256","name":"read","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"UnexpectedMajorType","type":"error"},{"inputs":[{"internalType":"uint256","name":"unexpected","type":"uint256"}],"name":"UnsupportedMajorType","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"policyId","type":"uint64"},{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":false,"internalType":"uint256","name":"holderDeposit","type":"uint256"}],"name":"CoverageApplication","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"policyId","type":"uint64"},{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":true,"internalType":"address","name":"insurer","type":"address"},{"indexed":false,"internalType":"uint256","name":"holderDeposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"insurerDeposit","type":"uint256"}],"name":"PolicyCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"policyId","type":"uint64"},{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":true,"internalType":"address","name":"insurer","type":"address"},{"indexed":false,"internalType":"uint256","name":"holderDeposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"insurerDeposit","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"dataRequestId","type":"uint64"},{"indexed":false,"internalType":"bool","name":"holderClaims","type":"bool"}],"name":"PolicySettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"policyId","type":"uint64"},{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":true,"internalType":"address","name":"insurer","type":"address"},{"indexed":false,"internalType":"uint256","name":"holderDeposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"insurerDeposit","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"dataRequestId","type":"uint64"}],"name":"PolicySettlementInitiated","type":"event"},{"inputs":[{"internalType":"uint64","name":"precipitationThreshold","type":"uint64"},{"internalType":"string","name":"datasetId","type":"string"}],"name":"applyForCoverage","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"policyId","type":"uint64"}],"name":"bidForCoverage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"_requestId","type":"uint64"},{"internalType":"bool","name":"_ok","type":"bool"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"cursor","type":"uint256"}],"internalType":"struct WitnetBuffer.Buffer","name":"buffer","type":"tuple"},{"internalType":"uint8","name":"initialByte","type":"uint8"},{"internalType":"uint8","name":"majorType","type":"uint8"},{"internalType":"uint8","name":"additionalInformation","type":"uint8"},{"internalType":"uint64","name":"len","type":"uint64"},{"internalType":"uint64","name":"tag","type":"uint64"}],"internalType":"struct CborReader.CBOR[]","name":"_data","type":"tuple[]"},{"internalType":"string","name":"_errorMessage","type":"string"}],"internalType":"struct OdfResponse.Res","name":"result","type":"tuple"}],"name":"onResult","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"policyId","type":"uint64"}],"name":"settle","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260018054600160a01b600160e01b0319169055348015602257600080fd5b50604051613919380380613919833981016040819052603f916071565b60008054336001600160a01b031991821617909155600180549091166001600160a01b0392909216919091179055609f565b600060208284031215608257600080fd5b81516001600160a01b0381168114609857600080fd5b9392505050565b61386b806100ae6000396000f3fe60806040526004361061005a5760003560e01c80634b9ba446116100435780634b9ba446146100895780638b6f0d74146100c6578063cae6a407146100e657600080fd5b8063272001e71461005f5780633ccfd60b14610074575b600080fd5b61007261006d366004612df4565b6100f9565b005b34801561008057600080fd5b506100726105ab565b34801561009557600080fd5b506100a96100a4366004612df4565b61065c565b60405167ffffffffffffffff909116815260200160405180910390f35b3480156100d257600080fd5b506100726100e1366004613139565b610bf6565b6100a96100f43660046131f5565b611258565b67ffffffffffffffff8082166000908152600260208181526040808420815161010080820184528254808916835273ffffffffffffffffffffffffffffffffffffffff6801000000000000000090910481169583019590955260018301549382019390935293810154909216606084015260038201546080840152600482015460ff8116151560a08501520490931660c08201526005830180549293919260e0840191906101a690613245565b80601f01602080910402602001604051908101604052809291908181526020018280546101d290613245565b801561021f5780601f106101f45761010080835404028352916020019161021f565b820191906000526020600020905b81548152906001019060200180831161020257829003601f168201915b50505091909252505050602081015190915073ffffffffffffffffffffffffffffffffffffffff166102985760405162461bcd60e51b815260206004820152601560248201527f706f6c69637920646f6573206e6f74206578697374000000000000000000000060448201526064015b60405180910390fd5b606081015173ffffffffffffffffffffffffffffffffffffffff16156103005760405162461bcd60e51b815260206004820152601b60248201527f706f6c6963792077617320616c72656164792061636365707465640000000000604482015260640161028f565b8060a00151156103525760405162461bcd60e51b815260206004820152601a60248201527f706f6c6963792077617320616c726561647920736574746c6564000000000000604482015260640161028f565b806040015134116103cb5760405162461bcd60e51b815260206004820152602260248201527f6e65656420746f2070726f766964652073756666696369656e74206465706f7360448201527f6974000000000000000000000000000000000000000000000000000000000000606482015260840161028f565b3360608201908152346080830190815267ffffffffffffffff84811660009081526002602081815260409283902087518154928901519086167fffffffff00000000000000000000000000000000000000000000000000000000909316929092176801000000000000000073ffffffffffffffffffffffffffffffffffffffff93841602178155928701516001840155945190820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909516179093559051600383015560a083015160048301805460c08601517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009091169215157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1692909217610100929093169190910291909117905560e0820151829190600582019061051890826132da565b50905050806060015173ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167fac9f49869e29bfd82412359f358df8bf88224381ef1995ad3fb0e5b51c129c298460400151856080015160405161059f929190918252602082015260400190565b60405180910390a45050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106125760405162461bcd60e51b815260206004820152601760248201527f4f6e6c79206f776e65722063616e207769746864726177000000000000000000604482015260640161028f565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116914780156108fc02929091818181858888f19350505050158015610659573d6000803e3d6000fd5b50565b67ffffffffffffffff8082166000908152600260208181526040808420815161010080820184528254808916835273ffffffffffffffffffffffffffffffffffffffff6801000000000000000090910481169583019590955260018301549382019390935293810154909216606084015260038201546080840152600482015460ff8116151560a08501520490931660c082015260058301805492938493909160e084019161070a90613245565b80601f016020809104026020016040519081016040528092919081815260200182805461073690613245565b80156107835780601f1061075857610100808354040283529160200191610783565b820191906000526020600020905b81548152906001019060200180831161076657829003601f168201915b50505091909252505050602081015190915073ffffffffffffffffffffffffffffffffffffffff166107f75760405162461bcd60e51b815260206004820152601560248201527f706f6c69637920646f6573206e6f742065786973740000000000000000000000604482015260640161028f565b8060a00151156108495760405162461bcd60e51b815260206004820152601a60248201527f706f6c6963792077617320616c726561647920736574746c6564000000000000604482015260640161028f565b606081015173ffffffffffffffffffffffffffffffffffffffff16610a0f57600160a0820181815267ffffffffffffffff85811660009081526002602081815260409283902087518154928901519086167fffffffff00000000000000000000000000000000000000000000000000000000909316929092176801000000000000000073ffffffffffffffffffffffffffffffffffffffff938416021781559287015195830195909555606086015190820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919095161790935560808401516003840155905160048301805460c08601517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009091169215157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1692909217610100929093169190910291909117905560e082015182919060058201906109b390826132da565b50905050806020015173ffffffffffffffffffffffffffffffffffffffff166108fc82604001519081150290604051600060405180830381858888f19350505050158015610a05573d6000803e3d6000fd5b5060009392505050565b6000610a19611531565b9050610a696040518060400160405280601081526020017f776561746865725f73746174696f6e73000000000000000000000000000000008152508360e001518361156f9092919063ffffffff16565b610a8c6040518060e0016040528060bd81526020016137a260bd9139829061158d565b6001546040517fb8853b5400000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff169063b8853b5490610aeb9085903090638b6f0d74906004016133b8565b6020604051808303816000875af1158015610b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2e9190613475565b67ffffffffffffffff81811660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000168b8616179055606088810151898301518a518b86015160808d01518751918252958101959095529484019590955295965073ffffffffffffffffffffffffffffffffffffffff958616959093169391909116917f54bd3a28af22ebd07e9ba95adde85521fe7ae950fc9d3b4f5574b6deb506de11910160405180910390a4949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c5d5760405162461bcd60e51b815260206004820152601c60248201527f43616e206f6e6c792062652063616c6c6564206279206f7261636c6500000000604482015260640161028f565b600060036000610c6b845190565b67ffffffffffffffff908116825260208201929092526040016000908120549091169150819003610cde5760405162461bcd60e51b815260206004820152601e60248201527f636f72726573706f6e64696e6720706f6c696379206e6f7420666f756e640000604482015260640161028f565b67ffffffffffffffff8082166000908152600260208181526040808420815161010080820184528254808916835273ffffffffffffffffffffffffffffffffffffffff6801000000000000000090910481169583019590955260018301549382019390935293810154909216606084015260038201546080840152600482015460ff8116151560a08501520490931660c08201526005830180549293919260e084019190610d8b90613245565b80601f0160208091040260200160405190810160405280929190818152602001828054610db790613245565b8015610e045780601f10610dd957610100808354040283529160200191610e04565b820191906000526020600020905b815481529060010190602001808311610de757829003601f168201915b50505091909252505050602081015190915073ffffffffffffffffffffffffffffffffffffffff1615801590610e535750606081015173ffffffffffffffffffffffffffffffffffffffff1615155b610e9f5760405162461bcd60e51b815260206004820152601a60248201527f706f6c69637920697320696e20696e76616c6964207374617465000000000000604482015260640161028f565b8060a0015115610ef15760405162461bcd60e51b815260206004820152601660248201527f706f6c69637920616c726561647920736574746c656400000000000000000000604482015260640161028f565b610efa836115dc565b67ffffffffffffffff16600114610f535760405162461bcd60e51b815260206004820152601360248201527f4578706563746564206f6e65207265636f726400000000000000000000000000604482015260640161028f565b6000610f5f84826115f0565b90506000610f8682600081518110610f7957610f79613492565b6020026020010151611629565b60c084018051600160a0870181815267ffffffffffffffff8981166000908152600260208181526040928390208c518154928e01519086167fffffffff00000000000000000000000000000000000000000000000000000000909316929092176801000000000000000073ffffffffffffffffffffffffffffffffffffffff93841602178155928c01519583019590955560608b015190820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919095161790935560808901516003840155905160048301805495517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009096169115157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1691909117610100958316959095029490941790935560e0870151939450908216918416919091109185919060058201906110e290826132da565b50905050836060015173ffffffffffffffffffffffffffffffffffffffff16846020015173ffffffffffffffffffffffffffffffffffffffff16856000015167ffffffffffffffff167f3cba6f1baeb45c5440208ba050bfeb9e604dc591d7661cf2c7d8065351423a048760400151886080015161115e8c5190565b60408051938452602084019290925267ffffffffffffffff1690820152851515606082015260800160405180910390a480156111f457836020015173ffffffffffffffffffffffffffffffffffffffff166108fc856080015186604001516111c691906134f0565b6040518115909202916000818181858888f193505050501580156111ee573d6000803e3d6000fd5b50611250565b836060015173ffffffffffffffffffffffffffffffffffffffff166108fc8560800151866040015161122691906134f0565b6040518115909202916000818181858888f1935050505015801561124e573d6000803e3d6000fd5b505b505050505050565b6000346000036112aa5760405162461bcd60e51b815260206004820152601960248201527f6e65656420746f2070726f766964652061206465706f73697400000000000000604482015260640161028f565b6001805481906014906112e090839074010000000000000000000000000000000000000000900467ffffffffffffffff16613503565b825467ffffffffffffffff91821661010093840a908102920219161790915560408051918201815260008083526020830181905290820181905260608083018290526080830182905260a0830182905260c083019190915260e082015290506001805474010000000000000000000000000000000000000000900467ffffffffffffffff9081168084523360208086019182523460408088019182528a861660c0890190815260e089018b81526000968752600294859052919095208851815495519088167fffffffff00000000000000000000000000000000000000000000000000000000909616959095176801000000000000000073ffffffffffffffffffffffffffffffffffffffff96871602178155915196820196909655606087015191810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001692909316919091179091556080850151600382015560a085015160048201805493517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009094169115157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16919091176101009390941692909202929092179055905182919060058201906114bc90826132da565b50905050806020015173ffffffffffffffffffffffffffffffffffffffff16816000015167ffffffffffffffff167fe9b43372ad2470bf088a19481efde518124553fb2f7cb1216c0b8f83cf15ff45836040015160405161151f91815260200190565b60405180910390a35190505b92915050565b611539612d86565b60006115466104006116c6565b9050611551816116e7565b61155c81600161170b565b6040805160208101909152908152919050565b600061157a82611717565b905061158784848361191c565b50505050565b60408051808201909152600381527f73716c0000000000000000000000000000000000000000000000000000000000602082015282516115cc91611978565b81516115d89082611978565b5050565b6000600182604001515161152b919061352b565b606061162283604001518367ffffffffffffffff168151811061161557611615613492565b6020026020010151611991565b9392505050565b6000816040015160ff1660010361166657600061164e83600001518460600151611c64565b905061162267ffffffffffffffff821660001961353e565b816040015160ff1660000361167e5761152b82611d46565b60408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff90911660048201526001602482015260440161028f565b919050565b6116ce612d9e565b80516116da9083611dc4565b5060006020820152919050565b6116f2816004611e3b565b60018160200181815161170591906134f0565b90525050565b6115d882600083611e52565b80516060908290604d1461176d5760405162461bcd60e51b815260206004820152600b60248201527f496e76616c696420444944000000000000000000000000000000000000000000604482015260640161028f565b6117768161355e565b76ffffffffffffffffffffffffffffffffffffffffffffff19167f6469643a6f64663a660000000000000000000000000000000000000000000000146117fe5760405162461bcd60e51b815260206004820152600b60248201527f496e76616c696420444944000000000000000000000000000000000000000000604482015260640161028f565b6040805160228082526060820190925260009160208201818036833701905050905060005b60228161ffff16101561191457600061183d8260026135ae565b6118489060096135d4565b9050611899846118598360016135d4565b61ffff168151811061186d5761186d613492565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016611f73565b60046118b4868461ffff168151811061186d5761186d613492565b60ff16901b6118c391906135ef565b60f81b838361ffff16815181106118dc576118dc613492565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050600101611823565b509392505050565b60408051808201909152600281527f64730000000000000000000000000000000000000000000000000000000000006020820152835161195b91611978565b82516119679083611978565b825161197390826121c3565b505050565b6119858260038351611e52565b815161197390826121d0565b60608160048060ff16826040015160ff16146119eb5760408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff9182166004820152908216602482015260440161028f565b60006119ff85600001518660600151611c64565b9050611a0c816001613503565b67ffffffffffffffff1667ffffffffffffffff811115611a2e57611a2e612e11565b604051908082528060200260200182016040528015611a9e57816020015b6040805161010081018252606060c08201818152600060e0840181905290835260208084018290529383018190529082018190526080820181905260a08201528252600019909201910181611a4c5790505b50935060005b8167ffffffffffffffff16811015611c3357611abf866121f1565b9550611b98866040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091526040805160c081018083528451610100830184526060909152600060e0830152825180840190935280518352602090810151908301529081908152602001836020015160ff168152602001836040015160ff168152602001836060015160ff168152602001836080015167ffffffffffffffff1681526020018360a0015167ffffffffffffffff168152509050919050565b858281518110611baa57611baa613492565b6020026020010181905250600460ff16866040015160ff1603611c03576000611bd287611991565b90508060018251611be3919061352b565b81518110611bf357611bf3613492565b6020026020010151965050611c2b565b600560ff16866040015160ff1603611c20576000611bd287612252565b611c2986612578565b505b600101611aa4565b5084848267ffffffffffffffff1681518110611c5157611c51613492565b6020026020010181905250505050919050565b600060188260ff161015611c7c575060ff811661152b565b8160ff16601803611c9a57611c908361278c565b60ff16905061152b565b8160ff16601903611cb957611cae83612807565b61ffff16905061152b565b8160ff16601a03611cda57611ccd8361288c565b63ffffffff16905061152b565b8160ff16601b03611cf557611cee83612904565b905061152b565b8160ff16601f03611d0f575067ffffffffffffffff61152b565b6040517f6d785b1300000000000000000000000000000000000000000000000000000000815260ff8316600482015260240161028f565b60008160008060ff16826040015160ff1614611da05760408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff9182166004820152908216602482015260440161028f565b611db284600001518560600151611c64565b67ffffffffffffffff16949350505050565b604080518082019091526060815260006020820152611de4602083613608565b15611e0c57611df4602083613608565b611dff90602061352b565b611e0990836134f0565b91505b602080840183905260405180855260008152908184010181811015611e3057600080fd5b604052509192915050565b815161197390601f611fe0600585901b161761297c565b60178167ffffffffffffffff1611611e795782516115879060e0600585901b16831761297c565b60ff8167ffffffffffffffff1611611ebb578251611ea2906018611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660016129e5565b61ffff8167ffffffffffffffff1611611efe578251611ee5906019611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660026129e5565b63ffffffff8167ffffffffffffffff1611611f43578251611f2a90601a611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660046129e5565b8251611f5a90601b611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660086129e5565b60007f30000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000083161080159061200957507f39000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000831611155b1561201d5761152b603060f884901c613643565b7f61000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008316108015906120b157507f66000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000831611155b156120d15760616120c760f884901c600a6135ef565b61152b9190613643565b7f41000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000083161080159061216557507f46000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000831611155b1561217b5760416120c760f884901c600a6135ef565b60405162461bcd60e51b815260206004820152600e60248201527f4e6f742061206865782063686172000000000000000000000000000000000000604482015260640161028f565b6119858260028351611e52565b60408051808201909152606081526000602082015261162283838451612a6a565b6040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091528151805151602090910151101561224e57815161152b90612b3b565b5090565b60608160058060ff16826040015160ff16146122ac5760408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff9182166004820152908216602482015260440161028f565b60006122c085600001518660600151611c64565b6122cb90600261365c565b90506122d8816001613503565b67ffffffffffffffff1667ffffffffffffffff8111156122fa576122fa612e11565b60405190808252806020026020018201604052801561236a57816020015b6040805161010081018252606060c08201818152600060e0840181905290835260208084018290529383018190529082018190526080820181905260a082015282526000199092019101816123185790505b50935060005b8167ffffffffffffffff16811015611c335761238b866121f1565b9550612464866040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091526040805160c081018083528451610100830184526060909152600060e0830152825180840190935280518352602090810151908301529081908152602001836020015160ff168152602001836040015160ff168152602001836060015160ff168152602001836080015167ffffffffffffffff1681526020018360a0015167ffffffffffffffff168152509050919050565b85828151811061247657612476613492565b602090810291909101015261248c600282613608565b1580156124a15750604086015160ff16600314155b156124e95760408087015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff90911660048201526003602482015260440161028f565b604086015160ff16600414806125065750604086015160ff166005145b1561256557604086015160009060ff1660041461252b5761252687612252565b612534565b61253487611991565b90508060018251612545919061352b565b8151811061255557612555613492565b6020026020010151965050612570565b61256e86612578565b505b600101612370565b6040805161010081018252606060c08201818152600060e08401819052908352602083018190528284018190529082018190526080820181905260a08201529082015160ff1615806125d15750604082015160ff166001145b8061260a5750604082015160ff1660071480156125f657506019826060015160ff1610155b801561260a5750601b826060015160ff1611155b1561263e5761261882612ce9565b67ffffffffffffffff16826000015160200181815161263791906134f0565b9052505090565b604082015160ff166003148061265b5750604082015160ff166002145b156126a057600061267483600001518460600151611c64565b90508067ffffffffffffffff16836000015160200181815161269691906134f0565b90525061224e9050565b604082015160ff16600414806126bd5750604082015160ff166005145b156126e7576126d482600001518360600151611c64565b67ffffffffffffffff1660808301525090565b604082015160ff1660071415806127195750816060015160ff166014141580156127195750816060015160ff16601514155b1561224e5760405162461bcd60e51b815260206004820152602760248201527f43626f725265616465722e736b69703a20756e737570706f72746564206d616a60448201527f6f72207479706500000000000000000000000000000000000000000000000000606482015260840161028f565b60008160200151826000015151808211156127dd576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b83516020850180518083016001015195509081906127fa82613680565b8152505050505050919050565b60008160200151600261281a91906134f0565b82515180821115612861576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b835160208501805160028184018101519650909161287f82846134f0565b9052509395945050505050565b60008160200151600461289f91906134f0565b825151808211156128e6576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b835160208501805160048184018101519650909161287f82846134f0565b60008160200151600861291791906134f0565b8251518082111561295e576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b835160208501805160088184018101519650909161287f82846134f0565b60408051808201909152606081526000602082015282515160006129a18260016134f0565b9050846020015182106129c2576129c2856129bd83600261369a565b612d6f565b84516020838201018581535080518211156129db578181525b5093949350505050565b6040805180820190915260608152600060208201528351516000612a0982856134f0565b90508560200151811115612a2657612a26866129bd83600261369a565b60006001612a3686610100613795565b612a40919061352b565b90508651828101878319825116178152508051831115612a5e578281525b50959695505050505050565b6040805180820190915260608152600060208201528251821115612a8d57600080fd5b8351516000612a9c84836134f0565b90508560200151811115612ab957612ab9866129bd83600261369a565b855180518382016020019160009180851115612ad3578482525b505050602086015b60208610612b135780518252612af26020836134f0565b9150612aff6020826134f0565b9050612b0c60208761352b565b9550612adb565b51815160001960208890036101000a0190811690199190911617905250849150509392505050565b6040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091528151518290600003612bba576040517f240db51c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060ff8167ffffffffffffffff8160015b8015612c5c57612bdb8961278c565b955081612be781613680565b6007600589901c169650601f881695509250507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa8501612c54576020890151612c308a86611c64565b9350808a60200151612c42919061352b565b612c4c90846134f0565b925050612bcc565b506000612bcc565b600760ff86161115612c9f576040517fbd2ac87900000000000000000000000000000000000000000000000000000000815260ff8616600482015260240161028f565b506040805160c08101825289815260ff96871660208201529486169085015291909316606083015267ffffffffffffffff908116608083015290911660a082015291505b50919050565b60006018826060015160ff161015612d0357506000919050565b601c826060015160ff161015612d325760188260600151612d249190613643565b60ff166001901b9050919050565b60608201516040517f6d785b1300000000000000000000000000000000000000000000000000000000815260ff909116600482015260240161028f565b8151612d7b8383611dc4565b5061158783826121d0565b6040518060200160405280612d99612d9e565b905290565b6040518060400160405280612dc6604051806040016040528060608152602001600081525090565b8152602001600081525090565b67ffffffffffffffff8116811461065957600080fd5b80356116c181612dd3565b600060208284031215612e0657600080fd5b813561162281612dd3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715612e6357612e63612e11565b60405290565b6040805190810167ffffffffffffffff81118282101715612e6357612e63612e11565b6040516080810167ffffffffffffffff81118282101715612e6357612e63612e11565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612ef657612ef6612e11565b604052919050565b600067ffffffffffffffff831115612f1857612f18612e11565b612f4960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601612eaf565b9050828152838383011115612f5d57600080fd5b828260208301376000602084830101529392505050565b803560ff811681146116c157600080fd5b600082601f830112612f9657600080fd5b8135602067ffffffffffffffff80831115612fb357612fb3612e11565b8260051b612fc2838201612eaf565b9384528581018301938381019088861115612fdc57600080fd5b84880192505b8583101561310d57823584811115612ff957600080fd5b88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060c0828c038201121561302e57600080fd5b613036612e40565b878301358781111561304757600080fd5b83016040818e038401121561305b57600080fd5b613063612e69565b9250888101358881111561307657600080fd5b8101603f81018e1361308757600080fd5b6130988e8b83013560408401612efe565b845250604081013589840152508181526130b460408401612f74565b888201526130c460608401612f74565b60408201526130d560808401612f74565b60608201526130e660a08401612de9565b60808201526130f760c08401612de9565b60a0820152845250509184019190840190612fe2565b98975050505050505050565b600082601f83011261312a57600080fd5b61162283833560208501612efe565b60006020828403121561314b57600080fd5b813567ffffffffffffffff8082111561316357600080fd5b908301906080828603121561317757600080fd5b61317f612e8c565b823561318a81612dd3565b81526020830135801515811461319f57600080fd5b60208201526040830135828111156131b657600080fd5b6131c287828601612f85565b6040830152506060830135828111156131da57600080fd5b6131e687828601613119565b60608301525095945050505050565b6000806040838503121561320857600080fd5b823561321381612dd3565b9150602083013567ffffffffffffffff81111561322f57600080fd5b61323b85828601613119565b9150509250929050565b600181811c9082168061325957607f821691505b602082108103612ce3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f821115611973576000816000526020600020601f850160051c810160208610156132bb5750805b601f850160051c820191505b81811015611250578281556001016132c7565b815167ffffffffffffffff8111156132f4576132f4612e11565b613308816133028454613245565b84613292565b602080601f83116001811461333d57600084156133255750858301515b600019600386901b1c1916600185901b178555611250565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561338a5788860151825594840194600190910190840161336b565b50858210156133a85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000845160208060408501528151604060608601528051604060a087015280518060e088015260005b8181101561340257828101850151888201610100015284016133e5565b506000878201610100908101919091529284015160c088015284840151608088015263ffffffff881660208a901b1760401b84880152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168601909101935061346b9050565b5050949350505050565b60006020828403121561348757600080fd5b815161162281612dd3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561152b5761152b6134c1565b67ffffffffffffffff818116838216019080821115613524576135246134c1565b5092915050565b8181038181111561152b5761152b6134c1565b8181036000831280158383131683831282161715613524576135246134c1565b6000815160208301517fffffffffffffffffff0000000000000000000000000000000000000000000000808216935060098310156135a65780818460090360031b1b83161693505b505050919050565b61ffff8181168382160280821691908281146135cc576135cc6134c1565b505092915050565b61ffff818116838216019080821115613524576135246134c1565b60ff818116838216019081111561152b5761152b6134c1565b60008261363e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60ff828116828216039081111561152b5761152b6134c1565b67ffffffffffffffff8181168382160280821691908281146135cc576135cc6134c1565b60006000198203613693576136936134c1565b5060010190565b808202811582820484141761152b5761152b6134c1565b600181815b808511156136ec5781600019048211156136d2576136d26134c1565b808516156136df57918102915b93841c93908002906136b6565b509250929050565b6000826137035750600161152b565b816137105750600061152b565b816001811461372657600281146137305761374c565b600191505061152b565b60ff841115613741576137416134c1565b50506001821b61152b565b5060208310610133831016604e8410600b841016171561376f575081810a61152b565b61377983836136b1565b806000190482111561378d5761378d6134c1565b029392505050565b600061162283836136f456fe73656c656374206361737428666c6f6f72286176672870726563697069746174696f6e5f616363756d756c61746564292920617320626967696e74292066726f6d20282073656c656374206465766963655f69642c206d61782870726563697069746174696f6e5f616363756d756c61746564292061732070726563697069746174696f6e5f616363756d756c617465642066726f6d20776561746865725f73746174696f6e732067726f7570206279206465766963655f6964202920a164736f6c6343000819000a000000000000000000000000f1960569d1b4a23c34109d9341af6496ed90c0c3
Deployed Bytecode
0x60806040526004361061005a5760003560e01c80634b9ba446116100435780634b9ba446146100895780638b6f0d74146100c6578063cae6a407146100e657600080fd5b8063272001e71461005f5780633ccfd60b14610074575b600080fd5b61007261006d366004612df4565b6100f9565b005b34801561008057600080fd5b506100726105ab565b34801561009557600080fd5b506100a96100a4366004612df4565b61065c565b60405167ffffffffffffffff909116815260200160405180910390f35b3480156100d257600080fd5b506100726100e1366004613139565b610bf6565b6100a96100f43660046131f5565b611258565b67ffffffffffffffff8082166000908152600260208181526040808420815161010080820184528254808916835273ffffffffffffffffffffffffffffffffffffffff6801000000000000000090910481169583019590955260018301549382019390935293810154909216606084015260038201546080840152600482015460ff8116151560a08501520490931660c08201526005830180549293919260e0840191906101a690613245565b80601f01602080910402602001604051908101604052809291908181526020018280546101d290613245565b801561021f5780601f106101f45761010080835404028352916020019161021f565b820191906000526020600020905b81548152906001019060200180831161020257829003601f168201915b50505091909252505050602081015190915073ffffffffffffffffffffffffffffffffffffffff166102985760405162461bcd60e51b815260206004820152601560248201527f706f6c69637920646f6573206e6f74206578697374000000000000000000000060448201526064015b60405180910390fd5b606081015173ffffffffffffffffffffffffffffffffffffffff16156103005760405162461bcd60e51b815260206004820152601b60248201527f706f6c6963792077617320616c72656164792061636365707465640000000000604482015260640161028f565b8060a00151156103525760405162461bcd60e51b815260206004820152601a60248201527f706f6c6963792077617320616c726561647920736574746c6564000000000000604482015260640161028f565b806040015134116103cb5760405162461bcd60e51b815260206004820152602260248201527f6e65656420746f2070726f766964652073756666696369656e74206465706f7360448201527f6974000000000000000000000000000000000000000000000000000000000000606482015260840161028f565b3360608201908152346080830190815267ffffffffffffffff84811660009081526002602081815260409283902087518154928901519086167fffffffff00000000000000000000000000000000000000000000000000000000909316929092176801000000000000000073ffffffffffffffffffffffffffffffffffffffff93841602178155928701516001840155945190820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909516179093559051600383015560a083015160048301805460c08601517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009091169215157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1692909217610100929093169190910291909117905560e0820151829190600582019061051890826132da565b50905050806060015173ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167fac9f49869e29bfd82412359f358df8bf88224381ef1995ad3fb0e5b51c129c298460400151856080015160405161059f929190918252602082015260400190565b60405180910390a45050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106125760405162461bcd60e51b815260206004820152601760248201527f4f6e6c79206f776e65722063616e207769746864726177000000000000000000604482015260640161028f565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116914780156108fc02929091818181858888f19350505050158015610659573d6000803e3d6000fd5b50565b67ffffffffffffffff8082166000908152600260208181526040808420815161010080820184528254808916835273ffffffffffffffffffffffffffffffffffffffff6801000000000000000090910481169583019590955260018301549382019390935293810154909216606084015260038201546080840152600482015460ff8116151560a08501520490931660c082015260058301805492938493909160e084019161070a90613245565b80601f016020809104026020016040519081016040528092919081815260200182805461073690613245565b80156107835780601f1061075857610100808354040283529160200191610783565b820191906000526020600020905b81548152906001019060200180831161076657829003601f168201915b50505091909252505050602081015190915073ffffffffffffffffffffffffffffffffffffffff166107f75760405162461bcd60e51b815260206004820152601560248201527f706f6c69637920646f6573206e6f742065786973740000000000000000000000604482015260640161028f565b8060a00151156108495760405162461bcd60e51b815260206004820152601a60248201527f706f6c6963792077617320616c726561647920736574746c6564000000000000604482015260640161028f565b606081015173ffffffffffffffffffffffffffffffffffffffff16610a0f57600160a0820181815267ffffffffffffffff85811660009081526002602081815260409283902087518154928901519086167fffffffff00000000000000000000000000000000000000000000000000000000909316929092176801000000000000000073ffffffffffffffffffffffffffffffffffffffff938416021781559287015195830195909555606086015190820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919095161790935560808401516003840155905160048301805460c08601517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009091169215157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1692909217610100929093169190910291909117905560e082015182919060058201906109b390826132da565b50905050806020015173ffffffffffffffffffffffffffffffffffffffff166108fc82604001519081150290604051600060405180830381858888f19350505050158015610a05573d6000803e3d6000fd5b5060009392505050565b6000610a19611531565b9050610a696040518060400160405280601081526020017f776561746865725f73746174696f6e73000000000000000000000000000000008152508360e001518361156f9092919063ffffffff16565b610a8c6040518060e0016040528060bd81526020016137a260bd9139829061158d565b6001546040517fb8853b5400000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff169063b8853b5490610aeb9085903090638b6f0d74906004016133b8565b6020604051808303816000875af1158015610b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2e9190613475565b67ffffffffffffffff81811660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000168b8616179055606088810151898301518a518b86015160808d01518751918252958101959095529484019590955295965073ffffffffffffffffffffffffffffffffffffffff958616959093169391909116917f54bd3a28af22ebd07e9ba95adde85521fe7ae950fc9d3b4f5574b6deb506de11910160405180910390a4949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c5d5760405162461bcd60e51b815260206004820152601c60248201527f43616e206f6e6c792062652063616c6c6564206279206f7261636c6500000000604482015260640161028f565b600060036000610c6b845190565b67ffffffffffffffff908116825260208201929092526040016000908120549091169150819003610cde5760405162461bcd60e51b815260206004820152601e60248201527f636f72726573706f6e64696e6720706f6c696379206e6f7420666f756e640000604482015260640161028f565b67ffffffffffffffff8082166000908152600260208181526040808420815161010080820184528254808916835273ffffffffffffffffffffffffffffffffffffffff6801000000000000000090910481169583019590955260018301549382019390935293810154909216606084015260038201546080840152600482015460ff8116151560a08501520490931660c08201526005830180549293919260e084019190610d8b90613245565b80601f0160208091040260200160405190810160405280929190818152602001828054610db790613245565b8015610e045780601f10610dd957610100808354040283529160200191610e04565b820191906000526020600020905b815481529060010190602001808311610de757829003601f168201915b50505091909252505050602081015190915073ffffffffffffffffffffffffffffffffffffffff1615801590610e535750606081015173ffffffffffffffffffffffffffffffffffffffff1615155b610e9f5760405162461bcd60e51b815260206004820152601a60248201527f706f6c69637920697320696e20696e76616c6964207374617465000000000000604482015260640161028f565b8060a0015115610ef15760405162461bcd60e51b815260206004820152601660248201527f706f6c69637920616c726561647920736574746c656400000000000000000000604482015260640161028f565b610efa836115dc565b67ffffffffffffffff16600114610f535760405162461bcd60e51b815260206004820152601360248201527f4578706563746564206f6e65207265636f726400000000000000000000000000604482015260640161028f565b6000610f5f84826115f0565b90506000610f8682600081518110610f7957610f79613492565b6020026020010151611629565b60c084018051600160a0870181815267ffffffffffffffff8981166000908152600260208181526040928390208c518154928e01519086167fffffffff00000000000000000000000000000000000000000000000000000000909316929092176801000000000000000073ffffffffffffffffffffffffffffffffffffffff93841602178155928c01519583019590955560608b015190820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919095161790935560808901516003840155905160048301805495517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009096169115157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1691909117610100958316959095029490941790935560e0870151939450908216918416919091109185919060058201906110e290826132da565b50905050836060015173ffffffffffffffffffffffffffffffffffffffff16846020015173ffffffffffffffffffffffffffffffffffffffff16856000015167ffffffffffffffff167f3cba6f1baeb45c5440208ba050bfeb9e604dc591d7661cf2c7d8065351423a048760400151886080015161115e8c5190565b60408051938452602084019290925267ffffffffffffffff1690820152851515606082015260800160405180910390a480156111f457836020015173ffffffffffffffffffffffffffffffffffffffff166108fc856080015186604001516111c691906134f0565b6040518115909202916000818181858888f193505050501580156111ee573d6000803e3d6000fd5b50611250565b836060015173ffffffffffffffffffffffffffffffffffffffff166108fc8560800151866040015161122691906134f0565b6040518115909202916000818181858888f1935050505015801561124e573d6000803e3d6000fd5b505b505050505050565b6000346000036112aa5760405162461bcd60e51b815260206004820152601960248201527f6e65656420746f2070726f766964652061206465706f73697400000000000000604482015260640161028f565b6001805481906014906112e090839074010000000000000000000000000000000000000000900467ffffffffffffffff16613503565b825467ffffffffffffffff91821661010093840a908102920219161790915560408051918201815260008083526020830181905290820181905260608083018290526080830182905260a0830182905260c083019190915260e082015290506001805474010000000000000000000000000000000000000000900467ffffffffffffffff9081168084523360208086019182523460408088019182528a861660c0890190815260e089018b81526000968752600294859052919095208851815495519088167fffffffff00000000000000000000000000000000000000000000000000000000909616959095176801000000000000000073ffffffffffffffffffffffffffffffffffffffff96871602178155915196820196909655606087015191810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001692909316919091179091556080850151600382015560a085015160048201805493517fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000009094169115157fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff16919091176101009390941692909202929092179055905182919060058201906114bc90826132da565b50905050806020015173ffffffffffffffffffffffffffffffffffffffff16816000015167ffffffffffffffff167fe9b43372ad2470bf088a19481efde518124553fb2f7cb1216c0b8f83cf15ff45836040015160405161151f91815260200190565b60405180910390a35190505b92915050565b611539612d86565b60006115466104006116c6565b9050611551816116e7565b61155c81600161170b565b6040805160208101909152908152919050565b600061157a82611717565b905061158784848361191c565b50505050565b60408051808201909152600381527f73716c0000000000000000000000000000000000000000000000000000000000602082015282516115cc91611978565b81516115d89082611978565b5050565b6000600182604001515161152b919061352b565b606061162283604001518367ffffffffffffffff168151811061161557611615613492565b6020026020010151611991565b9392505050565b6000816040015160ff1660010361166657600061164e83600001518460600151611c64565b905061162267ffffffffffffffff821660001961353e565b816040015160ff1660000361167e5761152b82611d46565b60408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff90911660048201526001602482015260440161028f565b919050565b6116ce612d9e565b80516116da9083611dc4565b5060006020820152919050565b6116f2816004611e3b565b60018160200181815161170591906134f0565b90525050565b6115d882600083611e52565b80516060908290604d1461176d5760405162461bcd60e51b815260206004820152600b60248201527f496e76616c696420444944000000000000000000000000000000000000000000604482015260640161028f565b6117768161355e565b76ffffffffffffffffffffffffffffffffffffffffffffff19167f6469643a6f64663a660000000000000000000000000000000000000000000000146117fe5760405162461bcd60e51b815260206004820152600b60248201527f496e76616c696420444944000000000000000000000000000000000000000000604482015260640161028f565b6040805160228082526060820190925260009160208201818036833701905050905060005b60228161ffff16101561191457600061183d8260026135ae565b6118489060096135d4565b9050611899846118598360016135d4565b61ffff168151811061186d5761186d613492565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016611f73565b60046118b4868461ffff168151811061186d5761186d613492565b60ff16901b6118c391906135ef565b60f81b838361ffff16815181106118dc576118dc613492565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050600101611823565b509392505050565b60408051808201909152600281527f64730000000000000000000000000000000000000000000000000000000000006020820152835161195b91611978565b82516119679083611978565b825161197390826121c3565b505050565b6119858260038351611e52565b815161197390826121d0565b60608160048060ff16826040015160ff16146119eb5760408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff9182166004820152908216602482015260440161028f565b60006119ff85600001518660600151611c64565b9050611a0c816001613503565b67ffffffffffffffff1667ffffffffffffffff811115611a2e57611a2e612e11565b604051908082528060200260200182016040528015611a9e57816020015b6040805161010081018252606060c08201818152600060e0840181905290835260208084018290529383018190529082018190526080820181905260a08201528252600019909201910181611a4c5790505b50935060005b8167ffffffffffffffff16811015611c3357611abf866121f1565b9550611b98866040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091526040805160c081018083528451610100830184526060909152600060e0830152825180840190935280518352602090810151908301529081908152602001836020015160ff168152602001836040015160ff168152602001836060015160ff168152602001836080015167ffffffffffffffff1681526020018360a0015167ffffffffffffffff168152509050919050565b858281518110611baa57611baa613492565b6020026020010181905250600460ff16866040015160ff1603611c03576000611bd287611991565b90508060018251611be3919061352b565b81518110611bf357611bf3613492565b6020026020010151965050611c2b565b600560ff16866040015160ff1603611c20576000611bd287612252565b611c2986612578565b505b600101611aa4565b5084848267ffffffffffffffff1681518110611c5157611c51613492565b6020026020010181905250505050919050565b600060188260ff161015611c7c575060ff811661152b565b8160ff16601803611c9a57611c908361278c565b60ff16905061152b565b8160ff16601903611cb957611cae83612807565b61ffff16905061152b565b8160ff16601a03611cda57611ccd8361288c565b63ffffffff16905061152b565b8160ff16601b03611cf557611cee83612904565b905061152b565b8160ff16601f03611d0f575067ffffffffffffffff61152b565b6040517f6d785b1300000000000000000000000000000000000000000000000000000000815260ff8316600482015260240161028f565b60008160008060ff16826040015160ff1614611da05760408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff9182166004820152908216602482015260440161028f565b611db284600001518560600151611c64565b67ffffffffffffffff16949350505050565b604080518082019091526060815260006020820152611de4602083613608565b15611e0c57611df4602083613608565b611dff90602061352b565b611e0990836134f0565b91505b602080840183905260405180855260008152908184010181811015611e3057600080fd5b604052509192915050565b815161197390601f611fe0600585901b161761297c565b60178167ffffffffffffffff1611611e795782516115879060e0600585901b16831761297c565b60ff8167ffffffffffffffff1611611ebb578251611ea2906018611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660016129e5565b61ffff8167ffffffffffffffff1611611efe578251611ee5906019611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660026129e5565b63ffffffff8167ffffffffffffffff1611611f43578251611f2a90601a611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660046129e5565b8251611f5a90601b611fe0600586901b161761297c565b5082516115879067ffffffffffffffff831660086129e5565b60007f30000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000083161080159061200957507f39000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000831611155b1561201d5761152b603060f884901c613643565b7f61000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008316108015906120b157507f66000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000831611155b156120d15760616120c760f884901c600a6135ef565b61152b9190613643565b7f41000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000083161080159061216557507f46000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000831611155b1561217b5760416120c760f884901c600a6135ef565b60405162461bcd60e51b815260206004820152600e60248201527f4e6f742061206865782063686172000000000000000000000000000000000000604482015260640161028f565b6119858260028351611e52565b60408051808201909152606081526000602082015261162283838451612a6a565b6040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091528151805151602090910151101561224e57815161152b90612b3b565b5090565b60608160058060ff16826040015160ff16146122ac5760408083015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff9182166004820152908216602482015260440161028f565b60006122c085600001518660600151611c64565b6122cb90600261365c565b90506122d8816001613503565b67ffffffffffffffff1667ffffffffffffffff8111156122fa576122fa612e11565b60405190808252806020026020018201604052801561236a57816020015b6040805161010081018252606060c08201818152600060e0840181905290835260208084018290529383018190529082018190526080820181905260a082015282526000199092019101816123185790505b50935060005b8167ffffffffffffffff16811015611c335761238b866121f1565b9550612464866040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091526040805160c081018083528451610100830184526060909152600060e0830152825180840190935280518352602090810151908301529081908152602001836020015160ff168152602001836040015160ff168152602001836060015160ff168152602001836080015167ffffffffffffffff1681526020018360a0015167ffffffffffffffff168152509050919050565b85828151811061247657612476613492565b602090810291909101015261248c600282613608565b1580156124a15750604086015160ff16600314155b156124e95760408087015190517e1000a000000000000000000000000000000000000000000000000000000000815260ff90911660048201526003602482015260440161028f565b604086015160ff16600414806125065750604086015160ff166005145b1561256557604086015160009060ff1660041461252b5761252687612252565b612534565b61253487611991565b90508060018251612545919061352b565b8151811061255557612555613492565b6020026020010151965050612570565b61256e86612578565b505b600101612370565b6040805161010081018252606060c08201818152600060e08401819052908352602083018190528284018190529082018190526080820181905260a08201529082015160ff1615806125d15750604082015160ff166001145b8061260a5750604082015160ff1660071480156125f657506019826060015160ff1610155b801561260a5750601b826060015160ff1611155b1561263e5761261882612ce9565b67ffffffffffffffff16826000015160200181815161263791906134f0565b9052505090565b604082015160ff166003148061265b5750604082015160ff166002145b156126a057600061267483600001518460600151611c64565b90508067ffffffffffffffff16836000015160200181815161269691906134f0565b90525061224e9050565b604082015160ff16600414806126bd5750604082015160ff166005145b156126e7576126d482600001518360600151611c64565b67ffffffffffffffff1660808301525090565b604082015160ff1660071415806127195750816060015160ff166014141580156127195750816060015160ff16601514155b1561224e5760405162461bcd60e51b815260206004820152602760248201527f43626f725265616465722e736b69703a20756e737570706f72746564206d616a60448201527f6f72207479706500000000000000000000000000000000000000000000000000606482015260840161028f565b60008160200151826000015151808211156127dd576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b83516020850180518083016001015195509081906127fa82613680565b8152505050505050919050565b60008160200151600261281a91906134f0565b82515180821115612861576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b835160208501805160028184018101519650909161287f82846134f0565b9052509395945050505050565b60008160200151600461289f91906134f0565b825151808211156128e6576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b835160208501805160048184018101519650909161287f82846134f0565b60008160200151600861291791906134f0565b8251518082111561295e576040517f63a056dd000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161028f565b835160208501805160088184018101519650909161287f82846134f0565b60408051808201909152606081526000602082015282515160006129a18260016134f0565b9050846020015182106129c2576129c2856129bd83600261369a565b612d6f565b84516020838201018581535080518211156129db578181525b5093949350505050565b6040805180820190915260608152600060208201528351516000612a0982856134f0565b90508560200151811115612a2657612a26866129bd83600261369a565b60006001612a3686610100613795565b612a40919061352b565b90508651828101878319825116178152508051831115612a5e578281525b50959695505050505050565b6040805180820190915260608152600060208201528251821115612a8d57600080fd5b8351516000612a9c84836134f0565b90508560200151811115612ab957612ab9866129bd83600261369a565b855180518382016020019160009180851115612ad3578482525b505050602086015b60208610612b135780518252612af26020836134f0565b9150612aff6020826134f0565b9050612b0c60208761352b565b9550612adb565b51815160001960208890036101000a0190811690199190911617905250849150509392505050565b6040805161010081018252606060c08201818152600060e084018190529083526020830181905292820183905281018290526080810182905260a08101919091528151518290600003612bba576040517f240db51c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060ff8167ffffffffffffffff8160015b8015612c5c57612bdb8961278c565b955081612be781613680565b6007600589901c169650601f881695509250507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa8501612c54576020890151612c308a86611c64565b9350808a60200151612c42919061352b565b612c4c90846134f0565b925050612bcc565b506000612bcc565b600760ff86161115612c9f576040517fbd2ac87900000000000000000000000000000000000000000000000000000000815260ff8616600482015260240161028f565b506040805160c08101825289815260ff96871660208201529486169085015291909316606083015267ffffffffffffffff908116608083015290911660a082015291505b50919050565b60006018826060015160ff161015612d0357506000919050565b601c826060015160ff161015612d325760188260600151612d249190613643565b60ff166001901b9050919050565b60608201516040517f6d785b1300000000000000000000000000000000000000000000000000000000815260ff909116600482015260240161028f565b8151612d7b8383611dc4565b5061158783826121d0565b6040518060200160405280612d99612d9e565b905290565b6040518060400160405280612dc6604051806040016040528060608152602001600081525090565b8152602001600081525090565b67ffffffffffffffff8116811461065957600080fd5b80356116c181612dd3565b600060208284031215612e0657600080fd5b813561162281612dd3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715612e6357612e63612e11565b60405290565b6040805190810167ffffffffffffffff81118282101715612e6357612e63612e11565b6040516080810167ffffffffffffffff81118282101715612e6357612e63612e11565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612ef657612ef6612e11565b604052919050565b600067ffffffffffffffff831115612f1857612f18612e11565b612f4960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601612eaf565b9050828152838383011115612f5d57600080fd5b828260208301376000602084830101529392505050565b803560ff811681146116c157600080fd5b600082601f830112612f9657600080fd5b8135602067ffffffffffffffff80831115612fb357612fb3612e11565b8260051b612fc2838201612eaf565b9384528581018301938381019088861115612fdc57600080fd5b84880192505b8583101561310d57823584811115612ff957600080fd5b88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060c0828c038201121561302e57600080fd5b613036612e40565b878301358781111561304757600080fd5b83016040818e038401121561305b57600080fd5b613063612e69565b9250888101358881111561307657600080fd5b8101603f81018e1361308757600080fd5b6130988e8b83013560408401612efe565b845250604081013589840152508181526130b460408401612f74565b888201526130c460608401612f74565b60408201526130d560808401612f74565b60608201526130e660a08401612de9565b60808201526130f760c08401612de9565b60a0820152845250509184019190840190612fe2565b98975050505050505050565b600082601f83011261312a57600080fd5b61162283833560208501612efe565b60006020828403121561314b57600080fd5b813567ffffffffffffffff8082111561316357600080fd5b908301906080828603121561317757600080fd5b61317f612e8c565b823561318a81612dd3565b81526020830135801515811461319f57600080fd5b60208201526040830135828111156131b657600080fd5b6131c287828601612f85565b6040830152506060830135828111156131da57600080fd5b6131e687828601613119565b60608301525095945050505050565b6000806040838503121561320857600080fd5b823561321381612dd3565b9150602083013567ffffffffffffffff81111561322f57600080fd5b61323b85828601613119565b9150509250929050565b600181811c9082168061325957607f821691505b602082108103612ce3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f821115611973576000816000526020600020601f850160051c810160208610156132bb5750805b601f850160051c820191505b81811015611250578281556001016132c7565b815167ffffffffffffffff8111156132f4576132f4612e11565b613308816133028454613245565b84613292565b602080601f83116001811461333d57600084156133255750858301515b600019600386901b1c1916600185901b178555611250565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561338a5788860151825594840194600190910190840161336b565b50858210156133a85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000845160208060408501528151604060608601528051604060a087015280518060e088015260005b8181101561340257828101850151888201610100015284016133e5565b506000878201610100908101919091529284015160c088015284840151608088015263ffffffff881660208a901b1760401b84880152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168601909101935061346b9050565b5050949350505050565b60006020828403121561348757600080fd5b815161162281612dd3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561152b5761152b6134c1565b67ffffffffffffffff818116838216019080821115613524576135246134c1565b5092915050565b8181038181111561152b5761152b6134c1565b8181036000831280158383131683831282161715613524576135246134c1565b6000815160208301517fffffffffffffffffff0000000000000000000000000000000000000000000000808216935060098310156135a65780818460090360031b1b83161693505b505050919050565b61ffff8181168382160280821691908281146135cc576135cc6134c1565b505092915050565b61ffff818116838216019080821115613524576135246134c1565b60ff818116838216019081111561152b5761152b6134c1565b60008261363e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60ff828116828216039081111561152b5761152b6134c1565b67ffffffffffffffff8181168382160280821691908281146135cc576135cc6134c1565b60006000198203613693576136936134c1565b5060010190565b808202811582820484141761152b5761152b6134c1565b600181815b808511156136ec5781600019048211156136d2576136d26134c1565b808516156136df57918102915b93841c93908002906136b6565b509250929050565b6000826137035750600161152b565b816137105750600061152b565b816001811461372657600281146137305761374c565b600191505061152b565b60ff841115613741576137416134c1565b50506001821b61152b565b5060208310610133831016604e8410600b841016171561376f575081810a61152b565b61377983836136b1565b806000190482111561378d5761378d6134c1565b029392505050565b600061162283836136f456fe73656c656374206361737428666c6f6f72286176672870726563697069746174696f6e5f616363756d756c61746564292920617320626967696e74292066726f6d20282073656c656374206465766963655f69642c206d61782870726563697069746174696f6e5f616363756d756c61746564292061732070726563697069746174696f6e5f616363756d756c617465642066726f6d20776561746865725f73746174696f6e732067726f7570206279206465766963655f6964202920a164736f6c6343000819000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f1960569d1b4a23c34109d9341af6496ed90c0c3
-----Decoded View---------------
Arg [0] : oracleAddr (address): 0xf1960569d1b4A23c34109D9341Af6496Ed90C0c3
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f1960569d1b4a23c34109d9341af6496ed90c0c3
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.