ETH Price: $1,682.68 (+0.42%)
Gas: 6 Gwei
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
0x60e06040122529212021-04-16 19:07:13897 days 14 hrs ago1618600033IN
 Create: ChainlinkedKeydonixOracleMainAsset
0 ETH0.31122111166

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChainlinkedKeydonixOracleMainAsset

Compiler Version
v0.6.8+commit.0bbfe453

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-04-16
*/

// File: helpers/IUniswapV2Factory.sol

// SPDX-License-Identifier: bsl-1.1

/*
  Copyright 2020 Unit Protocol: Artem Zakharov ([email protected]).
*/
pragma solidity ^0.6.8;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function createPair(address tokenA, address tokenB) external returns (address pair);
}

// File: helpers/AggregatorInterface.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov ([email protected]).
*/
pragma solidity ^0.6.8;

interface AggregatorInterface {
    function latestAnswer() external view returns (int256); // deprecated
    function latestTimestamp() external view returns (uint256); // deprecated
    function latestRound() external view returns (uint256);
    function decimals() external view returns (uint256);

    function latestRoundData()
    external
    view
    returns (
        uint80 roundId,
        int256 answer,
        uint256 startedAt,
        uint256 updatedAt,
        uint80 answeredInRound
    );
}

// File: helpers/IKeydonixOracleUsd.sol

pragma experimental ABIEncoderV2;


interface IKeydonixOracleUsd {

    // returns Q112-encoded value
    function assetToUsd(address asset, uint amount, UniswapOracle.ProofData calldata proofData) external view returns (uint);
}
// File: @keydonix/uniswap-oracle-contracts/source/UQ112x112.sol

pragma solidity 0.6.8;

// https://raw.githubusercontent.com/Uniswap/uniswap-v2-core/master/contracts/libraries/UQ112x112.sol
// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))

// range: [0, 2**112 - 1]
// resolution: 1 / 2**112

library UQ112x112 {
	uint224 constant Q112 = 2**112;

	// encode a uint112 as a UQ112x112
	function encode(uint112 y) internal pure returns (uint224 z) {
		z = uint224(y) * Q112; // never overflows
	}

	// divide a UQ112x112 by a uint112, returning a UQ112x112
	function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
		z = x / uint224(y);
	}
}

// File: @keydonix/uniswap-oracle-contracts/source/IUniswapV2Pair.sol

pragma solidity 0.6.8;

interface IUniswapV2Pair {
    function token0() external view returns (address);
    function token1() external view returns (address);

    function price0CumulativeLast() external view returns (uint256);
    function price1CumulativeLast() external view returns (uint256);

	function getReserves() external view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast);
}

// File: @keydonix/uniswap-oracle-contracts/source/Rlp.sol

pragma solidity 0.6.8;

library Rlp {
	uint constant DATA_SHORT_START = 0x80;
	uint constant DATA_LONG_START = 0xB8;
	uint constant LIST_SHORT_START = 0xC0;
	uint constant LIST_LONG_START = 0xF8;

	uint constant DATA_LONG_OFFSET = 0xB7;
	uint constant LIST_LONG_OFFSET = 0xF7;


	struct Item {
		uint _unsafe_memPtr;    // Pointer to the RLP-encoded bytes.
		uint _unsafe_length;    // Number of bytes. This is the full length of the string.
	}

	struct Iterator {
		Item _unsafe_item;   // Item that's being iterated over.
		uint _unsafe_nextPtr;   // Position of the next item in the list.
	}

	/* Iterator */

	function next(Iterator memory self) internal pure returns (Item memory subItem) {
		require(hasNext(self), "Rlp.sol:Rlp:next:1");
		uint256 ptr = self._unsafe_nextPtr;
		uint256 itemLength = _itemLength(ptr);
		subItem._unsafe_memPtr = ptr;
		subItem._unsafe_length = itemLength;
		self._unsafe_nextPtr = ptr + itemLength;
	}

	function next(Iterator memory self, bool strict) internal pure returns (Item memory subItem) {
		subItem = next(self);
		require(!strict || _validate(subItem), "Rlp.sol:Rlp:next:2");
	}

	function hasNext(Iterator memory self) internal pure returns (bool) {
		Rlp.Item memory item = self._unsafe_item;
		return self._unsafe_nextPtr < item._unsafe_memPtr + item._unsafe_length;
	}

	/* Item */

	/// @dev Creates an Item from an array of RLP encoded bytes.
	/// @param self The RLP encoded bytes.
	/// @return An Item
	function toItem(bytes memory self) internal pure returns (Item memory) {
		uint len = self.length;
		if (len == 0) {
			return Item(0, 0);
		}
		uint memPtr;
		assembly {
			memPtr := add(self, 0x20)
		}
		return Item(memPtr, len);
	}

	/// @dev Creates an Item from an array of RLP encoded bytes.
	/// @param self The RLP encoded bytes.
	/// @param strict Will throw if the data is not RLP encoded.
	/// @return An Item
	function toItem(bytes memory self, bool strict) internal pure returns (Item memory) {
		Rlp.Item memory item = toItem(self);
		if(strict) {
			uint len = self.length;
			require(_payloadOffset(item) <= len, "Rlp.sol:Rlp:toItem4");
			require(_itemLength(item._unsafe_memPtr) == len, "Rlp.sol:Rlp:toItem:5");
			require(_validate(item), "Rlp.sol:Rlp:toItem:6");
		}
		return item;
	}

	/// @dev Check if the Item is null.
	/// @param self The Item.
	/// @return 'true' if the item is null.
	function isNull(Item memory self) internal pure returns (bool) {
		return self._unsafe_length == 0;
	}

	/// @dev Check if the Item is a list.
	/// @param self The Item.
	/// @return 'true' if the item is a list.
	function isList(Item memory self) internal pure returns (bool) {
		if (self._unsafe_length == 0)
			return false;
		uint memPtr = self._unsafe_memPtr;
		bool result;
		assembly {
			result := iszero(lt(byte(0, mload(memPtr)), 0xC0))
		}
		return result;
	}

	/// @dev Check if the Item is data.
	/// @param self The Item.
	/// @return 'true' if the item is data.
	function isData(Item memory self) internal pure returns (bool) {
		if (self._unsafe_length == 0)
			return false;
		uint memPtr = self._unsafe_memPtr;
		bool result;
		assembly {
			result := lt(byte(0, mload(memPtr)), 0xC0)
		}
		return result;
	}

	/// @dev Check if the Item is empty (string or list).
	/// @param self The Item.
	/// @return result 'true' if the item is null.
	function isEmpty(Item memory self) internal pure returns (bool) {
		if(isNull(self))
			return false;
		uint b0;
		uint memPtr = self._unsafe_memPtr;
		assembly {
			b0 := byte(0, mload(memPtr))
		}
		return (b0 == DATA_SHORT_START || b0 == LIST_SHORT_START);
	}

	/// @dev Get the number of items in an RLP encoded list.
	/// @param self The Item.
	/// @return The number of items.
	function items(Item memory self) internal pure returns (uint) {
		if (!isList(self))
			return 0;
		uint b0;
		uint memPtr = self._unsafe_memPtr;
		assembly {
			b0 := byte(0, mload(memPtr))
		}
		uint pos = memPtr + _payloadOffset(self);
		uint last = memPtr + self._unsafe_length - 1;
		uint itms;
		while(pos <= last) {
			pos += _itemLength(pos);
			itms++;
		}
		return itms;
	}

	/// @dev Create an iterator.
	/// @param self The Item.
	/// @return An 'Iterator' over the item.
	function iterator(Item memory self) internal pure returns (Iterator memory) {
		require(isList(self), "Rlp.sol:Rlp:iterator:1");
		uint ptr = self._unsafe_memPtr + _payloadOffset(self);
		Iterator memory it;
		it._unsafe_item = self;
		it._unsafe_nextPtr = ptr;
		return it;
	}

	/// @dev Return the RLP encoded bytes.
	/// @param self The Item.
	/// @return The bytes.
	function toBytes(Item memory self) internal pure returns (bytes memory) {
		uint256 len = self._unsafe_length;
		require(len != 0, "Rlp.sol:Rlp:toBytes:2");
		bytes memory bts;
		bts = new bytes(len);
		_copyToBytes(self._unsafe_memPtr, bts, len);
		return bts;
	}

	/// @dev Decode an Item into bytes. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toData(Item memory self) internal pure returns (bytes memory) {
		require(isData(self));
		(uint256 rStartPos, uint256 len) = _decode(self);
		bytes memory bts;
		bts = new bytes(len);
		_copyToBytes(rStartPos, bts, len);
		return bts;
	}

	/// @dev Get the list of sub-items from an RLP encoded list.
	/// Warning: This is inefficient, as it requires that the list is read twice.
	/// @param self The Item.
	/// @return Array of Items.
	function toList(Item memory self) internal pure returns (Item[] memory) {
		require(isList(self), "Rlp.sol:Rlp:toList:1");
		uint256 numItems = items(self);
		Item[] memory list = new Item[](numItems);
		Rlp.Iterator memory it = iterator(self);
		uint idx;
		while(hasNext(it)) {
			list[idx] = next(it);
			idx++;
		}
		return list;
	}

	/// @dev Decode an Item into an ascii string. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toAscii(Item memory self) internal pure returns (string memory) {
		require(isData(self), "Rlp.sol:Rlp:toAscii:1");
		(uint256 rStartPos, uint256 len) = _decode(self);
		bytes memory bts = new bytes(len);
		_copyToBytes(rStartPos, bts, len);
		string memory str = string(bts);
		return str;
	}

	/// @dev Decode an Item into a uint. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toUint(Item memory self) internal pure returns (uint) {
		require(isData(self), "Rlp.sol:Rlp:toUint:1");
		(uint256 rStartPos, uint256 len) = _decode(self);
		require(len <= 32, "Rlp.sol:Rlp:toUint:3");
		require(len != 0, "Rlp.sol:Rlp:toUint:4");
		uint data;
		assembly {
			data := div(mload(rStartPos), exp(256, sub(32, len)))
		}
		return data;
	}

	/// @dev Decode an Item into a boolean. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toBool(Item memory self) internal pure returns (bool) {
		require(isData(self), "Rlp.sol:Rlp:toBool:1");
		(uint256 rStartPos, uint256 len) = _decode(self);
		require(len == 1, "Rlp.sol:Rlp:toBool:3");
		uint temp;
		assembly {
			temp := byte(0, mload(rStartPos))
		}
		require(temp <= 1, "Rlp.sol:Rlp:toBool:8");
		return temp == 1 ? true : false;
	}

	/// @dev Decode an Item into a byte. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toByte(Item memory self) internal pure returns (byte) {
		require(isData(self), "Rlp.sol:Rlp:toByte:1");
		(uint256 rStartPos, uint256 len) = _decode(self);
		require(len == 1, "Rlp.sol:Rlp:toByte:3");
		byte temp;
		assembly {
			temp := byte(0, mload(rStartPos))
		}
		return byte(temp);
	}

	/// @dev Decode an Item into an int. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toInt(Item memory self) internal pure returns (int) {
		return int(toUint(self));
	}

	/// @dev Decode an Item into a bytes32. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toBytes32(Item memory self) internal pure returns (bytes32) {
		return bytes32(toUint(self));
	}

	/// @dev Decode an Item into an address. This will not work if the
	/// Item is a list.
	/// @param self The Item.
	/// @return The decoded string.
	function toAddress(Item memory self) internal pure returns (address) {
		require(isData(self), "Rlp.sol:Rlp:toAddress:1");
		(uint256 rStartPos, uint256 len) = _decode(self);
		require(len == 20, "Rlp.sol:Rlp:toAddress:3");
		address data;
		assembly {
			data := div(mload(rStartPos), exp(256, 12))
		}
		return data;
	}

	// Get the payload offset.
	function _payloadOffset(Item memory self) private pure returns (uint) {
		if(self._unsafe_length == 0)
			return 0;
		uint b0;
		uint memPtr = self._unsafe_memPtr;
		assembly {
			b0 := byte(0, mload(memPtr))
		}
		if(b0 < DATA_SHORT_START)
			return 0;
		if(b0 < DATA_LONG_START || (b0 >= LIST_SHORT_START && b0 < LIST_LONG_START))
			return 1;
		if(b0 < LIST_SHORT_START)
			return b0 - DATA_LONG_OFFSET + 1;
		return b0 - LIST_LONG_OFFSET + 1;
	}

	// Get the full length of an Item.
	function _itemLength(uint memPtr) private pure returns (uint len) {
		uint b0;
		assembly {
			b0 := byte(0, mload(memPtr))
		}
		if (b0 < DATA_SHORT_START)
			len = 1;
		else if (b0 < DATA_LONG_START)
			len = b0 - DATA_SHORT_START + 1;
		else if (b0 < LIST_SHORT_START) {
			assembly {
				let bLen := sub(b0, 0xB7) // bytes length (DATA_LONG_OFFSET)
				let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length
				len := add(1, add(bLen, dLen)) // total length
			}
		}
		else if (b0 < LIST_LONG_START)
			len = b0 - LIST_SHORT_START + 1;
		else {
			assembly {
				let bLen := sub(b0, 0xF7) // bytes length (LIST_LONG_OFFSET)
				let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length
				len := add(1, add(bLen, dLen)) // total length
			}
		}
	}

	// Get start position and length of the data.
	function _decode(Item memory self) private pure returns (uint memPtr, uint len) {
		require(isData(self), "Rlp.sol:Rlp:_decode:1");
		uint b0;
		uint start = self._unsafe_memPtr;
		assembly {
			b0 := byte(0, mload(start))
		}
		if (b0 < DATA_SHORT_START) {
			memPtr = start;
			len = 1;
			return (memPtr, len);
		}
		if (b0 < DATA_LONG_START) {
			len = self._unsafe_length - 1;
			memPtr = start + 1;
		} else {
			uint bLen;
			assembly {
				bLen := sub(b0, 0xB7) // DATA_LONG_OFFSET
			}
			len = self._unsafe_length - 1 - bLen;
			memPtr = start + bLen + 1;
		}
		return (memPtr, len);
	}

	// Assumes that enough memory has been allocated to store in target.
	function _copyToBytes(uint sourceBytes, bytes memory destinationBytes, uint btsLen) internal pure {
		// Exploiting the fact that 'tgt' was the last thing to be allocated,
		// we can write entire words, and just overwrite any excess.
		assembly {
			let words := div(add(btsLen, 31), 32)
			let sourcePointer := sourceBytes
			let destinationPointer := add(destinationBytes, 32)
			for { let i := 0 } lt(i, words) { i := add(i, 1) }
			{
				let offset := mul(i, 32)
				mstore(add(destinationPointer, offset), mload(add(sourcePointer, offset)))
			}
			mstore(add(destinationBytes, add(32, mload(destinationBytes))), 0)
		}
	}

	// Check that an Item is valid.
	function _validate(Item memory self) private pure returns (bool ret) {
		// Check that RLP is well-formed.
		uint b0;
		uint b1;
		uint memPtr = self._unsafe_memPtr;
		assembly {
			b0 := byte(0, mload(memPtr))
			b1 := byte(1, mload(memPtr))
		}
		if(b0 == DATA_SHORT_START + 1 && b1 < DATA_SHORT_START)
			return false;
		return true;
	}

	function rlpBytesToUint256(bytes memory source) internal pure returns (uint256 result) {
		return Rlp.toUint(Rlp.toItem(source));
	}
}

// File: @keydonix/uniswap-oracle-contracts/source/MerklePatriciaVerifier.sol

pragma solidity 0.6.8;


library MerklePatriciaVerifier {
	/*
	 * @dev Extracts the value from a merkle proof
	 * @param expectedRoot The expected hash of the root node of the trie.
	 * @param path The path in the trie leading to value.
	 * @param proofNodesRlp RLP encoded array of proof nodes.
	 * @return The value proven to exist in the merkle patricia tree whose root is `expectedRoot` at the path `path`
	 *
	 * WARNING: Does not currently support validation of unset/0 values!
	 */
	function getValueFromProof(bytes32 expectedRoot, bytes32 path, bytes memory proofNodesRlp) internal pure returns (bytes memory) {
		Rlp.Item memory rlpParentNodes = Rlp.toItem(proofNodesRlp);
		Rlp.Item[] memory parentNodes = Rlp.toList(rlpParentNodes);

		bytes memory currentNode;
		Rlp.Item[] memory currentNodeList;

		bytes32 nodeKey = expectedRoot;
		uint pathPtr = 0;

		// our input is a 32-byte path, but we have to prepend a single 0 byte to that and pass it along as a 33 byte memory array since that is what getNibbleArray wants
		bytes memory nibblePath = new bytes(33);
		assembly { mstore(add(nibblePath, 33), path) }
		nibblePath = _getNibbleArray(nibblePath);

		require(path.length != 0, "empty path provided");

		currentNode = Rlp.toBytes(parentNodes[0]);

		for (uint i=0; i<parentNodes.length; i++) {
			require(pathPtr <= nibblePath.length, "Path overflow");

			currentNode = Rlp.toBytes(parentNodes[i]);
			require(nodeKey == keccak256(currentNode), "node doesn't match key");
			currentNodeList = Rlp.toList(parentNodes[i]);

			if(currentNodeList.length == 17) {
				if(pathPtr == nibblePath.length) {
					return Rlp.toData(currentNodeList[16]);
				}

				uint8 nextPathNibble = uint8(nibblePath[pathPtr]);
				require(nextPathNibble <= 16, "nibble too long");
				nodeKey = Rlp.toBytes32(currentNodeList[nextPathNibble]);
				pathPtr += 1;
			} else if(currentNodeList.length == 2) {
				pathPtr += _nibblesToTraverse(Rlp.toData(currentNodeList[0]), nibblePath, pathPtr);
				// leaf node
				if(pathPtr == nibblePath.length) {
					return Rlp.toData(currentNodeList[1]);
				}
				//extension node
				require(_nibblesToTraverse(Rlp.toData(currentNodeList[0]), nibblePath, pathPtr) != 0, "invalid extension node");

				nodeKey = Rlp.toBytes32(currentNodeList[1]);
			} else {
				require(false, "unexpected length array");
			}
		}
		require(false, "not enough proof nodes");
	}

	function _nibblesToTraverse(bytes memory encodedPartialPath, bytes memory path, uint pathPtr) private pure returns (uint) {
		uint len;
		// encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath
		// and slicedPath have elements that are each one hex character (1 nibble)
		bytes memory partialPath = _getNibbleArray(encodedPartialPath);
		bytes memory slicedPath = new bytes(partialPath.length);

		// pathPtr counts nibbles in path
		// partialPath.length is a number of nibbles
		for(uint i=pathPtr; i<pathPtr+partialPath.length; i++) {
			byte pathNibble = path[i];
			slicedPath[i-pathPtr] = pathNibble;
		}

		if(keccak256(partialPath) == keccak256(slicedPath)) {
			len = partialPath.length;
		} else {
			len = 0;
		}
		return len;
	}

	// bytes byteArray must be hp encoded
	function _getNibbleArray(bytes memory byteArray) private pure returns (bytes memory) {
		bytes memory nibbleArray;
		if (byteArray.length == 0) return nibbleArray;

		uint8 offset;
		uint8 hpNibble = uint8(_getNthNibbleOfBytes(0,byteArray));
		if(hpNibble == 1 || hpNibble == 3) {
			nibbleArray = new bytes(byteArray.length*2-1);
			byte oddNibble = _getNthNibbleOfBytes(1,byteArray);
			nibbleArray[0] = oddNibble;
			offset = 1;
		} else {
			nibbleArray = new bytes(byteArray.length*2-2);
			offset = 0;
		}

		for(uint i=offset; i<nibbleArray.length; i++) {
			nibbleArray[i] = _getNthNibbleOfBytes(i-offset+2,byteArray);
		}
		return nibbleArray;
	}

	function _getNthNibbleOfBytes(uint n, bytes memory str) private pure returns (byte) {
		return byte(n%2==0 ? uint8(str[n/2])/0x10 : uint8(str[n/2])%0x10);
	}
}

// File: @keydonix/uniswap-oracle-contracts/source/BlockVerifier.sol

pragma solidity 0.6.8;

library BlockVerifier {
	function extractStateRootAndTimestamp(bytes memory rlpBytes) internal view returns (bytes32 stateRoot, uint256 blockTimestamp, uint256 blockNumber) {
		assembly {
			function revertWithReason(message, length) {
				mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
				mstore(4, 0x20)
				mstore(0x24, length)
				mstore(0x44, message)
				revert(0, add(0x44, length))
			}

			function readDynamic(prefixPointer) -> dataPointer, dataLength {
				let value := byte(0, mload(prefixPointer))
				switch lt(value, 0x80)
				case 1 {
					dataPointer := prefixPointer
					dataLength := 1
				}
				case 0 {
					dataPointer := add(prefixPointer, 1)
					dataLength := sub(value, 0x80)
				}
			}

			// get the length of the data
			let rlpLength := mload(rlpBytes)
			// move pointer forward, ahead of length
			rlpBytes := add(rlpBytes, 0x20)

			// we know the length of the block will be between 483 bytes and 709 bytes, which means it will have 2 length bytes after the prefix byte, so we can skip 3 bytes in
			// CONSIDER: we could save a trivial amount of gas by compressing most of this into a single add instruction
			let parentHashPrefixPointer := add(rlpBytes, 3)
			let parentHashPointer := add(parentHashPrefixPointer, 1)
			let uncleHashPrefixPointer := add(parentHashPointer, 32)
			let uncleHashPointer := add(uncleHashPrefixPointer, 1)
			let minerAddressPrefixPointer := add(uncleHashPointer, 32)
			let minerAddressPointer := add(minerAddressPrefixPointer, 1)
			let stateRootPrefixPointer := add(minerAddressPointer, 20)
			let stateRootPointer := add(stateRootPrefixPointer, 1)
			let transactionRootPrefixPointer := add(stateRootPointer, 32)
			let transactionRootPointer := add(transactionRootPrefixPointer, 1)
			let receiptsRootPrefixPointer := add(transactionRootPointer, 32)
			let receiptsRootPointer := add(receiptsRootPrefixPointer, 1)
			let logsBloomPrefixPointer := add(receiptsRootPointer, 32)
			let logsBloomPointer := add(logsBloomPrefixPointer, 3)
			let difficultyPrefixPointer := add(logsBloomPointer, 256)
			let difficultyPointer, difficultyLength := readDynamic(difficultyPrefixPointer)
			let blockNumberPrefixPointer := add(difficultyPointer, difficultyLength)
			let blockNumberPointer, blockNumberLength := readDynamic(blockNumberPrefixPointer)
			let gasLimitPrefixPointer := add(blockNumberPointer, blockNumberLength)
			let gasLimitPointer, gasLimitLength := readDynamic(gasLimitPrefixPointer)
			let gasUsedPrefixPointer := add(gasLimitPointer, gasLimitLength)
			let gasUsedPointer, gasUsedLength := readDynamic(gasUsedPrefixPointer)
			let timestampPrefixPointer := add(gasUsedPointer, gasUsedLength)
			let timestampPointer, timestampLength := readDynamic(timestampPrefixPointer)

			blockNumber := shr(sub(256, mul(blockNumberLength, 8)), mload(blockNumberPointer))
			let blockHash := blockhash(blockNumber)
			let rlpHash := keccak256(rlpBytes, rlpLength)
			if iszero(eq(blockHash, rlpHash)) { revertWithReason("blockHash != rlpHash", 20) }

			stateRoot := mload(stateRootPointer)
			blockTimestamp := shr(sub(256, mul(timestampLength, 8)), mload(timestampPointer))
		}
	}
}

// File: @keydonix/uniswap-oracle-contracts/source/UniswapOracle.sol

pragma solidity 0.6.8;






contract UniswapOracle {
	using UQ112x112 for uint224;

	bytes32 public constant reserveTimestampSlotHash = keccak256(abi.encodePacked(uint256(8)));
	bytes32 public constant token0Slot = keccak256(abi.encodePacked(uint256(9)));
	bytes32 public constant token1Slot = keccak256(abi.encodePacked(uint256(10)));

	struct ProofData {
		bytes block;
		bytes accountProofNodesRlp;
		bytes reserveAndTimestampProofNodesRlp;
		bytes priceAccumulatorProofNodesRlp;
	}

	function getAccountStorageRoot(address uniswapV2Pair, ProofData memory proofData) public view returns (bytes32 storageRootHash, uint256 blockNumber, uint256 blockTimestamp) {
		bytes32 stateRoot;
		(stateRoot, blockTimestamp, blockNumber) = BlockVerifier.extractStateRootAndTimestamp(proofData.block);
		bytes memory accountDetailsBytes = MerklePatriciaVerifier.getValueFromProof(stateRoot, keccak256(abi.encodePacked(uniswapV2Pair)), proofData.accountProofNodesRlp);
		Rlp.Item[] memory accountDetails = Rlp.toList(Rlp.toItem(accountDetailsBytes));
		return (Rlp.toBytes32(accountDetails[2]), blockNumber, blockTimestamp);
	}

	// This function verifies the full block is old enough (MIN_BLOCK_COUNT), not too old (or blockhash will return 0x0) and return the proof values for the two storage slots we care about
	function verifyBlockAndExtractReserveData(IUniswapV2Pair uniswapV2Pair, uint8 minBlocksBack, uint8 maxBlocksBack, bytes32 slotHash, ProofData memory proofData) public view returns
	(uint256 blockTimestamp, uint256 blockNumber, uint256 priceCumulativeLast, uint112 reserve0, uint112 reserve1, uint256 reserveTimestamp) {
		bytes32 storageRootHash;
		(storageRootHash, blockNumber, blockTimestamp) = getAccountStorageRoot(address(uniswapV2Pair), proofData);
		require (blockNumber <= block.number - minBlocksBack, "Proof does not span enough blocks");
		require (blockNumber >= block.number - maxBlocksBack, "Proof spans too many blocks");

		priceCumulativeLast = Rlp.rlpBytesToUint256(MerklePatriciaVerifier.getValueFromProof(storageRootHash, slotHash, proofData.priceAccumulatorProofNodesRlp));
		uint256 reserve0Reserve1TimestampPacked = Rlp.rlpBytesToUint256(MerklePatriciaVerifier.getValueFromProof(storageRootHash, reserveTimestampSlotHash, proofData.reserveAndTimestampProofNodesRlp));
		reserveTimestamp = reserve0Reserve1TimestampPacked >> (112 + 112);
		reserve1 = uint112((reserve0Reserve1TimestampPacked >> 112) & (2**112 - 1));
		reserve0 = uint112(reserve0Reserve1TimestampPacked & (2**112 - 1));
	}

	function getPrice(IUniswapV2Pair uniswapV2Pair, address denominationToken, uint8 minBlocksBack, uint8 maxBlocksBack, ProofData memory proofData) public view returns (uint256 price, uint256 blockNumber) {
		// exchange = the ExchangeV2Pair. check denomination token (USE create2 check?!) check gas cost
		bool denominationTokenIs0;
		if (uniswapV2Pair.token0() == denominationToken) {
			denominationTokenIs0 = true;
		} else if (uniswapV2Pair.token1() == denominationToken) {
			denominationTokenIs0 = false;
		} else {
			revert("denominationToken invalid");
		}
		return getPriceRaw(uniswapV2Pair, denominationTokenIs0, minBlocksBack, maxBlocksBack, proofData);
	}

	function getPriceRaw(IUniswapV2Pair uniswapV2Pair, bool denominationTokenIs0, uint8 minBlocksBack, uint8 maxBlocksBack, ProofData memory proofData) public view returns (uint256 price, uint256 blockNumber) {
		uint256 historicBlockTimestamp;
		uint256 historicPriceCumulativeLast;
		{
			// Stack-too-deep workaround, manual scope
			// Side-note: wtf Solidity?
			uint112 reserve0;
			uint112 reserve1;
			uint256 reserveTimestamp;
			(historicBlockTimestamp, blockNumber, historicPriceCumulativeLast, reserve0, reserve1, reserveTimestamp) = verifyBlockAndExtractReserveData(uniswapV2Pair, minBlocksBack, maxBlocksBack, denominationTokenIs0 ? token1Slot : token0Slot, proofData);
			uint256 secondsBetweenReserveUpdateAndHistoricBlock = historicBlockTimestamp - reserveTimestamp;
			// bring old record up-to-date, in case there was no cumulative update in provided historic block itself
			if (secondsBetweenReserveUpdateAndHistoricBlock > 0) {
				historicPriceCumulativeLast += secondsBetweenReserveUpdateAndHistoricBlock * uint(UQ112x112
					.encode(denominationTokenIs0 ? reserve0 : reserve1)
					.uqdiv(denominationTokenIs0 ? reserve1 : reserve0)
				);
			}
		}
		uint256 secondsBetweenProvidedBlockAndNow = block.timestamp - historicBlockTimestamp;
		price = (getCurrentPriceCumulativeLast(uniswapV2Pair, denominationTokenIs0) - historicPriceCumulativeLast) / secondsBetweenProvidedBlockAndNow;
		return (price, blockNumber);
	}

	function getCurrentPriceCumulativeLast(IUniswapV2Pair uniswapV2Pair, bool denominationTokenIs0) public view returns (uint256 priceCumulativeLast) {
		(uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = uniswapV2Pair.getReserves();
		priceCumulativeLast = denominationTokenIs0 ? uniswapV2Pair.price1CumulativeLast() : uniswapV2Pair.price0CumulativeLast();
		uint256 timeElapsed = block.timestamp - blockTimestampLast;
		priceCumulativeLast += timeElapsed * uint(UQ112x112
			.encode(denominationTokenIs0 ? reserve0 : reserve1)
			.uqdiv(denominationTokenIs0 ? reserve1 : reserve0)
		);
	}
}

// File: helpers/IKeydonixOracleEth.sol


interface IKeydonixOracleEth {

    // returns Q112-encoded value
    function assetToEth(address asset, uint amount, UniswapOracle.ProofData calldata proofData) external view returns (uint);
}
// File: helpers/IOracleEth.sol

interface IOracleEth {

    // returns Q112-encoded value
    function assetToEth(address asset, uint amount) external view returns (uint);

    // returns the value "as is"
    function ethToUsd(uint amount) external view returns (uint);

    // returns the value "as is"
    function usdToEth(uint amount) external view returns (uint);
}
// File: helpers/IOracleRegistry.sol


interface IOracleRegistry {

    struct Oracle {
        uint oracleType;
        address oracleAddress;
    }

    function WETH (  ) external view returns ( address );
    function getKeydonixOracleTypes (  ) external view returns ( uint256[] memory );
    function getOracles (  ) external view returns ( Oracle[] memory foundOracles );
    function keydonixOracleTypes ( uint256 ) external view returns ( uint256 );
    function maxOracleType (  ) external view returns ( uint256 );
    function oracleByAsset ( address asset ) external view returns ( address );
    function oracleByType ( uint256 ) external view returns ( address );
    function oracleTypeByAsset ( address ) external view returns ( uint256 );
    function oracleTypeByOracle ( address ) external view returns ( uint256 );
    function setKeydonixOracleTypes ( uint256[] calldata _keydonixOracleTypes ) external;
    function setOracle ( uint256 oracleType, address oracle ) external;
    function setOracleTypeForAsset ( address asset, uint256 oracleType ) external;
    function setOracleTypeForAssets ( address[] calldata assets, uint256 oracleType ) external;
    function unsetOracle ( uint256 oracleType ) external;
    function unsetOracleForAsset ( address asset ) external;
    function unsetOracleForAssets ( address[] calldata assets ) external;
    function vaultParameters (  ) external view returns ( address );
}

// File: helpers/SafeMath.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov ([email protected]).
*/
pragma solidity ^0.6.8;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

    /**
    * @dev Multiplies two numbers, throws on overflow.
    */
    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
        if (a == 0) {
            return 0;
        }
        c = a * b;
        assert(c / a == b);
        return c;
    }

    /**
    * @dev Integer division of two numbers, truncating the quotient.
    */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
    * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }

    /**
    * @dev Adds two numbers, throws on overflow.
    */
    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a + b;
        assert(c >= a);
        return c;
    }
}

// File: impl/ChainlinkedKeydonixOracleMainAsset.sol

/*
  Copyright 2020 Unit Protocol: Artem Zakharov ([email protected]).
*/
pragma solidity 0.6.8;










/**
 * @title ChainlinkedKeydonixOracleMainAsset
 * @dev Calculates the USD price of desired tokens
 **/
contract ChainlinkedKeydonixOracleMainAsset is UniswapOracle, IKeydonixOracleEth, IKeydonixOracleUsd {
    using SafeMath for uint;

    uint8 public constant MIN_BLOCKS_BACK = uint8(100);

    uint8 public constant MAX_BLOCKS_BACK = uint8(255);

    uint public constant ETH_USD_DENOMINATOR = 1e8;

    uint public constant Q112 = 2 ** 112;

    IUniswapV2Factory public immutable uniswapFactory;

    IOracleRegistry public immutable oracleRegistry;

    address public immutable WETH;

    constructor(
        IUniswapV2Factory uniFactory,
        IOracleRegistry _oracleRegistry
    )
        public
    {
        require(address(uniFactory) != address(0), "Unit Protocol: ZERO_ADDRESS");
        require(address(_oracleRegistry) != address(0), "Unit Protocol: ZERO_ADDRESS");

        uniswapFactory = uniFactory;
        WETH = _oracleRegistry.WETH();
        oracleRegistry = _oracleRegistry;
    }

    /**
     * @notice USD token's rate is UniswapV2 Token/WETH pool's average time weighted price between proofs' blockNumber and current block number
     * @notice Merkle proof must be in range [MIN_BLOCKS_BACK ... MAX_BLOCKS_BACK] blocks ago
     * @notice {Token}/WETH pair must exists on Uniswap
     * @param asset The token address
     * @param amount Amount of tokens
     * @param proofData Merkle proof data
     * @return Q112-encoded price of tokens in USD
     **/
    function assetToUsd(address asset, uint amount, UniswapOracle.ProofData memory proofData) public override view returns (uint) {
        uint priceInEth = assetToEth(asset, amount, proofData);
        return IOracleEth(oracleRegistry.oracleByAsset(WETH)).ethToUsd(priceInEth);
    }

    /**
     * @notice USD token's rate is UniswapV2 Token/WETH pool's average price between proof's blockNumber and current block number
     * @notice Merkle proof must be in range [MIN_BLOCKS_BACK ... MAX_BLOCKS_BACK] blocks ago
     * @notice {Token}/WETH pair must be registered on Uniswap
     * @param asset The token address
     * @param amount Amount of tokens
     * @param proofData Merkle proof data
     * @return Q112-encoded price of asset in ETH
     **/
    function assetToEth(address asset, uint amount, UniswapOracle.ProofData memory proofData) public override view returns (uint) {
        if (amount == 0) { return 0; }
        if (asset == WETH) { return amount.mul(Q112); }
        IUniswapV2Pair pair = IUniswapV2Pair(uniswapFactory.getPair(asset, WETH));
        require(address(pair) != address(0), "Unit Protocol: UNISWAP_PAIR_DOES_NOT_EXIST");
        (uint priceInEth, ) = getPrice(pair, WETH, MIN_BLOCKS_BACK, MAX_BLOCKS_BACK, proofData);
        return priceInEth.mul(amount);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IUniswapV2Factory","name":"uniFactory","type":"address"},{"internalType":"contract IOracleRegistry","name":"_oracleRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ETH_USD_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BLOCKS_BACK","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BLOCKS_BACK","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Q112","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"bytes","name":"block","type":"bytes"},{"internalType":"bytes","name":"accountProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"reserveAndTimestampProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"priceAccumulatorProofNodesRlp","type":"bytes"}],"internalType":"struct UniswapOracle.ProofData","name":"proofData","type":"tuple"}],"name":"assetToEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"bytes","name":"block","type":"bytes"},{"internalType":"bytes","name":"accountProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"reserveAndTimestampProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"priceAccumulatorProofNodesRlp","type":"bytes"}],"internalType":"struct UniswapOracle.ProofData","name":"proofData","type":"tuple"}],"name":"assetToUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"uniswapV2Pair","type":"address"},{"components":[{"internalType":"bytes","name":"block","type":"bytes"},{"internalType":"bytes","name":"accountProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"reserveAndTimestampProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"priceAccumulatorProofNodesRlp","type":"bytes"}],"internalType":"struct UniswapOracle.ProofData","name":"proofData","type":"tuple"}],"name":"getAccountStorageRoot","outputs":[{"internalType":"bytes32","name":"storageRootHash","type":"bytes32"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniswapV2Pair","name":"uniswapV2Pair","type":"address"},{"internalType":"bool","name":"denominationTokenIs0","type":"bool"}],"name":"getCurrentPriceCumulativeLast","outputs":[{"internalType":"uint256","name":"priceCumulativeLast","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniswapV2Pair","name":"uniswapV2Pair","type":"address"},{"internalType":"address","name":"denominationToken","type":"address"},{"internalType":"uint8","name":"minBlocksBack","type":"uint8"},{"internalType":"uint8","name":"maxBlocksBack","type":"uint8"},{"components":[{"internalType":"bytes","name":"block","type":"bytes"},{"internalType":"bytes","name":"accountProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"reserveAndTimestampProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"priceAccumulatorProofNodesRlp","type":"bytes"}],"internalType":"struct UniswapOracle.ProofData","name":"proofData","type":"tuple"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniswapV2Pair","name":"uniswapV2Pair","type":"address"},{"internalType":"bool","name":"denominationTokenIs0","type":"bool"},{"internalType":"uint8","name":"minBlocksBack","type":"uint8"},{"internalType":"uint8","name":"maxBlocksBack","type":"uint8"},{"components":[{"internalType":"bytes","name":"block","type":"bytes"},{"internalType":"bytes","name":"accountProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"reserveAndTimestampProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"priceAccumulatorProofNodesRlp","type":"bytes"}],"internalType":"struct UniswapOracle.ProofData","name":"proofData","type":"tuple"}],"name":"getPriceRaw","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleRegistry","outputs":[{"internalType":"contract IOracleRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserveTimestampSlotHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0Slot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1Slot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapFactory","outputs":[{"internalType":"contract IUniswapV2Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IUniswapV2Pair","name":"uniswapV2Pair","type":"address"},{"internalType":"uint8","name":"minBlocksBack","type":"uint8"},{"internalType":"uint8","name":"maxBlocksBack","type":"uint8"},{"internalType":"bytes32","name":"slotHash","type":"bytes32"},{"components":[{"internalType":"bytes","name":"block","type":"bytes"},{"internalType":"bytes","name":"accountProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"reserveAndTimestampProofNodesRlp","type":"bytes"},{"internalType":"bytes","name":"priceAccumulatorProofNodesRlp","type":"bytes"}],"internalType":"struct UniswapOracle.ProofData","name":"proofData","type":"tuple"}],"name":"verifyBlockAndExtractReserveData","outputs":[{"internalType":"uint256","name":"blockTimestamp","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"priceCumulativeLast","type":"uint256"},{"internalType":"uint112","name":"reserve0","type":"uint112"},{"internalType":"uint112","name":"reserve1","type":"uint112"},{"internalType":"uint256","name":"reserveTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"}]

60e06040523480156200001157600080fd5b506040516200231038038062002310833981016040819052620000349162000168565b6001600160a01b038216620000665760405162461bcd60e51b81526004016200005d90620001a6565b60405180910390fd5b6001600160a01b0381166200008f5760405162461bcd60e51b81526004016200005d90620001a6565b816001600160a01b03166080816001600160a01b031660601b81525050806001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b158015620000e657600080fd5b505afa158015620000fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000121919062000142565b6001600160601b0319606091821b811660c05291901b1660a05250620001f6565b60006020828403121562000154578081fd5b81516200016181620001dd565b9392505050565b600080604083850312156200017b578081fd5b82516200018881620001dd565b60208401519092506200019b81620001dd565b809150509250929050565b6020808252601b908201527f556e69742050726f746f636f6c3a205a45524f5f414444524553530000000000604082015260600190565b6001600160a01b0381168114620001f357600080fd5b50565b60805160601c60a05160601c60c05160601c6120c66200024a60003980610299528061069852806106d0528061076c528061081452508061026c52806103d9525080610505528061073d52506120c66000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c80638bdb2afa116100a2578063b01f20ec11610071578063b01f20ec146101e1578063c1ad2ede146101e9578063e46e2680146101fc578063e65d3dcd1461020f578063f3284624146102225761010b565b80638bdb2afa146101a857806392f4e5ef146101b0578063ad1a9a71146101b8578063ad5c4648146101d95761010b565b8063415588c6116100de578063415588c61461015e5780634bb93ab114610166578063545f51a41461017b57806372f4262f146101835761010b565b806314b094fb146101105780632432a15f1461013957806325483382146101415780633bf7a83e14610156575b600080fd5b61012361011e3660046119e3565b610244565b6040516101309190611c10565b60405180910390f35b610123610397565b6101496103c2565b6040516101309190612021565b6101236103c7565b6101236103cf565b61016e6103d7565b6040516101309190611c19565b6101236103fb565b610196610191366004611b26565b61040d565b60405161013096959493929190611fed565b61016e610503565b610123610527565b6101cb6101c6366004611a39565b610539565b604051610130929190611fdf565b61016e610696565b6101496106ba565b6101236101f73660046119e3565b6106bf565b61012361020a366004611abc565b61085a565b6101cb61021d366004611af4565b610a1f565b610235610230366004611996565b610b05565b60405161013093929190611c47565b6000806102528585856106bf565b604051631c0b181960e11b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906338163032906102c1907f000000000000000000000000000000000000000000000000000000000000000090600401611c19565b60206040518083038186803b1580156102d957600080fd5b505afa1580156102ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610311919061197a565b6001600160a01b031663946d1480826040518263ffffffff1660e01b815260040161033c9190611c10565b60206040518083038186803b15801561035457600080fd5b505afa158015610368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038c9190611bdb565b9150505b9392505050565b60096040516020016103a99190611c10565b6040516020818303038152906040528051906020012081565b60ff81565b600160701b81565b6305f5e10081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60086040516020016103a99190611c10565b60008060008060008060006104228c89610b05565b98509650905060ff8b1643038611156104565760405162461bcd60e51b815260040161044d90611dde565b60405180910390fd5b8960ff16430386101561047b5760405162461bcd60e51b815260040161044d90611d17565b61049261048d828b8b60600151610b9b565b610df2565b945060006104cf61048d8360086040516020016104af9190611c10565b604051602081830303815290604052805190602001208c60400151610b9b565b905060e081901c9250607081901c6001600160701b03169350806001600160701b0316945050509550955095509550955095565b7f000000000000000000000000000000000000000000000000000000000000000081565b600a6040516020016103a99190611c10565b6000806000866001600160a01b0316886001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561058157600080fd5b505afa158015610595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b9919061197a565b6001600160a01b031614156105d05750600161067a565b866001600160a01b0316886001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561061357600080fd5b505afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064b919061197a565b6001600160a01b031614156106625750600061067a565b60405162461bcd60e51b815260040161044d90611d4e565b6106878882888888610a1f565b92509250509550959350505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b606481565b6000826106ce57506000610390565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614156107235761071c83600160701b63ffffffff610e0d16565b9050610390565b60405163e6a4390560e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e6a43905906107949088907f000000000000000000000000000000000000000000000000000000000000000090600401611c2d565b60206040518083038186803b1580156107ac57600080fd5b505afa1580156107c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e4919061197a565b90506001600160a01b03811661080c5760405162461bcd60e51b815260040161044d90611f3e565b600061083d827f0000000000000000000000000000000000000000000000000000000000000000606460ff88610539565b509050610850818663ffffffff610e0d16565b9695505050505050565b600080600080856001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561089957600080fd5b505afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611b87565b9250925092508461095257856001600160a01b0316635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561091557600080fd5b505afa158015610929573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094d9190611bdb565b6109c3565b856001600160a01b0316635a3d54936040518163ffffffff1660e01b815260040160206040518083038186803b15801561098b57600080fd5b505afa15801561099f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c39190611bdb565b935063ffffffff81164203610a08866109dc57846109de565b835b6109f3886109ec57856109ee565b865b610e38565b6001600160e01b03169063ffffffff610e4a16565b6001600160e01b0316029390930195945050505050565b6000806000806000806000610a918c8b8b8e610a62576009604051602001610a479190611c10565b60405160208183030381529060405280519060200120610a8b565b600a604051602001610a749190611c10565b604051602081830303815290604052805190602001205b8c61040d565b939a50939850909650945090925090508085038015610ad857610ac88c610ab85784610aba565b835b6109f38e6109ec57856109ee565b6001600160e01b03168102850194505b5050504283900390508082610aed8c8c61085a565b0381610af557fe5b0494505050509550959350505050565b600080600080610b188560000151610e6f565b8095508194508293505050506060610b5b8288604051602001610b3b9190611bf3565b604051602081830303815290604052805190602001208860200151610b9b565b90506060610b70610b6b83610f80565b610fc3565b9050610b8f81600281518110610b8257fe5b60200260200101516110a2565b95505050509250925092565b6060610ba561180e565b610bae83610f80565b90506060610bbb82610fc3565b60408051602180825260608281019093529293509091829189916000918491602082018180368337019050509050896021820152610bf8816110ad565b9050610c1786600081518110610c0a57fe5b6020026020010151611219565b945060005b8651811015610dd9578151831115610c465760405162461bcd60e51b815260040161044d90611f88565b610c55878281518110610c0a57fe5b955085805190602001208414610c7d5760405162461bcd60e51b815260040161044d90611d85565b610c99878281518110610c8c57fe5b6020026020010151610fc3565b9450845160111415610d33578151831415610cda57610ccb85601081518110610cbe57fe5b6020026020010151611293565b98505050505050505050610390565b6000828481518110610ce857fe5b016020015160f81c90506010811115610d135760405162461bcd60e51b815260040161044d90611db5565b610d25868260ff1681518110610b8257fe5b945060018401935050610dd1565b845160021415610db957610d57610d5086600081518110610cbe57fe5b8385611310565b8251930192831415610d7357610ccb85600181518110610cbe57fe5b610d86610d5086600081518110610cbe57fe5b610da25760405162461bcd60e51b815260040161044d90611c8b565b610db285600181518110610b8257fe5b9350610dd1565b60405162461bcd60e51b815260040161044d90611e1f565b600101610c1c565b5060405162461bcd60e51b815260040161044d90611faf565b6000610e05610e0083610f80565b6113ee565b90505b919050565b600082610e1c57506000610e32565b5081810281838281610e2a57fe5b0414610e3257fe5b92915050565b6001600160701b0316600160701b0290565b60006001600160701b0382166001600160e01b03841681610e6757fe5b049392505050565b6000806000610ed7565b62461bcd60e51b60005260206004528160245280604452816044016000fd5b600080825160001a6080811060018114610eb7578015610ec357610ed0565b84935060019250610ed0565b6001850193506080820392505b5050915091565b835160208501946101e0810190607b01610ef082610e98565b019150610efc82610e98565b8082019350610f0a84610e98565b019350610f1684610e98565b019350610f2284610e98565b835160088402610100031c975087409550868b209350838614610f6157610f616014730c4d8dec6d690c2e6d040427a40e4d8e090c2e6d60631b610e79565b84519950815160088202610100031c9850505050505050509193909250565b610f8861180e565b815180610faa5750506040805180820190915260008082526020820152610e08565b6040805180820190915260209384018152928301525090565b6060610fce82611477565b610fea5760405162461bcd60e51b815260040161044d90611eb3565b6000610ff58361149e565b90506060816001600160401b038111801561100f57600080fd5b5060405190808252806020026020018201604052801561104957816020015b61103661180e565b81526020019060019003908161102e5790505b509050611054611828565b61105d856114f8565b905060005b61106b82611549565b156110985761107982611568565b83828151811061108557fe5b6020908102919091010152600101611062565b5090949350505050565b6000610e05826113ee565b6060808251600014156110c1579050610e08565b6000806110cf6000866115bf565b60f81c905060018114806110e657508060ff166003145b156111745760018551600202036001600160401b038111801561110857600080fd5b506040519080825280601f01601f191660200182016040528015611133576020820181803683370190505b50925060006111436001876115bf565b9050808460008151811061115357fe5b60200101906001600160f81b031916908160001a90535060019250506111c4565b60028551600202036001600160401b038111801561119157600080fd5b506040519080825280601f01601f1916602001820160405280156111bc576020820181803683370190505b509250600091505b60ff82165b835181101561120f576111e48360ff168203600201876115bf565b8482815181106111f057fe5b60200101906001600160f81b031916908160001a9053506001016111c9565b5091949350505050565b60208101516060908061123e5760405162461bcd60e51b815260040161044d90611e56565b6060816001600160401b038111801561125657600080fd5b506040519080825280601f01601f191660200182016040528015611281576020820181803683370190505b5090506103908460000151828461161c565b606061129e8261165a565b6112a757600080fd5b6000806112b384611680565b915091506060816001600160401b03811180156112cf57600080fd5b506040519080825280601f01601f1916602001820160405280156112fa576020820181803683370190505b50905061130883828461161c565b949350505050565b600080606061131e866110ad565b9050606081516001600160401b038111801561133957600080fd5b506040519080825280601f01601f191660200182016040528015611364576020820181803683370190505b509050845b825186018110156113be57600087828151811061138257fe5b602001015160f81c60f81b905080838884038151811061139e57fe5b60200101906001600160f81b031916908160001a90535050600101611369565b508080519060200120828051906020012014156113de57815192506113e3565b600092505b509095945050505050565b60006113f98261165a565b6114155760405162461bcd60e51b815260040161044d90611e85565b60008061142184611680565b9150915060208111156114465760405162461bcd60e51b815260040161044d90611c5d565b806114635760405162461bcd60e51b815260040161044d90611f10565b90516020919091036101000a900492915050565b600081602001516000141561148e57506000610e08565b50515160c060009190911a101590565b60006114a982611477565b6114b557506000610e08565b81518051600090811a91906114c985611702565b6020860151908301915082016000190160005b818311610850576114ec83611780565b909201916001016114dc565b611500611828565b61150982611477565b6115255760405162461bcd60e51b815260040161044d90611ce7565b600061153083611702565b835101905061153d611828565b92835260208301525090565b600061155361180e565b50508051602080820151915192015191011190565b61157061180e565b61157982611549565b6115955760405162461bcd60e51b815260040161044d90611cbb565b602082015160006115a582611780565b828452602080850182905292019390910192909252919050565b600060028306156115f05760108260028504815181106115db57fe5b016020015160f81c816115ea57fe5b06611612565b601082600285048151811061160157fe5b016020015160f81c8161161057fe5b045b60f81b9392505050565b6020601f820104836020840160005b838110156116475760208102838101519083015260010161162b565b5050505060008251602001830152505050565b600081602001516000141561167157506000610e08565b50515160c060009190911a1090565b60008061168c8361165a565b6116a85760405162461bcd60e51b815260040161044d90611ee1565b8251805160001a9060808210156116c6579250600191506116fd9050565b60b88210156116e45760018560200151039250806001019350610ed0565b602085015182820160b51901945082900360b601925050505b915091565b600081602001516000141561171957506000610e08565b8151805160001a90608082101561173557600092505050610e08565b60b8821080611750575060c08210158015611750575060f882105b1561176057600192505050610e08565b60c0821015611775575060b519019050610e08565b5060f5190192915050565b8051600090811a60808110156117995760019150611808565b60b88110156117ae57607e1981019150611808565b60c08110156117d757600183015160b76020839003016101000a9004810160b519019150611808565b60f88110156117ec5760be1981019150611808565b600183015160f76020839003016101000a9004810160f5190191505b50919050565b604051806040016040528060008152602001600081525090565b604051806040016040528061183b61180e565b8152602001600081525090565b600082601f830112611858578081fd5b81356001600160401b0381111561186d578182fd5b611880601f8201601f191660200161202f565b915080825283602082850101111561189757600080fd5b8060208401602084013760009082016020015292915050565b6000608082840312156118c1578081fd5b6118cb608061202f565b905081356001600160401b03808211156118e457600080fd5b6118f085838601611848565b8352602084013591508082111561190657600080fd5b61191285838601611848565b6020840152604084013591508082111561192b57600080fd5b61193785838601611848565b6040840152606084013591508082111561195057600080fd5b5061195d84828501611848565b60608301525092915050565b803560ff81168114610e3257600080fd5b60006020828403121561198b578081fd5b815161039081612055565b600080604083850312156119a8578081fd5b82356119b381612055565b915060208301356001600160401b038111156119cd578182fd5b6119d9858286016118b0565b9150509250929050565b6000806000606084860312156119f7578081fd5b8335611a0281612055565b92506020840135915060408401356001600160401b03811115611a23578182fd5b611a2f868287016118b0565b9150509250925092565b600080600080600060a08688031215611a50578081fd5b8535611a5b81612055565b94506020860135611a6b81612055565b9350611a7a8760408801611969565b9250611a898760608801611969565b915060808601356001600160401b03811115611aa3578182fd5b611aaf888289016118b0565b9150509295509295909350565b60008060408385031215611ace578182fd5b8235611ad981612055565b91506020830135611ae98161206d565b809150509250929050565b600080600080600060a08688031215611b0b578081fd5b8535611b1681612055565b94506020860135611a6b8161206d565b600080600080600060a08688031215611b3d578081fd5b8535611b4881612055565b9450611b578760208801611969565b9350611b668760408801611969565b92506060860135915060808601356001600160401b03811115611aa3578182fd5b600080600060608486031215611b9b578283fd5b8351611ba68161207b565b6020850151909350611bb78161207b565b604085015190925063ffffffff81168114611bd0578182fd5b809150509250925092565b600060208284031215611bec578081fd5b5051919050565b60609190911b6bffffffffffffffffffffffff1916815260140190565b90815260200190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b9283526020830191909152604082015260600190565b602080825260149082015273526c702e736f6c3a526c703a746f55696e743a3360601b604082015260600190565b602080825260169082015275696e76616c696420657874656e73696f6e206e6f646560501b604082015260600190565b602080825260129082015271526c702e736f6c3a526c703a6e6578743a3160701b604082015260600190565b602080825260169082015275526c702e736f6c3a526c703a6974657261746f723a3160501b604082015260600190565b6020808252601b908201527f50726f6f66207370616e7320746f6f206d616e7920626c6f636b730000000000604082015260600190565b60208082526019908201527f64656e6f6d696e6174696f6e546f6b656e20696e76616c696400000000000000604082015260600190565b6020808252601690820152756e6f646520646f65736e2774206d61746368206b657960501b604082015260600190565b6020808252600f908201526e6e6962626c6520746f6f206c6f6e6760881b604082015260600190565b60208082526021908201527f50726f6f6620646f6573206e6f74207370616e20656e6f75676820626c6f636b6040820152607360f81b606082015260800190565b60208082526017908201527f756e6578706563746564206c656e677468206172726179000000000000000000604082015260600190565b6020808252601590820152742936381739b7b61d2936381d3a37a13cba32b99d1960591b604082015260600190565b602080825260149082015273526c702e736f6c3a526c703a746f55696e743a3160601b604082015260600190565b602080825260149082015273526c702e736f6c3a526c703a746f4c6973743a3160601b604082015260600190565b602080825260159082015274526c702e736f6c3a526c703a5f6465636f64653a3160581b604082015260600190565b602080825260149082015273149b1c0b9cdbdb0e949b1c0e9d1bd55a5b9d0e8d60621b604082015260600190565b6020808252602a908201527f556e69742050726f746f636f6c3a20554e49535741505f504149525f444f455360408201526917d393d517d1561254d560b21b606082015260800190565b6020808252600d908201526c50617468206f766572666c6f7760981b604082015260600190565b6020808252601690820152756e6f7420656e6f7567682070726f6f66206e6f64657360501b604082015260600190565b918252602082015260400190565b958652602086019490945260408501929092526001600160701b03908116606085015216608083015260a082015260c00190565b60ff91909116815260200190565b6040518181016001600160401b038111828210171561204d57600080fd5b604052919050565b6001600160a01b038116811461206a57600080fd5b50565b801515811461206a57600080fd5b6001600160701b038116811461206a57600080fdfea26469706673582212203fd9ccd55351f7378c20686406cb078e73ae79febe7e8011fc56961496dc1a5f64736f6c63430006080033000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac00000000000000000000000075fbfe26b21fd3ea008af0c764949f8214150c8f

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061010b5760003560e01c80638bdb2afa116100a2578063b01f20ec11610071578063b01f20ec146101e1578063c1ad2ede146101e9578063e46e2680146101fc578063e65d3dcd1461020f578063f3284624146102225761010b565b80638bdb2afa146101a857806392f4e5ef146101b0578063ad1a9a71146101b8578063ad5c4648146101d95761010b565b8063415588c6116100de578063415588c61461015e5780634bb93ab114610166578063545f51a41461017b57806372f4262f146101835761010b565b806314b094fb146101105780632432a15f1461013957806325483382146101415780633bf7a83e14610156575b600080fd5b61012361011e3660046119e3565b610244565b6040516101309190611c10565b60405180910390f35b610123610397565b6101496103c2565b6040516101309190612021565b6101236103c7565b6101236103cf565b61016e6103d7565b6040516101309190611c19565b6101236103fb565b610196610191366004611b26565b61040d565b60405161013096959493929190611fed565b61016e610503565b610123610527565b6101cb6101c6366004611a39565b610539565b604051610130929190611fdf565b61016e610696565b6101496106ba565b6101236101f73660046119e3565b6106bf565b61012361020a366004611abc565b61085a565b6101cb61021d366004611af4565b610a1f565b610235610230366004611996565b610b05565b60405161013093929190611c47565b6000806102528585856106bf565b604051631c0b181960e11b81529091506001600160a01b037f00000000000000000000000075fbfe26b21fd3ea008af0c764949f8214150c8f16906338163032906102c1907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290600401611c19565b60206040518083038186803b1580156102d957600080fd5b505afa1580156102ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610311919061197a565b6001600160a01b031663946d1480826040518263ffffffff1660e01b815260040161033c9190611c10565b60206040518083038186803b15801561035457600080fd5b505afa158015610368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038c9190611bdb565b9150505b9392505050565b60096040516020016103a99190611c10565b6040516020818303038152906040528051906020012081565b60ff81565b600160701b81565b6305f5e10081565b7f00000000000000000000000075fbfe26b21fd3ea008af0c764949f8214150c8f81565b60086040516020016103a99190611c10565b60008060008060008060006104228c89610b05565b98509650905060ff8b1643038611156104565760405162461bcd60e51b815260040161044d90611dde565b60405180910390fd5b8960ff16430386101561047b5760405162461bcd60e51b815260040161044d90611d17565b61049261048d828b8b60600151610b9b565b610df2565b945060006104cf61048d8360086040516020016104af9190611c10565b604051602081830303815290604052805190602001208c60400151610b9b565b905060e081901c9250607081901c6001600160701b03169350806001600160701b0316945050509550955095509550955095565b7f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac81565b600a6040516020016103a99190611c10565b6000806000866001600160a01b0316886001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561058157600080fd5b505afa158015610595573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b9919061197a565b6001600160a01b031614156105d05750600161067a565b866001600160a01b0316886001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561061357600080fd5b505afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064b919061197a565b6001600160a01b031614156106625750600061067a565b60405162461bcd60e51b815260040161044d90611d4e565b6106878882888888610a1f565b92509250509550959350505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b606481565b6000826106ce57506000610390565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316846001600160a01b031614156107235761071c83600160701b63ffffffff610e0d16565b9050610390565b60405163e6a4390560e01b81526000906001600160a01b037f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac169063e6a43905906107949088907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290600401611c2d565b60206040518083038186803b1580156107ac57600080fd5b505afa1580156107c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e4919061197a565b90506001600160a01b03811661080c5760405162461bcd60e51b815260040161044d90611f3e565b600061083d827f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2606460ff88610539565b509050610850818663ffffffff610e0d16565b9695505050505050565b600080600080856001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561089957600080fd5b505afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190611b87565b9250925092508461095257856001600160a01b0316635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561091557600080fd5b505afa158015610929573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094d9190611bdb565b6109c3565b856001600160a01b0316635a3d54936040518163ffffffff1660e01b815260040160206040518083038186803b15801561098b57600080fd5b505afa15801561099f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c39190611bdb565b935063ffffffff81164203610a08866109dc57846109de565b835b6109f3886109ec57856109ee565b865b610e38565b6001600160e01b03169063ffffffff610e4a16565b6001600160e01b0316029390930195945050505050565b6000806000806000806000610a918c8b8b8e610a62576009604051602001610a479190611c10565b60405160208183030381529060405280519060200120610a8b565b600a604051602001610a749190611c10565b604051602081830303815290604052805190602001205b8c61040d565b939a50939850909650945090925090508085038015610ad857610ac88c610ab85784610aba565b835b6109f38e6109ec57856109ee565b6001600160e01b03168102850194505b5050504283900390508082610aed8c8c61085a565b0381610af557fe5b0494505050509550959350505050565b600080600080610b188560000151610e6f565b8095508194508293505050506060610b5b8288604051602001610b3b9190611bf3565b604051602081830303815290604052805190602001208860200151610b9b565b90506060610b70610b6b83610f80565b610fc3565b9050610b8f81600281518110610b8257fe5b60200260200101516110a2565b95505050509250925092565b6060610ba561180e565b610bae83610f80565b90506060610bbb82610fc3565b60408051602180825260608281019093529293509091829189916000918491602082018180368337019050509050896021820152610bf8816110ad565b9050610c1786600081518110610c0a57fe5b6020026020010151611219565b945060005b8651811015610dd9578151831115610c465760405162461bcd60e51b815260040161044d90611f88565b610c55878281518110610c0a57fe5b955085805190602001208414610c7d5760405162461bcd60e51b815260040161044d90611d85565b610c99878281518110610c8c57fe5b6020026020010151610fc3565b9450845160111415610d33578151831415610cda57610ccb85601081518110610cbe57fe5b6020026020010151611293565b98505050505050505050610390565b6000828481518110610ce857fe5b016020015160f81c90506010811115610d135760405162461bcd60e51b815260040161044d90611db5565b610d25868260ff1681518110610b8257fe5b945060018401935050610dd1565b845160021415610db957610d57610d5086600081518110610cbe57fe5b8385611310565b8251930192831415610d7357610ccb85600181518110610cbe57fe5b610d86610d5086600081518110610cbe57fe5b610da25760405162461bcd60e51b815260040161044d90611c8b565b610db285600181518110610b8257fe5b9350610dd1565b60405162461bcd60e51b815260040161044d90611e1f565b600101610c1c565b5060405162461bcd60e51b815260040161044d90611faf565b6000610e05610e0083610f80565b6113ee565b90505b919050565b600082610e1c57506000610e32565b5081810281838281610e2a57fe5b0414610e3257fe5b92915050565b6001600160701b0316600160701b0290565b60006001600160701b0382166001600160e01b03841681610e6757fe5b049392505050565b6000806000610ed7565b62461bcd60e51b60005260206004528160245280604452816044016000fd5b600080825160001a6080811060018114610eb7578015610ec357610ed0565b84935060019250610ed0565b6001850193506080820392505b5050915091565b835160208501946101e0810190607b01610ef082610e98565b019150610efc82610e98565b8082019350610f0a84610e98565b019350610f1684610e98565b019350610f2284610e98565b835160088402610100031c975087409550868b209350838614610f6157610f616014730c4d8dec6d690c2e6d040427a40e4d8e090c2e6d60631b610e79565b84519950815160088202610100031c9850505050505050509193909250565b610f8861180e565b815180610faa5750506040805180820190915260008082526020820152610e08565b6040805180820190915260209384018152928301525090565b6060610fce82611477565b610fea5760405162461bcd60e51b815260040161044d90611eb3565b6000610ff58361149e565b90506060816001600160401b038111801561100f57600080fd5b5060405190808252806020026020018201604052801561104957816020015b61103661180e565b81526020019060019003908161102e5790505b509050611054611828565b61105d856114f8565b905060005b61106b82611549565b156110985761107982611568565b83828151811061108557fe5b6020908102919091010152600101611062565b5090949350505050565b6000610e05826113ee565b6060808251600014156110c1579050610e08565b6000806110cf6000866115bf565b60f81c905060018114806110e657508060ff166003145b156111745760018551600202036001600160401b038111801561110857600080fd5b506040519080825280601f01601f191660200182016040528015611133576020820181803683370190505b50925060006111436001876115bf565b9050808460008151811061115357fe5b60200101906001600160f81b031916908160001a90535060019250506111c4565b60028551600202036001600160401b038111801561119157600080fd5b506040519080825280601f01601f1916602001820160405280156111bc576020820181803683370190505b509250600091505b60ff82165b835181101561120f576111e48360ff168203600201876115bf565b8482815181106111f057fe5b60200101906001600160f81b031916908160001a9053506001016111c9565b5091949350505050565b60208101516060908061123e5760405162461bcd60e51b815260040161044d90611e56565b6060816001600160401b038111801561125657600080fd5b506040519080825280601f01601f191660200182016040528015611281576020820181803683370190505b5090506103908460000151828461161c565b606061129e8261165a565b6112a757600080fd5b6000806112b384611680565b915091506060816001600160401b03811180156112cf57600080fd5b506040519080825280601f01601f1916602001820160405280156112fa576020820181803683370190505b50905061130883828461161c565b949350505050565b600080606061131e866110ad565b9050606081516001600160401b038111801561133957600080fd5b506040519080825280601f01601f191660200182016040528015611364576020820181803683370190505b509050845b825186018110156113be57600087828151811061138257fe5b602001015160f81c60f81b905080838884038151811061139e57fe5b60200101906001600160f81b031916908160001a90535050600101611369565b508080519060200120828051906020012014156113de57815192506113e3565b600092505b509095945050505050565b60006113f98261165a565b6114155760405162461bcd60e51b815260040161044d90611e85565b60008061142184611680565b9150915060208111156114465760405162461bcd60e51b815260040161044d90611c5d565b806114635760405162461bcd60e51b815260040161044d90611f10565b90516020919091036101000a900492915050565b600081602001516000141561148e57506000610e08565b50515160c060009190911a101590565b60006114a982611477565b6114b557506000610e08565b81518051600090811a91906114c985611702565b6020860151908301915082016000190160005b818311610850576114ec83611780565b909201916001016114dc565b611500611828565b61150982611477565b6115255760405162461bcd60e51b815260040161044d90611ce7565b600061153083611702565b835101905061153d611828565b92835260208301525090565b600061155361180e565b50508051602080820151915192015191011190565b61157061180e565b61157982611549565b6115955760405162461bcd60e51b815260040161044d90611cbb565b602082015160006115a582611780565b828452602080850182905292019390910192909252919050565b600060028306156115f05760108260028504815181106115db57fe5b016020015160f81c816115ea57fe5b06611612565b601082600285048151811061160157fe5b016020015160f81c8161161057fe5b045b60f81b9392505050565b6020601f820104836020840160005b838110156116475760208102838101519083015260010161162b565b5050505060008251602001830152505050565b600081602001516000141561167157506000610e08565b50515160c060009190911a1090565b60008061168c8361165a565b6116a85760405162461bcd60e51b815260040161044d90611ee1565b8251805160001a9060808210156116c6579250600191506116fd9050565b60b88210156116e45760018560200151039250806001019350610ed0565b602085015182820160b51901945082900360b601925050505b915091565b600081602001516000141561171957506000610e08565b8151805160001a90608082101561173557600092505050610e08565b60b8821080611750575060c08210158015611750575060f882105b1561176057600192505050610e08565b60c0821015611775575060b519019050610e08565b5060f5190192915050565b8051600090811a60808110156117995760019150611808565b60b88110156117ae57607e1981019150611808565b60c08110156117d757600183015160b76020839003016101000a9004810160b519019150611808565b60f88110156117ec5760be1981019150611808565b600183015160f76020839003016101000a9004810160f5190191505b50919050565b604051806040016040528060008152602001600081525090565b604051806040016040528061183b61180e565b8152602001600081525090565b600082601f830112611858578081fd5b81356001600160401b0381111561186d578182fd5b611880601f8201601f191660200161202f565b915080825283602082850101111561189757600080fd5b8060208401602084013760009082016020015292915050565b6000608082840312156118c1578081fd5b6118cb608061202f565b905081356001600160401b03808211156118e457600080fd5b6118f085838601611848565b8352602084013591508082111561190657600080fd5b61191285838601611848565b6020840152604084013591508082111561192b57600080fd5b61193785838601611848565b6040840152606084013591508082111561195057600080fd5b5061195d84828501611848565b60608301525092915050565b803560ff81168114610e3257600080fd5b60006020828403121561198b578081fd5b815161039081612055565b600080604083850312156119a8578081fd5b82356119b381612055565b915060208301356001600160401b038111156119cd578182fd5b6119d9858286016118b0565b9150509250929050565b6000806000606084860312156119f7578081fd5b8335611a0281612055565b92506020840135915060408401356001600160401b03811115611a23578182fd5b611a2f868287016118b0565b9150509250925092565b600080600080600060a08688031215611a50578081fd5b8535611a5b81612055565b94506020860135611a6b81612055565b9350611a7a8760408801611969565b9250611a898760608801611969565b915060808601356001600160401b03811115611aa3578182fd5b611aaf888289016118b0565b9150509295509295909350565b60008060408385031215611ace578182fd5b8235611ad981612055565b91506020830135611ae98161206d565b809150509250929050565b600080600080600060a08688031215611b0b578081fd5b8535611b1681612055565b94506020860135611a6b8161206d565b600080600080600060a08688031215611b3d578081fd5b8535611b4881612055565b9450611b578760208801611969565b9350611b668760408801611969565b92506060860135915060808601356001600160401b03811115611aa3578182fd5b600080600060608486031215611b9b578283fd5b8351611ba68161207b565b6020850151909350611bb78161207b565b604085015190925063ffffffff81168114611bd0578182fd5b809150509250925092565b600060208284031215611bec578081fd5b5051919050565b60609190911b6bffffffffffffffffffffffff1916815260140190565b90815260200190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b9283526020830191909152604082015260600190565b602080825260149082015273526c702e736f6c3a526c703a746f55696e743a3360601b604082015260600190565b602080825260169082015275696e76616c696420657874656e73696f6e206e6f646560501b604082015260600190565b602080825260129082015271526c702e736f6c3a526c703a6e6578743a3160701b604082015260600190565b602080825260169082015275526c702e736f6c3a526c703a6974657261746f723a3160501b604082015260600190565b6020808252601b908201527f50726f6f66207370616e7320746f6f206d616e7920626c6f636b730000000000604082015260600190565b60208082526019908201527f64656e6f6d696e6174696f6e546f6b656e20696e76616c696400000000000000604082015260600190565b6020808252601690820152756e6f646520646f65736e2774206d61746368206b657960501b604082015260600190565b6020808252600f908201526e6e6962626c6520746f6f206c6f6e6760881b604082015260600190565b60208082526021908201527f50726f6f6620646f6573206e6f74207370616e20656e6f75676820626c6f636b6040820152607360f81b606082015260800190565b60208082526017908201527f756e6578706563746564206c656e677468206172726179000000000000000000604082015260600190565b6020808252601590820152742936381739b7b61d2936381d3a37a13cba32b99d1960591b604082015260600190565b602080825260149082015273526c702e736f6c3a526c703a746f55696e743a3160601b604082015260600190565b602080825260149082015273526c702e736f6c3a526c703a746f4c6973743a3160601b604082015260600190565b602080825260159082015274526c702e736f6c3a526c703a5f6465636f64653a3160581b604082015260600190565b602080825260149082015273149b1c0b9cdbdb0e949b1c0e9d1bd55a5b9d0e8d60621b604082015260600190565b6020808252602a908201527f556e69742050726f746f636f6c3a20554e49535741505f504149525f444f455360408201526917d393d517d1561254d560b21b606082015260800190565b6020808252600d908201526c50617468206f766572666c6f7760981b604082015260600190565b6020808252601690820152756e6f7420656e6f7567682070726f6f66206e6f64657360501b604082015260600190565b918252602082015260400190565b958652602086019490945260408501929092526001600160701b03908116606085015216608083015260a082015260c00190565b60ff91909116815260200190565b6040518181016001600160401b038111828210171561204d57600080fd5b604052919050565b6001600160a01b038116811461206a57600080fd5b50565b801515811461206a57600080fd5b6001600160701b038116811461206a57600080fdfea26469706673582212203fd9ccd55351f7378c20686406cb078e73ae79febe7e8011fc56961496dc1a5f64736f6c63430006080033

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

000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac00000000000000000000000075fbfe26b21fd3ea008af0c764949f8214150c8f

-----Decoded View---------------
Arg [0] : uniFactory (address): 0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac
Arg [1] : _oracleRegistry (address): 0x75fBFe26B21fd3EA008af0C764949f8214150C8f

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac
Arg [1] : 00000000000000000000000075fbfe26b21fd3ea008af0c764949f8214150c8f


Deployed Bytecode Sourcemap

31852:2754:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;31852:2754:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;33284:284:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;23087:76;;;:::i;32051:50::-;;;:::i;:::-;;;;;;;;32165:36;;;:::i;32110:46::-;;;:::i;32268:47::-;;;:::i;:::-;;;;;;;;22993:90;;;:::i;24231:1224::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;32210:49;;;:::i;23167:77::-;;;:::i;25460:677::-;;;;;;;;;:::i;:::-;;;;;;;;;32324:29;;;:::i;31992:50::-;;;:::i;34057:546::-;;;;;;;;;:::i;27607:609::-;;;;;;;;;:::i;26142:1460::-;;;;;;;;;:::i;23407:632::-;;;;;;;;;:::i;:::-;;;;;;;;;;33284:284;33404:4;33421:15;33439:36;33450:5;33457:6;33465:9;33439:10;:36::i;:::-;33504:34;;-1:-1:-1;;;33504:34:0;;33421:54;;-1:-1:-1;;;;;;33504:14:0;:28;;;;:34;;33533:4;;33504:34;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;33504:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33504:34:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;33504:34:0;;;;;;;;;-1:-1:-1;;;;;33493:55:0;;33549:10;33493:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;33493:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33493:67:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;33493:67:0;;;;;;;;;33486:74;;;33284:284;;;;;;:::o;23087:76::-;23159:1;23134:28;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;23134:28:0;;;23124:39;;;;;;23087:76;:::o;32051:50::-;32097:3;32051:50;:::o;32165:36::-;-1:-1:-1;;;32165:36:0;:::o;32110:46::-;32153:3;32110:46;:::o;32268:47::-;;;:::o;22993:90::-;23079:1;23054:28;;;;;;;;;24231:1224;24414:22;24438:19;24459:27;24488:16;24506;24524:24;24555:23;24632:56;24662:13;24678:9;24632:21;:56::i;:::-;24583:105;-1:-1:-1;24583:105:0;-1:-1:-1;24583:105:0;-1:-1:-1;24717:28:0;;;:12;:28;24702:43;;;24693:90;;;;-1:-1:-1;;;24693:90:0;;;;;;;;;;;;;;;;;24827:13;24812:28;;:12;:28;24797:11;:43;;24788:84;;;;-1:-1:-1;;;24788:84:0;;;;;;;;;24901:131;24923:108;24964:15;24981:8;24991:9;:39;;;24923:40;:108::i;:::-;24901:21;:131::i;:::-;24879:153;;25037:39;25079:150;25101:127;25142:15;23079:1;23054:28;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;23054:28:0;;;23044:39;;;;;;25185:9;:42;;;25101:40;:127::i;25079:150::-;25037:192;;25289:9;25253:31;:46;;25234:65;;25359:3;25324:31;:38;;-1:-1:-1;;;;;25323:55:0;25304:75;;25403:31;-1:-1:-1;;;;;25403:46:0;25384:66;;24231:1224;;;;;;;;;;;;;:::o;32210:49::-;;;:::o;23167:77::-;23239:2;23214:29;;;;;;;;;25460:677;25626:13;25641:19;25766:25;25826:17;-1:-1:-1;;;;;25800:43:0;:13;-1:-1:-1;;;;;25800:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;25800:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25800:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;25800:22:0;;;;;;;;;-1:-1:-1;;;;;25800:43:0;;25796:236;;;-1:-1:-1;25874:4:0;25796:236;;;25920:17;-1:-1:-1;;;;;25894:43:0;:13;-1:-1:-1;;;;;25894:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;25894:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25894:22:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;25894:22:0;;;;;;;;;-1:-1:-1;;;;;25894:43:0;;25890:142;;;-1:-1:-1;25968:5:0;25890:142;;;25991:35;;-1:-1:-1;;;25991:35:0;;;;;;;;25890:142;26043:89;26055:13;26070:20;26092:13;26107;26122:9;26043:11;:89::i;:::-;26036:96;;;;;25460:677;;;;;;;;:::o;32324:29::-;;;:::o;31992:50::-;32038:3;31992:50;:::o;34057:546::-;34177:4;34198:11;34194:30;;-1:-1:-1;34220:1:0;34213:8;;34194:30;34247:4;-1:-1:-1;;;;;34238:13:0;:5;-1:-1:-1;;;;;34238:13:0;;34234:47;;;34262:16;:6;-1:-1:-1;;;34262:16:0;:10;:16;:::i;:::-;34255:23;;;;34234:47;34328:35;;-1:-1:-1;;;34328:35:0;;34291:19;;-1:-1:-1;;;;;34328:14:0;:22;;;;:35;;34351:5;;34358:4;;34328:35;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;34328:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;34328:35:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;34328:35:0;;;;;;;;;34291:73;-1:-1:-1;;;;;;34383:27:0;;34375:82;;;;-1:-1:-1;;;34375:82:0;;;;;;;;;34469:15;34490:65;34499:4;34505;32038:3;32097;34545:9;34490:8;:65::i;:::-;-1:-1:-1;34468:87:0;-1:-1:-1;34573:22:0;34468:87;34588:6;34573:22;:14;:22;:::i;:::-;34566:29;34057:546;-1:-1:-1;;;;;;34057:546:0:o;27607:609::-;27724:27;27759:16;27777;27795:25;27824:13;-1:-1:-1;;;;;27824:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;27824:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27824:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;27824:27:0;;;;;;;;;27758:93;;;;;;27878:20;:98;;27940:13;-1:-1:-1;;;;;27940:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;27940:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27940:36:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;27940:36:0;;;;;;;;;27878:98;;;27901:13;-1:-1:-1;;;;;27901:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;27901:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27901:36:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;27901:36:0;;;;;;;;;27856:120;-1:-1:-1;28003:36:0;;;:15;:36;28086:120;28163:20;:42;;28197:8;28163:42;;;28186:8;28163:42;28086:65;28108:20;:42;;28142:8;28108:42;;;28131:8;28108:42;28086:21;:65::i;:::-;-1:-1:-1;;;;;28086:76:0;;:120;:76;:120;:::i;:::-;-1:-1:-1;;;;;28081:130:0;28067:144;28044:167;;;;;27607:609;-1:-1:-1;;;;;27607:609:0:o;26142:1460::-;26311:13;26326:19;26352:30;26387:35;26512:16;26534;26556:24;26693:136;26726:13;26741;26756;26771:20;:46;;23159:1;23134:28;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;23134:28:0;;;23124:39;;;;;;26771:46;;;23239:2;23214:29;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;23214:29:0;;;23204:40;;;;;;26771:46;26819:9;26693:32;:136::i;:::-;26586:243;;-1:-1:-1;26586:243:0;;-1:-1:-1;26586:243:0;;-1:-1:-1;26586:243:0;-1:-1:-1;26586:243:0;;-1:-1:-1;26586:243:0;-1:-1:-1;26889:41:0;;;27049:47;;27045:280;;27187:124;27268:20;:42;;27302:8;27268:42;;;27291:8;27268:42;27187:67;27211:20;:42;;27245:8;27211:42;;27187:124;-1:-1:-1;;;;;27182:136:0;27136:43;:182;27105:213;;;;27045:280;-1:-1:-1;;;27378:15:0;:40;;;;-1:-1:-1;27378:40:0;27501:27;27432:66;27462:13;27477:20;27432:29;:66::i;:::-;:96;27431:134;;;;;;;-1:-1:-1;;;;26142:1460:0;;;;;;;;:::o;23407:632::-;23510:23;23535:19;23556:22;23585:17;23650:59;23693:9;:15;;;23650:42;:59::i;:::-;23607:102;;;;;;;;;;;;23714:32;23749:127;23790:9;23828:13;23811:31;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;23811:31:0;;;23801:42;;;;;;23845:9;:30;;;23749:40;:127::i;:::-;23714:162;;23881:32;23916:43;23927:31;23938:19;23927:10;:31::i;:::-;23916:10;:43::i;:::-;23881:78;;23972:32;23986:14;24001:1;23986:17;;;;;;;;;;;;;;23972:13;:32::i;:::-;23964:70;-1:-1:-1;;;;23407:632:0;;;;;:::o;15818:1960::-;15932:12;15951:30;;:::i;:::-;15984:25;15995:13;15984:10;:25::i;:::-;15951:58;;16014:29;16046:26;16057:14;16046:10;:26::i;:::-;16398:13;;;16408:2;16398:13;;;16079:24;16398:13;;;;;;16014:58;;-1:-1:-1;16079:24:0;;;;16166:12;;16148:15;;16079:24;;16398:13;;;21:6:-1;;108:14;16398:13:0;87:42:-1;143:17;;-1:-1;16398:13:0;16372:39;;16455:4;16450:2;16438:10;16434:19;16427:33;16479:27;16495:10;16479:15;:27::i;:::-;16466:40;-1:-1:-1;16582:27:0;16594:11;16606:1;16594:14;;;;;;;;;;;;;;16582:11;:27::i;:::-;16568:41;-1:-1:-1;16621:6:0;16616:1113;16633:11;:18;16631:1;:20;16616:1113;;;16683:10;:17;16672:7;:28;;16664:54;;;;-1:-1:-1;;;16664:54:0;;;;;;;;;16740:27;16752:11;16764:1;16752:14;;;;;;;16740:27;16726:41;;16802:11;16792:22;;;;;;16781:7;:33;16773:68;;;;-1:-1:-1;;;16773:68:0;;;;;;;;;16865:26;16876:11;16888:1;16876:14;;;;;;;;;;;;;;16865:10;:26::i;:::-;16847:44;;16902:15;:22;16928:2;16902:28;16899:825;;;16953:10;:17;16942:7;:28;16939:87;;;16987:31;16998:15;17014:2;16998:19;;;;;;;;;;;;;;16987:10;:31::i;:::-;16980:38;;;;;;;;;;;;16939:87;17034:20;17063:10;17074:7;17063:19;;;;;;;;;;;;;;;-1:-1:-1;17116:2:0;17098:20;;;17090:48;;;;-1:-1:-1;;;17090:48:0;;;;;;;;;17155:46;17169:15;17185:14;17169:31;;;;;;;;;17155:46;17145:56;;17219:1;17208:12;;;;16899:825;;;;17236:15;:22;17262:1;17236:27;17233:491;;;17283:71;17302:30;17313:15;17329:1;17313:18;;;;;;;17302:30;17334:10;17346:7;17283:18;:71::i;:::-;17393:17;;17272:82;;;17382:28;;17379:86;;;17427:30;17438:15;17454:1;17438:18;;;;;;;17379:86;17501:71;17520:30;17531:15;17547:1;17531:18;;;;;;;17501:71;17493:111;;;;-1:-1:-1;;;17493:111:0;;;;;;;;;17623:33;17637:15;17653:1;17637:18;;;;;;;17623:33;17613:43;;17233:491;;;17676:41;;-1:-1:-1;;;17676:41:0;;;;;;;;;16653:3;;16616:1113;;;-1:-1:-1;17733:40:0;;-1:-1:-1;;;17733:40:0;;;;;;;;15093:134;15164:14;15192:30;15203:18;15214:6;15203:10;:18::i;:::-;15192:10;:30::i;:::-;15185:37;;15093:134;;;;:::o;30650:202::-;30708:9;30734:6;30730:47;;-1:-1:-1;30764:1:0;30757:8;;30730:47;-1:-1:-1;30791:5:0;;;30795:1;30791;:5;:1;30814:5;;;;;:10;30807:18;;;;30650:202;;;;:::o;2145:111::-;-1:-1:-1;;;;;2215:10:0;-1:-1:-1;;;2215:17:0;;2145:111::o;2321:99::-;2381:9;-1:-1:-1;;;;;2405:10:0;;-1:-1:-1;;;;;2401:14:0;;2405:10;2401:14;;;;;;2321:99;-1:-1:-1;;;2321:99:0:o;19597:3221::-;19681:17;19700:22;19724:19;19765:241;;;-1:-1:-1;;;19822:1:0;19815:77;19908:4;19905:1;19898:15;19932:6;19926:4;19919:20;19958:7;19952:4;19945:21;19992:6;19986:4;19982:17;19979:1;19972:28;20013:325;;;20110:13;20104:20;20101:1;20096:29;20148:4;20141:5;20138:15;20164:1;20159:72;;;;20237:95;;;;20131:201;;20159:72;20189:13;20174:28;;20223:1;20209:15;;20159:72;;20237:95;20286:1;20271:13;20267:21;20252:36;;20320:4;20313:5;20309:16;20295:30;;20131:201;;;20076:262;;;;;20396:15;;20487:4;20473:19;;;21688:26;;;;21229:30;;21762:36;21688:26;21762:36;;;21835:40;;-1:-1:-1;21925:37:0;21835:40;21925:37;;;22020:17;22000:18;21996:42;21967:71;;22082:34;22094:21;22082:34;;;22149:36;;-1:-1:-1;22227:33:0;22149:36;22227:33;;;22295:34;;-1:-1:-1;22375:35:0;22295:34;22375:35;;;22479:18;22473:25;22468:1;22449:17;22445:25;22440:3;22436:35;22432:67;22417:82;;22531:11;22521:22;22504:39;;22583:9;22573:8;22563:30;22548:45;;22622:7;22611:9;22608:22;22598:2;;22634:44;22675:2;-1:-1:-1;;;22634:44:0;;;22706:16;22700:23;22687:36;;22791:16;22785:23;22780:1;22763:15;22759:23;22754:3;22750:33;22746:63;22728:81;;;;;;;;;19759:3055;;;;;:::o;4500:244::-;4558:11;;:::i;:::-;4587;;4607:8;4603:43;;-1:-1:-1;;4630:10:0;;;;;;;;;-1:-1:-1;4630:10:0;;;;;;;4623:17;;4603:43;4722:17;;;;;;;;;4701:4;4691:15;;;4722:17;;;;;;-1:-1:-1;4722:17:0;4500:244::o;8607:347::-;8664:13;8692:12;8699:4;8692:6;:12::i;:::-;8684:45;;;;-1:-1:-1;;;8684:45:0;;;;;;;;;8734:16;8753:11;8759:4;8753:5;:11::i;:::-;8734:30;;8769:18;8801:8;-1:-1:-1;;;;;8790:20:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;8790:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;8769:41;;8815:22;;:::i;:::-;8840:14;8849:4;8840:8;:14::i;:::-;8815:39;;8859:8;8872:62;8878:11;8886:2;8878:7;:11::i;:::-;8872:62;;;8909:8;8914:2;8909:4;:8::i;:::-;8897:4;8902:3;8897:9;;;;;;;;;;;;;;;;;:20;8923:5;;8872:62;;;-1:-1:-1;8945:4:0;;8607:347;-1:-1:-1;;;;8607:347:0:o;11349:107::-;11409:7;11438:12;11445:4;11438:6;:12::i;18627:675::-;18698:12;18717:24;18750:9;:16;18770:1;18750:21;18746:45;;;18780:11;-1:-1:-1;18773:18:0;;18746:45;18798:12;18815:14;18838:33;18859:1;18861:9;18838:20;:33::i;:::-;18832:40;;;-1:-1:-1;18892:1:0;18880:13;;;:30;;;18897:8;:13;;18909:1;18897:13;18880:30;18877:275;;;18961:1;18942:9;:16;18959:1;18942:18;:20;-1:-1:-1;;;;;18932:31:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;18932:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;18932:31:0;87:42:-1;143:17;;-1:-1;18932:31:0;;18918:45;;18969:14;18986:33;19007:1;19009:9;18986:20;:33::i;:::-;18969:50;;19042:9;19025:11;19037:1;19025:14;;;;;;;;;;;:26;-1:-1:-1;;;;;19025:26:0;;;;;;;;;19066:1;19057:10;;18877:275;;;;19128:1;19109:9;:16;19126:1;19109:18;:20;-1:-1:-1;;;;;19099:31:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;19099:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;19099:31:0;87:42:-1;143:17;;-1:-1;19099:31:0;;19085:45;;19145:1;19136:10;;18877:275;19162:13;;;19158:117;19179:11;:18;19177:1;:20;19158:117;;;19227:42;19250:6;19248:8;;:1;:8;19257:1;19248:10;19259:9;19227:20;:42::i;:::-;19210:11;19222:1;19210:14;;;;;;;;;;;:59;-1:-1:-1;;;;;19210:59:0;;;;;;;;-1:-1:-1;19199:3:0;;19158:117;;;-1:-1:-1;19286:11:0;;18627:675;-1:-1:-1;;;;18627:675:0:o;7723:271::-;7814:19;;;;7781:12;;7846:8;7838:42;;;;-1:-1:-1;;;7838:42:0;;;;;;;;;7885:16;7922:3;-1:-1:-1;;;;;7912:14:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;7912:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;7912::0;87:42:-1;143:17;;-1:-1;7912:14:0;;7906:20;;7931:43;7944:4;:19;;;7965:3;7970;7931:12;:43::i;8147:254::-;8204:12;8231;8238:4;8231:6;:12::i;:::-;8223:21;;12:1:-1;9;2:12;8223:21:0;8250:17;8269:11;8284:13;8292:4;8284:7;:13::i;:::-;8249:48;;;;8302:16;8339:3;-1:-1:-1;;;;;8329:14:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;8329:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;8329::0;87:42:-1;143:17;;-1:-1;8329:14:0;;8323:20;;8348:33;8361:9;8372:3;8377;8348:12;:33::i;:::-;8393:3;8147:254;-1:-1:-1;;;;8147:254:0:o;17783:799::-;17899:4;17910:8;18098:24;18125:35;18141:18;18125:15;:35::i;:::-;18098:62;;18165:23;18201:11;:18;-1:-1:-1;;;;;18191:29:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;18191:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;18191:29:0;87:42:-1;143:17;;-1:-1;18191:29:0;-1:-1:-1;18165:55:0;-1:-1:-1;18323:7:0;18312:132;18342:11;:18;18334:7;:26;18332:1;:28;18312:132;;;18373:15;18391:4;18396:1;18391:7;;;;;;;;;;;;;;;;18373:25;;18428:10;18404;18417:7;18415:1;:9;18404:21;;;;;;;;;;;:34;-1:-1:-1;;;;;18404:34:0;;;;;;;;-1:-1:-1;;18362:3:0;;18312:132;;;;18489:10;18479:21;;;;;;18463:11;18453:22;;;;;;:47;18450:113;;;18514:11;:18;18508:24;;18450:113;;;18556:1;18550:7;;18450:113;-1:-1:-1;18574:3:0;;17783:799;-1:-1:-1;;;;;17783:799:0:o;9580:371::-;9637:4;9656:12;9663:4;9656:6;:12::i;:::-;9648:45;;;;-1:-1:-1;;;9648:45:0;;;;;;;;;9699:17;9718:11;9733:13;9741:4;9733:7;:13::i;:::-;9698:48;;;;9766:2;9759:3;:9;;9751:42;;;;-1:-1:-1;;;9751:42:0;;;;;;;;;9806:8;9798:41;;;;-1:-1:-1;;;9798:41:0;;;;;;;;;9885:16;;9916:2;9912:12;;;;9907:3;9903:22;9881:45;;;9580:371;-1:-1:-1;;9580:371:0:o;5663:265::-;5720:4;5735;:19;;;5758:1;5735:24;5731:46;;;-1:-1:-1;5772:5:0;5765:12;;5731:46;-1:-1:-1;5796:19:0;5879:13;5895:4;5782:11;5871:22;;;;5868:32;5861:40;;5663:265::o;6834:399::-;6890:4;6906:12;6913:4;6906:6;:12::i;:::-;6901:31;;-1:-1:-1;6931:1:0;6924:8;;6901:31;6963:19;;7016:13;;6937:7;7008:22;;;;6963:19;7059:20;6963:4;7059:14;:20::i;:::-;7105:19;;;;7050:29;;;;-1:-1:-1;7096:28:0;;-1:-1:-1;;7096:32:0;7084:9;7147:66;7160:4;7153:3;:11;7147:66;;7179:16;7191:3;7179:11;:16::i;:::-;7172:23;;;;7201:6;;7147:66;;7340:284;7399:15;;:::i;:::-;7429:12;7436:4;7429:6;:12::i;:::-;7421:47;;;;-1:-1:-1;;;7421:47:0;;;;;;;;;7473:8;7506:20;7521:4;7506:14;:20::i;:::-;7484:19;;:42;;-1:-1:-1;7531:18:0;;:::i;:::-;7554:22;;;7581:18;;;:24;-1:-1:-1;7554:22:0;7340:284::o;4160:194::-;4222:4;4233:20;;:::i;:::-;-1:-1:-1;;4256:17:0;;4330:19;;;;;4308;;4285:20;;;4308:41;;-1:-1:-1;;4160:194:0:o;3630:332::-;3689:19;;:::i;:::-;3723:13;3731:4;3723:7;:13::i;:::-;3715:44;;;;-1:-1:-1;;;3715:44:0;;;;;;;;;3778:20;;;;3764:11;3824:16;3778:20;3824:11;:16::i;:::-;3845:28;;;3878:22;;;;:35;;;3941:16;;3918:20;;;;:39;;;;3845:7;3630:332;-1:-1:-1;3630:332:0:o;19307:159::-;19385:4;19410:1;19408;:3;:6;:52;;19456:4;19446:3;19452:1;19450;:3;19446:8;;;;;;;;;;;;;;19440:20;;;;;;19408:52;;;19433:4;19423:3;19429:1;19427;:3;19423:8;;;;;;;;;;;;;;19417:20;;;;;;19408:52;19403:58;;;19307:159;-1:-1:-1;;;19307:159:0:o;14056:642::-;14345:2;14340;14332:6;14328:15;14324:24;14374:11;14438:2;14420:16;14416:25;14461:1;14446:172;14471:5;14468:1;14465:12;14446:172;;;14529:2;14522:10;;14584:26;;;14578:33;14545:31;;;14538:74;14492:1;14485:9;14446:172;;;14450:14;;;;14687:1;14666:16;14660:23;14656:2;14652:32;14634:16;14630:55;14623:66;14305:389;;;:::o;6041:257::-;6098:4;6113;:19;;;6136:1;6113:24;6109:46;;;-1:-1:-1;6150:5:0;6143:12;;6109:46;-1:-1:-1;6174:19:0;6250:13;6266:4;6160:11;6242:22;;;;6239:32;;6041:257::o;13360:620::-;13417:11;13430:8;13453:12;13460:4;13453:6;:12::i;:::-;13445:46;;;;-1:-1:-1;;;13445:46:0;;;;;;;;;13521:19;;13574:12;;13496:7;13566:21;;3067:4;13600:21;;13596:92;;;13638:5;-1:-1:-1;13655:1:0;;-1:-1:-1;13662:20:0;;-1:-1:-1;13662:20:0;13596:92;3107:4;13696:2;:20;13692:259;;;13752:1;13730:4;:19;;;:23;13724:29;;13768:5;13776:1;13768:9;13759:18;;13692:259;;;13884:19;;;;13929:12;;;-1:-1:-1;;13929:16:0;;-1:-1:-1;13884:30:0;;;;;;-1:-1:-1;;;13360:620:0;;;;:::o;11978:464::-;12042:4;12056;:19;;;12079:1;12056:24;12053:41;;;-1:-1:-1;12093:1:0;12086:8;;12053:41;12125:19;;12178:13;;12099:7;12170:22;;3067:4;12204:21;;12201:38;;;12238:1;12231:8;;;;;;12201:38;3107:4;12247:2;:20;:72;;;;3148:4;12272:2;:22;;:46;;;;;3188:4;12298:2;:20;12272:46;12244:89;;;12332:1;12325:8;;;;;;12244:89;3148:4;12341:2;:21;12338:62;;;-1:-1:-1;;;12375:25:0;;-1:-1:-1;12368:32:0;;12338:62;-1:-1:-1;;;12412:25:0;;11978:464;-1:-1:-1;;11978:464:0:o;12484:823::-;12596:13;;12540:8;;12588:22;;3067:4;12623:21;;12619:684;;;12656:1;12650:7;;12619:684;;;3107:4;12671:2;:20;12667:636;;;-1:-1:-1;;12703:25:0;;;-1:-1:-1;12667:636:0;;;3148:4;12742:2;:21;12738:565;;;12887:1;12875:14;;12869:21;12807:4;12905:2;12901:13;;;;12896:3;12892:23;12865:51;;12951:15;;-1:-1:-1;;12944:23:0;;-1:-1:-1;12780:209:0;;;3188:4;13007:2;:20;13003:300;;;-1:-1:-1;;13039:25:0;;;-1:-1:-1;13003:300:0;;;13196:1;13184:14;;13178:21;13116:4;13214:2;13210:13;;;;13205:3;13201:23;13174:51;;13260:15;;-1:-1:-1;;13253:23:0;;-1:-1:-1;13089:209:0;12484:823;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;552:440::-;;653:3;646:4;638:6;634:17;630:27;620:2;;-1:-1;;661:12;620:2;708:6;695:20;-1:-1;;;;;28516:6;28513:30;28510:2;;;-1:-1;;28546:12;28510:2;730:64;28619:9;28600:17;;-1:-1;;28596:33;28687:4;28677:15;730:64;;;721:73;;814:6;807:5;800:21;918:3;28687:4;909:6;842;900:16;;897:25;894:2;;;935:1;;925:12;894:2;30488:6;28687:4;842:6;838:17;28687:4;876:5;872:16;30465:30;30544:1;30526:16;;;28687:4;30526:16;30519:27;876:5;613:379;-1:-1;;613:379;1218:1207;;1334:4;1322:9;1317:3;1313:19;1309:30;1306:2;;;-1:-1;;1342:12;1306:2;1370:20;1334:4;1370:20;;;1361:29;;1454:17;1441:31;-1:-1;;;;;1492:18;1484:6;1481:30;1478:2;;;1469:1;;1514:12;1478:2;1559:58;1613:3;1604:6;1593:9;1589:22;1559:58;;;1541:16;1534:84;1723:2;1712:9;1708:18;1695:32;1681:46;;1492:18;1739:6;1736:30;1733:2;;;1469:1;;1769:12;1733:2;1814:58;1868:3;1859:6;1848:9;1844:22;1814:58;;;1723:2;1800:5;1796:16;1789:84;1990:2;1979:9;1975:18;1962:32;1948:46;;1492:18;2006:6;2003:30;2000:2;;;1469:1;;2036:12;2000:2;2081:58;2135:3;2126:6;2115:9;2111:22;2081:58;;;1990:2;2067:5;2063:16;2056:84;2254:2;2243:9;2239:18;2226:32;2212:46;;1492:18;2270:6;2267:30;2264:2;;;1469:1;;2300:12;2264:2;;2345:58;2399:3;2390:6;2379:9;2375:22;2345:58;;;2254:2;2331:5;2327:16;2320:84;;1300:1125;;;;;2990:126;3055:20;;29759:4;29748:16;;31902:33;;31892:2;;31949:1;;31939:12;3123:263;;3238:2;3226:9;3217:7;3213:23;3209:32;3206:2;;;-1:-1;;3244:12;3206:2;226:6;220:13;238:33;265:5;238:33;;3393:506;;;3541:2;3529:9;3520:7;3516:23;3512:32;3509:2;;;-1:-1;;3547:12;3509:2;85:6;72:20;97:33;124:5;97:33;;;3599:63;-1:-1;3727:2;3712:18;;3699:32;-1:-1;;;;;3740:30;;3737:2;;;-1:-1;;3773:12;3737:2;3803:80;3875:7;3866:6;3855:9;3851:22;3803:80;;;3793:90;;;3503:396;;;;;;3906:631;;;;4071:2;4059:9;4050:7;4046:23;4042:32;4039:2;;;-1:-1;;4077:12;4039:2;85:6;72:20;97:33;124:5;97:33;;;4129:63;-1:-1;4229:2;4268:22;;2640:20;;-1:-1;4365:2;4350:18;;4337:32;-1:-1;;;;;4378:30;;4375:2;;;-1:-1;;4411:12;4375:2;4441:80;4513:7;4504:6;4493:9;4489:22;4441:80;;;4431:90;;;4033:504;;;;;;4544:919;;;;;;4761:3;4749:9;4740:7;4736:23;4732:33;4729:2;;;-1:-1;;4768:12;4729:2;1102:6;1089:20;1114:55;1163:5;1114:55;;;4820:85;-1:-1;4942:2;4981:22;;72:20;97:33;72:20;97:33;;;4950:63;-1:-1;5068:51;5111:7;5050:2;5087:22;;5068:51;;;5058:61;;5174:51;5217:7;5156:2;5197:9;5193:22;5174:51;;;5164:61;;5290:3;5279:9;5275:19;5262:33;-1:-1;;;;;5307:6;5304:30;5301:2;;;-1:-1;;5337:12;5301:2;5367:80;5439:7;5430:6;5419:9;5415:22;5367:80;;;5357:90;;;4723:740;;;;;;;;;5470:404;;;5610:2;5598:9;5589:7;5585:23;5581:32;5578:2;;;-1:-1;;5616:12;5578:2;1102:6;1089:20;1114:55;1163:5;1114:55;;;5668:85;-1:-1;5790:2;5826:22;;347:20;372:30;347:20;372:30;;;5798:60;;;;5572:302;;;;;;5881:913;;;;;;6095:3;6083:9;6074:7;6070:23;6066:33;6063:2;;;-1:-1;;6102:12;6063:2;1102:6;1089:20;1114:55;1163:5;1114:55;;;6154:85;-1:-1;6276:2;6312:22;;347:20;372:30;347:20;372:30;;6801:919;;;;;;7018:3;7006:9;6997:7;6993:23;6989:33;6986:2;;;-1:-1;;7025:12;6986:2;1102:6;1089:20;1114:55;1163:5;1114:55;;;7077:85;-1:-1;7217:51;7260:7;7199:2;7236:22;;7217:51;;;7207:61;;7323:51;7366:7;7305:2;7346:9;7342:22;7323:51;;;7313:61;;7411:2;7454:9;7450:22;481:20;7419:63;;7547:3;7536:9;7532:19;7519:33;-1:-1;;;;;7564:6;7561:30;7558:2;;;-1:-1;;7594:12;7727:533;;;;7875:2;7863:9;7854:7;7850:23;7846:32;7843:2;;;-1:-1;;7881:12;7843:2;2516:6;2510:13;2528:33;2555:5;2528:33;;;8044:2;8094:22;;2510:13;7933:74;;-1:-1;2528:33;2510:13;2528:33;;;8163:2;8212:22;;2928:13;8052:74;;-1:-1;29665:10;29654:22;;31781:34;;31771:2;;-1:-1;;31819:12;31771:2;8171:73;;;;7837:423;;;;;;8267:263;;8382:2;8370:9;8361:7;8357:23;8353:32;8350:2;;;-1:-1;;8388:12;8350:2;-1:-1;2788:13;;8344:186;-1:-1;8344:186;16181:253;30913:2;30909:14;;;;-1:-1;;30909:14;8746:58;;16406:2;16397:12;;16297:137;16441:253;8887:37;;;16666:2;16657:12;;16557:137;16701:222;-1:-1;;;;;29448:54;;;;8608:37;;16828:2;16813:18;;16799:124;16930:333;-1:-1;;;;;29448:54;;;8608:37;;29448:54;;17249:2;17234:18;;8608:37;17085:2;17070:18;;17056:207;17499:444;8887:37;;;17846:2;17831:18;;8887:37;;;;17929:2;17914:18;;8887:37;17682:2;17667:18;;17653:290;18504:416;18704:2;18718:47;;;9523:2;18689:18;;;28813:19;-1:-1;;;28853:14;;;9539:43;9601:12;;;18675:245;18927:416;19127:2;19141:47;;;9852:2;19112:18;;;28813:19;-1:-1;;;28853:14;;;9868:45;9932:12;;;19098:245;19350:416;19550:2;19564:47;;;10183:2;19535:18;;;28813:19;-1:-1;;;28853:14;;;10199:41;10259:12;;;19521:245;19773:416;19973:2;19987:47;;;10510:2;19958:18;;;28813:19;-1:-1;;;28853:14;;;10526:45;10590:12;;;19944:245;20196:416;20396:2;20410:47;;;10841:2;20381:18;;;28813:19;10877:29;28853:14;;;10857:50;10926:12;;;20367:245;20619:416;20819:2;20833:47;;;11177:2;20804:18;;;28813:19;11213:27;28853:14;;;11193:48;11260:12;;;20790:245;21042:416;21242:2;21256:47;;;11511:2;21227:18;;;28813:19;-1:-1;;;28853:14;;;11527:45;11591:12;;;21213:245;21465:416;21665:2;21679:47;;;11842:2;21650:18;;;28813:19;-1:-1;;;28853:14;;;11858:38;11915:12;;;21636:245;21888:416;22088:2;22102:47;;;12166:2;22073:18;;;28813:19;12202:34;28853:14;;;12182:55;-1:-1;;;12257:12;;;12250:25;12294:12;;;22059:245;22311:416;22511:2;22525:47;;;12545:2;22496:18;;;28813:19;12581:25;28853:14;;;12561:46;12626:12;;;22482:245;22734:416;22934:2;22948:47;;;12877:2;22919:18;;;28813:19;-1:-1;;;28853:14;;;12893:44;12956:12;;;22905:245;23157:416;23357:2;23371:47;;;13207:2;23342:18;;;28813:19;-1:-1;;;28853:14;;;13223:43;13285:12;;;23328:245;23580:416;23780:2;23794:47;;;13536:2;23765:18;;;28813:19;-1:-1;;;28853:14;;;13552:43;13614:12;;;23751:245;24003:416;24203:2;24217:47;;;13865:2;24188:18;;;28813:19;-1:-1;;;28853:14;;;13881:44;13944:12;;;24174:245;24426:416;24626:2;24640:47;;;14195:2;24611:18;;;28813:19;-1:-1;;;28853:14;;;14211:43;14273:12;;;24597:245;24849:416;25049:2;25063:47;;;14524:2;25034:18;;;28813:19;14560:34;28853:14;;;14540:55;-1:-1;;;14615:12;;;14608:34;14661:12;;;25020:245;25272:416;25472:2;25486:47;;;14912:2;25457:18;;;28813:19;-1:-1;;;28853:14;;;14928:36;14983:12;;;25443:245;26118:416;26318:2;26332:47;;;15562:2;26303:18;;;28813:19;-1:-1;;;28853:14;;;15578:45;15642:12;;;26289:245;26770:333;8887:37;;;27089:2;27074:18;;8887:37;26925:2;26910:18;;26896:207;27110:780;8887:37;;;27542:2;27527:18;;8887:37;;;;27625:2;27610:18;;8887:37;;;;-1:-1;;;;;29332:42;;;27708:2;27693:18;;15739:37;29332:42;27791:3;27776:19;;15739:37;27875:3;27860:19;;8887:37;27377:3;27362:19;;27348:542;27897:214;29759:4;29748:16;;;;16134:35;;28020:2;28005:18;;27991:120;28118:256;28180:2;28174:9;28206:17;;;-1:-1;;;;;28266:34;;28302:22;;;28263:62;28260:2;;;28338:1;;28328:12;28260:2;28180;28347:22;28158:216;;-1:-1;28158:216;30941:117;-1:-1;;;;;29448:54;;31000:35;;30990:2;;31049:1;;31039:12;30990:2;30984:74;;31065:111;31146:5;29045:13;29038:21;31124:5;31121:32;31111:2;;31167:1;;31157:12;31475:117;-1:-1;;;;;31562:5;29332:42;31537:5;31534:35;31524:2;;31583:1;;31573:12

Swarm Source

ipfs://3fd9ccd55351f7378c20686406cb078e73ae79febe7e8011fc56961496dc1a5f

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.