Address Details
contract
0x4abb96Ce263E7cc70cDfd657A6D90d6BDa3dC604
- Contract Name
- SortedOracles
- Creator
- 0x0cc59e–f1502d at 0xd66d9a–e80b0b
- Balance
- 0 CELO
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- Fetching transactions...
- Transfers
- Fetching transfers...
- Gas Used
- Fetching gas used...
- Last Balance Update
- 2159432
- Contract name:
- SortedOracles
- Optimization enabled
- false
- Compiler version
- v0.5.8+commit.23d335f2
- Verified at
- 2020-08-11T19:20:11.909101Z
Contract source code
pragma solidity ^0.5.3; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } contract Context { constructor () internal { } function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; return msg.data; } } contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } function owner() public view returns (address) { return _owner; } modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } function isOwner() public view returns (bool) { return _msgSender() == _owner; } function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } interface ISortedOracles { function addOracle(address, address) external; function removeOracle(address, address, uint256) external; function report(address, uint256, address, address) external; function removeExpiredReports(address, uint256) external; function isOldestReportExpired(address token) external view returns (bool, address); function numRates(address) external view returns (uint256); function medianRate(address) external view returns (uint256, uint256); function numTimestamps(address) external view returns (uint256); function medianTimestamp(address) external view returns (uint256); } library FixidityLib { struct Fraction { uint256 value; } function digits() internal pure returns (uint8) { return 24; } uint256 private constant FIXED1_UINT = 1000000000000000000000000; function fixed1() internal pure returns (Fraction memory) { return Fraction(FIXED1_UINT); } function wrap(uint256 x) internal pure returns (Fraction memory) { return Fraction(x); } function unwrap(Fraction memory x) internal pure returns (uint256) { return x.value; } function mulPrecision() internal pure returns (uint256) { return 1000000000000; } function maxNewFixed() internal pure returns (uint256) { return 115792089237316195423570985008687907853269984665640564; } function newFixed(uint256 x) internal pure returns (Fraction memory) { require(x <= maxNewFixed(), "can't create fixidity number larger than maxNewFixed()"); return Fraction(x * FIXED1_UINT); } function fromFixed(Fraction memory x) internal pure returns (uint256) { return x.value / FIXED1_UINT; } function newFixedFraction(uint256 numerator, uint256 denominator) internal pure returns (Fraction memory) { Fraction memory convertedNumerator = newFixed(numerator); Fraction memory convertedDenominator = newFixed(denominator); return divide(convertedNumerator, convertedDenominator); } function integer(Fraction memory x) internal pure returns (Fraction memory) { return Fraction((x.value / FIXED1_UINT) * FIXED1_UINT); } function fractional(Fraction memory x) internal pure returns (Fraction memory) { return Fraction(x.value - (x.value / FIXED1_UINT) * FIXED1_UINT); } function add(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) { uint256 z = x.value + y.value; require(z >= x.value, "add overflow detected"); return Fraction(z); } function subtract(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) { require(x.value >= y.value, "substraction underflow detected"); return Fraction(x.value - y.value); } function multiply(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) { if (x.value == 0 || y.value == 0) return Fraction(0); if (y.value == FIXED1_UINT) return x; if (x.value == FIXED1_UINT) return y; uint256 x1 = integer(x).value / FIXED1_UINT; uint256 x2 = fractional(x).value; uint256 y1 = integer(y).value / FIXED1_UINT; uint256 y2 = fractional(y).value; uint256 x1y1 = x1 * y1; if (x1 != 0) require(x1y1 / x1 == y1, "overflow x1y1 detected"); uint256 fixed_x1y1 = x1y1 * FIXED1_UINT; if (x1y1 != 0) require(fixed_x1y1 / x1y1 == FIXED1_UINT, "overflow x1y1 * fixed1 detected"); x1y1 = fixed_x1y1; uint256 x2y1 = x2 * y1; if (x2 != 0) require(x2y1 / x2 == y1, "overflow x2y1 detected"); uint256 x1y2 = x1 * y2; if (x1 != 0) require(x1y2 / x1 == y2, "overflow x1y2 detected"); x2 = x2 / mulPrecision(); y2 = y2 / mulPrecision(); uint256 x2y2 = x2 * y2; if (x2 != 0) require(x2y2 / x2 == y2, "overflow x2y2 detected"); Fraction memory result = Fraction(x1y1); result = add(result, Fraction(x2y1)); result = add(result, Fraction(x1y2)); result = add(result, Fraction(x2y2)); return result; } function reciprocal(Fraction memory x) internal pure returns (Fraction memory) { require(x.value != 0, "can't call reciprocal(0)"); return Fraction((FIXED1_UINT * FIXED1_UINT) / x.value); } function divide(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) { require(y.value != 0, "can't divide by 0"); uint256 X = x.value * FIXED1_UINT; require(X / FIXED1_UINT == x.value, "overflow at divide"); return Fraction(X / y.value); } function gt(Fraction memory x, Fraction memory y) internal pure returns (bool) { return x.value > y.value; } function gte(Fraction memory x, Fraction memory y) internal pure returns (bool) { return x.value >= y.value; } function lt(Fraction memory x, Fraction memory y) internal pure returns (bool) { return x.value < y.value; } function lte(Fraction memory x, Fraction memory y) internal pure returns (bool) { return x.value <= y.value; } function equals(Fraction memory x, Fraction memory y) internal pure returns (bool) { return x.value == y.value; } function isProperFraction(Fraction memory x) internal pure returns (bool) { return lte(x, fixed1()); } } contract Initializable { bool public initialized; modifier initializer() { require(!initialized, "contract already initialized"); initialized = true; _; } } library LinkedList { using SafeMath for uint256; struct Element { bytes32 previousKey; bytes32 nextKey; bool exists; } struct List { bytes32 head; bytes32 tail; uint256 numElements; mapping(bytes32 => Element) elements; } function insert(List storage list, bytes32 key, bytes32 previousKey, bytes32 nextKey) public { require(key != bytes32(0), "Key must be defined"); require(!contains(list, key), "Can't insert an existing element"); require( previousKey != key && nextKey != key, "Key cannot be the same as previousKey or nextKey" ); Element storage element = list.elements[key]; element.exists = true; if (list.numElements == 0) { list.tail = key; list.head = key; } else { require( previousKey != bytes32(0) || nextKey != bytes32(0), "Either previousKey or nextKey must be defined" ); element.previousKey = previousKey; element.nextKey = nextKey; if (previousKey != bytes32(0)) { require( contains(list, previousKey), "If previousKey is defined, it must exist in the list" ); Element storage previousElement = list.elements[previousKey]; require(previousElement.nextKey == nextKey, "previousKey must be adjacent to nextKey"); previousElement.nextKey = key; } else { list.tail = key; } if (nextKey != bytes32(0)) { require(contains(list, nextKey), "If nextKey is defined, it must exist in the list"); Element storage nextElement = list.elements[nextKey]; require(nextElement.previousKey == previousKey, "previousKey must be adjacent to nextKey"); nextElement.previousKey = key; } else { list.head = key; } } list.numElements = list.numElements.add(1); } function push(List storage list, bytes32 key) public { insert(list, key, bytes32(0), list.tail); } function remove(List storage list, bytes32 key) public { Element storage element = list.elements[key]; require(key != bytes32(0) && contains(list, key), "key not in list"); if (element.previousKey != bytes32(0)) { Element storage previousElement = list.elements[element.previousKey]; previousElement.nextKey = element.nextKey; } else { list.tail = element.nextKey; } if (element.nextKey != bytes32(0)) { Element storage nextElement = list.elements[element.nextKey]; nextElement.previousKey = element.previousKey; } else { list.head = element.previousKey; } delete list.elements[key]; list.numElements = list.numElements.sub(1); } function update(List storage list, bytes32 key, bytes32 previousKey, bytes32 nextKey) public { require( key != bytes32(0) && key != previousKey && key != nextKey && contains(list, key), "key on in list" ); remove(list, key); insert(list, key, previousKey, nextKey); } function contains(List storage list, bytes32 key) public view returns (bool) { return list.elements[key].exists; } function headN(List storage list, uint256 n) public view returns (bytes32[] memory) { require(n <= list.numElements, "not enough elements"); bytes32[] memory keys = new bytes32[](n); bytes32 key = list.head; for (uint256 i = 0; i < n; i = i.add(1)) { keys[i] = key; key = list.elements[key].previousKey; } return keys; } function getKeys(List storage list) public view returns (bytes32[] memory) { return headN(list, list.numElements); } } library SortedLinkedList { using SafeMath for uint256; using LinkedList for LinkedList.List; struct List { LinkedList.List list; mapping(bytes32 => uint256) values; } function insert( List storage list, bytes32 key, uint256 value, bytes32 lesserKey, bytes32 greaterKey ) public { require( key != bytes32(0) && key != lesserKey && key != greaterKey && !contains(list, key), "invalid key" ); require( (lesserKey != bytes32(0) || greaterKey != bytes32(0)) || list.list.numElements == 0, "greater and lesser key zero" ); require(contains(list, lesserKey) || lesserKey == bytes32(0), "invalid lesser key"); require(contains(list, greaterKey) || greaterKey == bytes32(0), "invalid greater key"); (lesserKey, greaterKey) = getLesserAndGreater(list, value, lesserKey, greaterKey); list.list.insert(key, lesserKey, greaterKey); list.values[key] = value; } function remove(List storage list, bytes32 key) public { list.list.remove(key); list.values[key] = 0; } function update( List storage list, bytes32 key, uint256 value, bytes32 lesserKey, bytes32 greaterKey ) public { remove(list, key); insert(list, key, value, lesserKey, greaterKey); } function push(List storage list, bytes32 key) public { insert(list, key, 0, bytes32(0), list.list.tail); } function popN(List storage list, uint256 n) public returns (bytes32[] memory) { require(n <= list.list.numElements, "not enough elements"); bytes32[] memory keys = new bytes32[](n); for (uint256 i = 0; i < n; i = i.add(1)) { bytes32 key = list.list.head; keys[i] = key; remove(list, key); } return keys; } function contains(List storage list, bytes32 key) public view returns (bool) { return list.list.contains(key); } function getValue(List storage list, bytes32 key) public view returns (uint256) { return list.values[key]; } function getElements(List storage list) public view returns (bytes32[] memory, uint256[] memory) { bytes32[] memory keys = getKeys(list); uint256[] memory values = new uint256[](keys.length); for (uint256 i = 0; i < keys.length; i = i.add(1)) { values[i] = list.values[keys[i]]; } return (keys, values); } function getKeys(List storage list) public view returns (bytes32[] memory) { return list.list.getKeys(); } function headN(List storage list, uint256 n) public view returns (bytes32[] memory) { return list.list.headN(n); } function getLesserAndGreater( List storage list, uint256 value, bytes32 lesserKey, bytes32 greaterKey ) private view returns (bytes32, bytes32) { if (lesserKey == bytes32(0) && isValueBetween(list, value, lesserKey, list.list.tail)) { return (lesserKey, list.list.tail); } else if ( greaterKey == bytes32(0) && isValueBetween(list, value, list.list.head, greaterKey) ) { return (list.list.head, greaterKey); } else if ( lesserKey != bytes32(0) && isValueBetween(list, value, lesserKey, list.list.elements[lesserKey].nextKey) ) { return (lesserKey, list.list.elements[lesserKey].nextKey); } else if ( greaterKey != bytes32(0) && isValueBetween(list, value, list.list.elements[greaterKey].previousKey, greaterKey) ) { return (list.list.elements[greaterKey].previousKey, greaterKey); } else { require(false, "get lesser and greater failure"); } } function isValueBetween(List storage list, uint256 value, bytes32 lesserKey, bytes32 greaterKey) private view returns (bool) { bool isLesser = lesserKey == bytes32(0) || list.values[lesserKey] <= value; bool isGreater = greaterKey == bytes32(0) || list.values[greaterKey] >= value; return isLesser && isGreater; } } library SortedLinkedListWithMedian { using SafeMath for uint256; using SortedLinkedList for SortedLinkedList.List; enum MedianAction { None, Lesser, Greater } enum MedianRelation { Undefined, Lesser, Greater, Equal } struct List { SortedLinkedList.List list; bytes32 median; mapping(bytes32 => MedianRelation) relation; } function insert( List storage list, bytes32 key, uint256 value, bytes32 lesserKey, bytes32 greaterKey ) public { list.list.insert(key, value, lesserKey, greaterKey); LinkedList.Element storage element = list.list.list.elements[key]; MedianAction action = MedianAction.None; if (list.list.list.numElements == 1) { list.median = key; list.relation[key] = MedianRelation.Equal; } else if (list.list.list.numElements % 2 == 1) { if ( element.previousKey == bytes32(0) || list.relation[element.previousKey] == MedianRelation.Lesser ) { action = MedianAction.Lesser; list.relation[key] = MedianRelation.Lesser; } else { list.relation[key] = MedianRelation.Greater; } } else { if ( element.nextKey == bytes32(0) || list.relation[element.nextKey] == MedianRelation.Greater ) { action = MedianAction.Greater; list.relation[key] = MedianRelation.Greater; } else { list.relation[key] = MedianRelation.Lesser; } } updateMedian(list, action); } function remove(List storage list, bytes32 key) public { MedianAction action = MedianAction.None; if (list.list.list.numElements == 0) { list.median = bytes32(0); } else if (list.list.list.numElements % 2 == 0) { if ( list.relation[key] == MedianRelation.Greater || list.relation[key] == MedianRelation.Equal ) { action = MedianAction.Lesser; } } else { if ( list.relation[key] == MedianRelation.Lesser || list.relation[key] == MedianRelation.Equal ) { action = MedianAction.Greater; } } updateMedian(list, action); list.list.remove(key); } function update( List storage list, bytes32 key, uint256 value, bytes32 lesserKey, bytes32 greaterKey ) public { remove(list, key); insert(list, key, value, lesserKey, greaterKey); } function push(List storage list, bytes32 key) public { insert(list, key, 0, bytes32(0), list.list.list.tail); } function popN(List storage list, uint256 n) public returns (bytes32[] memory) { require(n <= list.list.list.numElements, "not enough elements"); bytes32[] memory keys = new bytes32[](n); for (uint256 i = 0; i < n; i = i.add(1)) { bytes32 key = list.list.list.head; keys[i] = key; remove(list, key); } return keys; } function contains(List storage list, bytes32 key) public view returns (bool) { return list.list.contains(key); } function getValue(List storage list, bytes32 key) public view returns (uint256) { return list.list.values[key]; } function getMedianValue(List storage list) public view returns (uint256) { return getValue(list, list.median); } function getHead(List storage list) external view returns (bytes32) { return list.list.list.head; } function getMedian(List storage list) external view returns (bytes32) { return list.median; } function getTail(List storage list) external view returns (bytes32) { return list.list.list.tail; } function getNumElements(List storage list) external view returns (uint256) { return list.list.list.numElements; } function getElements(List storage list) public view returns (bytes32[] memory, uint256[] memory, MedianRelation[] memory) { bytes32[] memory keys = getKeys(list); uint256[] memory values = new uint256[](keys.length); MedianRelation[] memory relations = new MedianRelation[](keys.length); for (uint256 i = 0; i < keys.length; i = i.add(1)) { values[i] = list.list.values[keys[i]]; relations[i] = list.relation[keys[i]]; } return (keys, values, relations); } function getKeys(List storage list) public view returns (bytes32[] memory) { return list.list.getKeys(); } function updateMedian(List storage list, MedianAction action) private { LinkedList.Element storage previousMedian = list.list.list.elements[list.median]; if (action == MedianAction.Lesser) { list.relation[list.median] = MedianRelation.Greater; list.median = previousMedian.previousKey; } else if (action == MedianAction.Greater) { list.relation[list.median] = MedianRelation.Lesser; list.median = previousMedian.nextKey; } list.relation[list.median] = MedianRelation.Equal; } } library AddressSortedLinkedListWithMedian { using SafeMath for uint256; using SortedLinkedListWithMedian for SortedLinkedListWithMedian.List; function toBytes(address a) public pure returns (bytes32) { return bytes32(uint256(a) << 96); } function toAddress(bytes32 b) public pure returns (address) { return address(uint256(b) >> 96); } function insert( SortedLinkedListWithMedian.List storage list, address key, uint256 value, address lesserKey, address greaterKey ) public { list.insert(toBytes(key), value, toBytes(lesserKey), toBytes(greaterKey)); } function remove(SortedLinkedListWithMedian.List storage list, address key) public { list.remove(toBytes(key)); } function update( SortedLinkedListWithMedian.List storage list, address key, uint256 value, address lesserKey, address greaterKey ) public { list.update(toBytes(key), value, toBytes(lesserKey), toBytes(greaterKey)); } function contains(SortedLinkedListWithMedian.List storage list, address key) public view returns (bool) { return list.contains(toBytes(key)); } function getValue(SortedLinkedListWithMedian.List storage list, address key) public view returns (uint256) { return list.getValue(toBytes(key)); } function getMedianValue(SortedLinkedListWithMedian.List storage list) public view returns (uint256) { return list.getValue(list.median); } function getHead(SortedLinkedListWithMedian.List storage list) external view returns (address) { return toAddress(list.getHead()); } function getMedian(SortedLinkedListWithMedian.List storage list) external view returns (address) { return toAddress(list.getMedian()); } function getTail(SortedLinkedListWithMedian.List storage list) external view returns (address) { return toAddress(list.getTail()); } function getNumElements(SortedLinkedListWithMedian.List storage list) external view returns (uint256) { return list.getNumElements(); } function getElements(SortedLinkedListWithMedian.List storage list) public view returns (address[] memory, uint256[] memory, SortedLinkedListWithMedian.MedianRelation[] memory) { bytes32[] memory byteKeys = list.getKeys(); address[] memory keys = new address[](byteKeys.length); uint256[] memory values = new uint256[](byteKeys.length); SortedLinkedListWithMedian.MedianRelation[] memory relations = new SortedLinkedListWithMedian.MedianRelation[](keys.length); for (uint256 i = 0; i < byteKeys.length; i = i.add(1)) { keys[i] = toAddress(byteKeys[i]); values[i] = list.getValue(byteKeys[i]); relations[i] = list.relation[byteKeys[i]]; } return (keys, values, relations); } } contract SortedOracles is ISortedOracles, Ownable, Initializable { using SafeMath for uint256; using AddressSortedLinkedListWithMedian for SortedLinkedListWithMedian.List; using FixidityLib for FixidityLib.Fraction; uint256 private constant FIXED1_UINT = 1000000000000000000000000; mapping(address => SortedLinkedListWithMedian.List) private rates; mapping(address => SortedLinkedListWithMedian.List) private timestamps; mapping(address => mapping(address => bool)) public isOracle; mapping(address => address[]) public oracles; uint256 public reportExpirySeconds; event OracleAdded(address indexed token, address indexed oracleAddress); event OracleRemoved(address indexed token, address indexed oracleAddress); event OracleReported( address indexed token, address indexed oracle, uint256 timestamp, uint256 value ); event OracleReportRemoved(address indexed token, address indexed oracle); event MedianUpdated(address indexed token, uint256 value); event ReportExpirySet(uint256 reportExpiry); modifier onlyOracle(address token) { require(isOracle[token][msg.sender], "sender was not an oracle for token addr"); _; } function initialize(uint256 _reportExpirySeconds) external initializer { _transferOwnership(msg.sender); setReportExpiry(_reportExpirySeconds); } function setReportExpiry(uint256 _reportExpirySeconds) public onlyOwner { require(_reportExpirySeconds > 0, "report expiry seconds must be > 0"); require(_reportExpirySeconds != reportExpirySeconds, "reportExpirySeconds hasn't changed"); reportExpirySeconds = _reportExpirySeconds; emit ReportExpirySet(_reportExpirySeconds); } function addOracle(address token, address oracleAddress) external onlyOwner { require( token != address(0) && oracleAddress != address(0) && !isOracle[token][oracleAddress], "token addr was null or oracle addr was null or oracle addr is not an oracle for token addr" ); isOracle[token][oracleAddress] = true; oracles[token].push(oracleAddress); emit OracleAdded(token, oracleAddress); } function removeOracle(address token, address oracleAddress, uint256 index) external onlyOwner { require( token != address(0) && oracleAddress != address(0) && oracles[token].length > index && oracles[token][index] == oracleAddress, "token addr null or oracle addr null or index of token oracle not mapped to oracle addr" ); isOracle[token][oracleAddress] = false; oracles[token][index] = oracles[token][oracles[token].length.sub(1)]; oracles[token].length = oracles[token].length.sub(1); if (reportExists(token, oracleAddress)) { removeReport(token, oracleAddress); } emit OracleRemoved(token, oracleAddress); } function removeExpiredReports(address token, uint256 n) external { require( token != address(0) && n < timestamps[token].getNumElements(), "token addr null or trying to remove too many reports" ); for (uint256 i = 0; i < n; i = i.add(1)) { (bool isExpired, address oldestAddress) = isOldestReportExpired(token); if (isExpired) { removeReport(token, oldestAddress); } else { break; } } } function isOldestReportExpired(address token) public view returns (bool, address) { require(token != address(0)); address oldest = timestamps[token].getTail(); uint256 timestamp = timestamps[token].getValue(oldest); if (now.sub(timestamp) >= reportExpirySeconds) { return (true, oldest); } return (false, oldest); } function report(address token, uint256 value, address lesserKey, address greaterKey) external onlyOracle(token) { uint256 originalMedian = rates[token].getMedianValue(); if (rates[token].contains(msg.sender)) { rates[token].update(msg.sender, value, lesserKey, greaterKey); timestamps[token].remove(msg.sender); } else { rates[token].insert(msg.sender, value, lesserKey, greaterKey); } timestamps[token].insert( msg.sender, now, timestamps[token].getHead(), address(0) ); emit OracleReported(token, msg.sender, now, value); uint256 newMedian = rates[token].getMedianValue(); if (newMedian != originalMedian) { emit MedianUpdated(token, newMedian); } } function numRates(address token) public view returns (uint256) { return rates[token].getNumElements(); } function medianRate(address token) external view returns (uint256, uint256) { return (rates[token].getMedianValue(), numRates(token) == 0 ? 0 : FIXED1_UINT); } function getRates(address token) external view returns (address[] memory, uint256[] memory, SortedLinkedListWithMedian.MedianRelation[] memory) { return rates[token].getElements(); } function numTimestamps(address token) public view returns (uint256) { return timestamps[token].getNumElements(); } function medianTimestamp(address token) external view returns (uint256) { return timestamps[token].getMedianValue(); } function getTimestamps(address token) external view returns (address[] memory, uint256[] memory, SortedLinkedListWithMedian.MedianRelation[] memory) { return timestamps[token].getElements(); } function reportExists(address token, address oracle) internal view returns (bool) { return rates[token].contains(oracle) && timestamps[token].contains(oracle); } function getOracles(address token) external view returns (address[] memory) { return oracles[token]; } function removeReport(address token, address oracle) private { if (numTimestamps(token) == 1 && reportExists(token, oracle)) return; uint256 originalMedian = rates[token].getMedianValue(); rates[token].remove(oracle); timestamps[token].remove(oracle); emit OracleReportRemoved(token, oracle); uint256 newMedian = rates[token].getMedianValue(); if (newMedian != originalMedian) { emit MedianUpdated(token, newMedian); } } }
Contract ABI
[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""},{"type":"uint256[]","name":""},{"type":"uint8[]","name":""}],"name":"getRates","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"medianTimestamp","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"initialized","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isOracle","inputs":[{"type":"address","name":""},{"type":"address","name":""}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"reportExpirySeconds","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"removeOracle","inputs":[{"type":"address","name":"token"},{"type":"address","name":"oracleAddress"},{"type":"uint256","name":"index"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"numTimestamps","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"renounceOwnership","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"report","inputs":[{"type":"address","name":"token"},{"type":"uint256","name":"value"},{"type":"address","name":"lesserKey"},{"type":"address","name":"greaterKey"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"getOracles","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isOwner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"oracles","inputs":[{"type":"address","name":""},{"type":"uint256","name":""}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""},{"type":"uint256[]","name":""},{"type":"uint8[]","name":""}],"name":"getTimestamps","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"numRates","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"removeExpiredReports","inputs":[{"type":"address","name":"token"},{"type":"uint256","name":"n"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setReportExpiry","inputs":[{"type":"uint256","name":"_reportExpirySeconds"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""},{"type":"uint256","name":""}],"name":"medianRate","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"addOracle","inputs":[{"type":"address","name":"token"},{"type":"address","name":"oracleAddress"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"uint256","name":"_reportExpirySeconds"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""},{"type":"address","name":""}],"name":"isOldestReportExpired","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"event","name":"OracleAdded","inputs":[{"type":"address","name":"token","indexed":true},{"type":"address","name":"oracleAddress","indexed":true}],"anonymous":false},{"type":"event","name":"OracleRemoved","inputs":[{"type":"address","name":"token","indexed":true},{"type":"address","name":"oracleAddress","indexed":true}],"anonymous":false},{"type":"event","name":"OracleReported","inputs":[{"type":"address","name":"token","indexed":true},{"type":"address","name":"oracle","indexed":true},{"type":"uint256","name":"timestamp","indexed":false},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"OracleReportRemoved","inputs":[{"type":"address","name":"token","indexed":true},{"type":"address","name":"oracle","indexed":true}],"anonymous":false},{"type":"event","name":"MedianUpdated","inputs":[{"type":"address","name":"token","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"ReportExpirySet","inputs":[{"type":"uint256","name":"reportExpiry","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","indexed":true},{"type":"address","name":"newOwner","indexed":true}],"anonymous":false}]
Contract Creation Code
0x608060405260006100146100b760201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506100bf565b600033905090565b61388e80620000cf6000396000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c80638f32d59b116100b8578063ebc1d6bb1161007c578063ebc1d6bb14610844578063ef90e1b014610872578063f0ca4adb146108d1578063f2fde38b14610935578063fe4b84df14610979578063ffe736bf146109a757610142565b80638f32d59b146105c5578063a00a8b2c146105e7578063b929215814610675578063bbc66a941461079e578063dd34ca3b146107f657610142565b806353a572971161010a57806353a57297146103845780636dd6ef0c146103f2578063715018a61461044a57806380e50744146104545780638da5cb5b146104e25780638e7492811461052c57610142565b806302f55b6114610147578063071b48fc14610270578063158ef93e146102c8578063370c998e146102ea578063493a353c14610366575b600080fd5b6101896004803603602081101561015d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a36565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156101d45780820151818401526020810190506101b9565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156102165780820151818401526020810190506101fb565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561025857808201518184015260208101905061023d565b50505050905001965050505050505060405180910390f35b6102b26004803603602081101561028657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c06565b6040518082815260200191505060405180910390f35b6102d0610cd9565b604051808215151515815260200191505060405180910390f35b61034c6004803603604081101561030057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cec565b604051808215151515815260200191505060405180910390f35b61036e610d1b565b6040518082815260200191505060405180910390f35b6103f06004803603606081101561039a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d21565b005b6104346004803603602081101561040857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061125d565b6040518082815260200191505060405180910390f35b610452611330565b005b6104e06004803603608081101561046a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611469565b005b6104ea611e40565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61056e6004803603602081101561054257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e69565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105b1578082015181840152602081019050610596565b505050509050019250505060405180910390f35b6105cd611f36565b604051808215151515815260200191505060405180910390f35b610633600480360360408110156105fd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f94565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106b76004803603602081101561068b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611fdf565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156107025780820151818401526020810190506106e7565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015610744578082015181840152602081019050610729565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561078657808201518184015260208101905061076b565b50505050905001965050505050505060405180910390f35b6107e0600480360360208110156107b457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121af565b6040518082815260200191505060405180910390f35b6108426004803603604081101561080c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612282565b005b6108706004803603602081101561085a57600080fd5b8101908080359060200190929190505050612438565b005b6108b46004803603602081101561088857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125a7565b604051808381526020018281526020019250505060405180910390f35b610933600480360360408110156108e757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126a0565b005b6109776004803603602081101561094b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a02565b005b6109a56004803603602081101561098f57600080fd5b8101908080359060200190929190505050612a88565b005b6109e9600480360360208110156109bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b3b565b60405180831515151581526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6060806060600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636cfa387390916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b158015610aca57600080fd5b505af4158015610ade573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506060811015610b0857600080fd5b810190808051640100000000811115610b2057600080fd5b82810190506020810184811115610b3657600080fd5b8151856020820283011164010000000082111715610b5357600080fd5b50509291906020018051640100000000811115610b6f57600080fd5b82810190506020810184811115610b8557600080fd5b8151856020820283011164010000000082111715610ba257600080fd5b50509291906020018051640100000000811115610bbe57600080fd5b82810190506020810184811115610bd457600080fd5b8151856020820283011164010000000082111715610bf157600080fd5b50509291905050509250925092509193909250565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c9757600080fd5b505af4158015610cab573d6000803e3d6000fd5b505050506040513d6020811015610cc157600080fd5b81019080805190602001909291905050509050919050565b600060149054906101000a900460ff1681565b60036020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60055481565b610d29611f36565b610d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610e055750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015610e52575080600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050115b8015610efd57508173ffffffffffffffffffffffffffffffffffffffff16600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110610eba57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610f52576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260568152602001806137496056913960600191505060405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061107c6001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050612d8090919063ffffffff16565b8154811061108657fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106110fb57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111996001600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050612d8090919063ffffffff16565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020816111e3919061369d565b506111ee8383612dca565b156111fe576111fd8383612fd8565b5b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f6dc84b66cc948d847632b9d829f7cb1cb904fbf2c084554a9bc22ad9d845334060405160405180910390a3505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636eafa6c390916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156112ee57600080fd5b505af4158015611302573d6000803e3d6000fd5b505050506040513d602081101561131857600080fd5b81019080805190602001909291905050509050919050565b611338611f36565b6113aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b83600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611549576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806137f96027913960400191505060405180910390fd5b6000600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156115da57600080fd5b505af41580156115ee573d6000803e3d6000fd5b505050506040513d602081101561160457600080fd5b81019080805190602001909291905050509050600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6395073a799091336040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b1580156116da57600080fd5b505af41580156116ee573d6000803e3d6000fd5b505050506040513d602081101561170457600080fd5b81019080805190602001909291905050501561194557600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63832a21479091338888886040518663ffffffff1660e01b8152600401808681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060006040518083038186803b15801561184d57600080fd5b505af4158015611861573d6000803e3d6000fd5b50505050600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63c1e728e99091336040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b15801561192857600080fd5b505af415801561193c573d6000803e3d6000fd5b50505050611a91565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63d4a092729091338888886040518663ffffffff1660e01b8152600401808681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060006040518083038186803b158015611a7857600080fd5b505af4158015611a8c573d6000803e3d6000fd5b505050505b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63d4a0927290913342600260008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b630944c59490916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611b7d57600080fd5b505af4158015611b91573d6000803e3d6000fd5b505050506040513d6020811015611ba757600080fd5b810190808051906020019092919050505060006040518663ffffffff1660e01b8152600401808681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060006040518083038186803b158015611c8e57600080fd5b505af4158015611ca2573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f7cebb17173a9ed273d2b7538f64395c0ebf352ff743f1cf8ce66b437a61442134288604051808381526020018281526020019250505060405180910390a36000600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611da457600080fd5b505af4158015611db8573d6000803e3d6000fd5b505050506040513d6020811015611dce57600080fd5b81019080805190602001909291905050509050818114611e37578673ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040518082815260200191505060405180910390a25b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015611f2a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611ee0575b50505050509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611f78613409565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b60046020528160005260406000208181548110611fad57fe5b906000526020600020016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060806060600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636cfa387390916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561207357600080fd5b505af4158015612087573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060608110156120b157600080fd5b8101908080516401000000008111156120c957600080fd5b828101905060208101848111156120df57600080fd5b81518560208202830111640100000000821117156120fc57600080fd5b5050929190602001805164010000000081111561211857600080fd5b8281019050602081018481111561212e57600080fd5b815185602082028301116401000000008211171561214b57600080fd5b5050929190602001805164010000000081111561216757600080fd5b8281019050602081018481111561217d57600080fd5b815185602082028301116401000000008211171561219a57600080fd5b50509291905050509250925092509193909250565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636eafa6c390916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561224057600080fd5b505af4158015612254573d6000803e3d6000fd5b505050506040513d602081101561226a57600080fd5b81019080805190602001909291905050509050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156123875750600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636eafa6c390916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561234957600080fd5b505af415801561235d573d6000803e3d6000fd5b505050506040513d602081101561237357600080fd5b810190808051906020019092919050505081105b6123dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806137156034913960400191505060405180910390fd5b60008090505b81811015612433576000806123f685612b3b565b91509150811561240f5761240a8582612fd8565b612416565b5050612433565b505061242c60018261341190919063ffffffff16565b90506123e2565b505050565b612440611f36565b6124b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000811161250b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806138426021913960400191505060405180910390fd5b600554811415612566576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806138206022913960400191505060405180910390fd5b806005819055507fc68a9b88effd8a11611ff410efbc83569f0031b7bc70dd455b61344c7f0a042f816040518082815260200191505060405180910390a150565b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561263957600080fd5b505af415801561264d573d6000803e3d6000fd5b505050506040513d602081101561266357600080fd5b8101908080519060200190929190505050600061267f856121af565b146126945769d3c21bcecceda1000000612697565b60005b91509150915091565b6126a8611f36565b61271a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156127845750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156128175750600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b61286c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252605a81526020018061379f605a913960600191505060405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f828d2be040dede7698182e08dfa8bfbd663c879aee772509c4a2bd961d0ed43f60405160405180910390a35050565b612a0a611f36565b612a7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b612a8581613499565b50565b600060149054906101000a900460ff1615612b0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff021916908315150217905550612b2f33613499565b612b3881612438565b50565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612b7857600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63d938ec7b90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612c0957600080fd5b505af4158015612c1d573d6000803e3d6000fd5b505050506040513d6020811015612c3357600080fd5b810190808051906020019092919050505090506000600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b637c6bb8629091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015612d0b57600080fd5b505af4158015612d1f573d6000803e3d6000fd5b505050506040513d6020811015612d3557600080fd5b81019080805190602001909291905050509050600554612d5e8242612d8090919063ffffffff16565b10612d7157600182935093505050612d7b565b6000829350935050505b915091565b6000612dc283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135dd565b905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6395073a799091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015612e8f57600080fd5b505af4158015612ea3573d6000803e3d6000fd5b505050506040513d6020811015612eb957600080fd5b81019080805190602001909291905050508015612fd05750600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6395073a799091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015612f9457600080fd5b505af4158015612fa8573d6000803e3d6000fd5b505050506040513d6020811015612fbe57600080fd5b81019080805190602001909291905050505b905092915050565b6001612fe38361125d565b148015612ff65750612ff58282612dca565b5b1561300057613405565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561309157600080fd5b505af41580156130a5573d6000803e3d6000fd5b505050506040513d60208110156130bb57600080fd5b81019080805190602001909291905050509050600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63c1e728e99091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b15801561319157600080fd5b505af41580156131a5573d6000803e3d6000fd5b50505050600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63c1e728e99091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b15801561326c57600080fd5b505af4158015613280573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fe21a44017b6fa1658d84e937d56ff408501facdb4ff7427c479ac460d76f789360405160405180910390a36000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561336f57600080fd5b505af4158015613383573d6000803e3d6000fd5b505050506040513d602081101561339957600080fd5b81019080805190602001909291905050509050818114613402578373ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040518082815260200191505060405180910390a25b50505b5050565b600033905090565b60008082840190508381101561348f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561351f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806136ef6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600083831115829061368a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561364f578082015181840152602081019050613634565b50505050905090810190601f16801561367c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b8154818355818111156136c4578183600052602060002091820191016136c391906136c9565b5b505050565b6136eb91905b808211156136e75760008160009055506001016136cf565b5090565b9056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373746f6b656e2061646472206e756c6c206f7220747279696e6720746f2072656d6f766520746f6f206d616e79207265706f727473746f6b656e2061646472206e756c6c206f72206f7261636c652061646472206e756c6c206f7220696e646578206f6620746f6b656e206f7261636c65206e6f74206d617070656420746f206f7261636c652061646472746f6b656e206164647220776173206e756c6c206f72206f7261636c65206164647220776173206e756c6c206f72206f7261636c652061646472206973206e6f7420616e206f7261636c6520666f7220746f6b656e206164647273656e64657220776173206e6f7420616e206f7261636c6520666f7220746f6b656e20616464727265706f72744578706972795365636f6e6473206861736e2774206368616e6765647265706f727420657870697279207365636f6e6473206d757374206265203e2030a165627a7a7230582060b57140fb588509ccc502157dbe00d246dd2ba1d27546ce5a6cef6c8681293b0029
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101425760003560e01c80638f32d59b116100b8578063ebc1d6bb1161007c578063ebc1d6bb14610844578063ef90e1b014610872578063f0ca4adb146108d1578063f2fde38b14610935578063fe4b84df14610979578063ffe736bf146109a757610142565b80638f32d59b146105c5578063a00a8b2c146105e7578063b929215814610675578063bbc66a941461079e578063dd34ca3b146107f657610142565b806353a572971161010a57806353a57297146103845780636dd6ef0c146103f2578063715018a61461044a57806380e50744146104545780638da5cb5b146104e25780638e7492811461052c57610142565b806302f55b6114610147578063071b48fc14610270578063158ef93e146102c8578063370c998e146102ea578063493a353c14610366575b600080fd5b6101896004803603602081101561015d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a36565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156101d45780820151818401526020810190506101b9565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156102165780820151818401526020810190506101fb565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561025857808201518184015260208101905061023d565b50505050905001965050505050505060405180910390f35b6102b26004803603602081101561028657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c06565b6040518082815260200191505060405180910390f35b6102d0610cd9565b604051808215151515815260200191505060405180910390f35b61034c6004803603604081101561030057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cec565b604051808215151515815260200191505060405180910390f35b61036e610d1b565b6040518082815260200191505060405180910390f35b6103f06004803603606081101561039a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d21565b005b6104346004803603602081101561040857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061125d565b6040518082815260200191505060405180910390f35b610452611330565b005b6104e06004803603608081101561046a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611469565b005b6104ea611e40565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61056e6004803603602081101561054257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e69565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156105b1578082015181840152602081019050610596565b505050509050019250505060405180910390f35b6105cd611f36565b604051808215151515815260200191505060405180910390f35b610633600480360360408110156105fd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f94565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106b76004803603602081101561068b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611fdf565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156107025780820151818401526020810190506106e7565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015610744578082015181840152602081019050610729565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561078657808201518184015260208101905061076b565b50505050905001965050505050505060405180910390f35b6107e0600480360360208110156107b457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121af565b6040518082815260200191505060405180910390f35b6108426004803603604081101561080c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612282565b005b6108706004803603602081101561085a57600080fd5b8101908080359060200190929190505050612438565b005b6108b46004803603602081101561088857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125a7565b604051808381526020018281526020019250505060405180910390f35b610933600480360360408110156108e757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126a0565b005b6109776004803603602081101561094b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a02565b005b6109a56004803603602081101561098f57600080fd5b8101908080359060200190929190505050612a88565b005b6109e9600480360360208110156109bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b3b565b60405180831515151581526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390f35b6060806060600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636cfa387390916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b158015610aca57600080fd5b505af4158015610ade573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506060811015610b0857600080fd5b810190808051640100000000811115610b2057600080fd5b82810190506020810184811115610b3657600080fd5b8151856020820283011164010000000082111715610b5357600080fd5b50509291906020018051640100000000811115610b6f57600080fd5b82810190506020810184811115610b8557600080fd5b8151856020820283011164010000000082111715610ba257600080fd5b50509291906020018051640100000000811115610bbe57600080fd5b82810190506020810184811115610bd457600080fd5b8151856020820283011164010000000082111715610bf157600080fd5b50509291905050509250925092509193909250565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c9757600080fd5b505af4158015610cab573d6000803e3d6000fd5b505050506040513d6020811015610cc157600080fd5b81019080805190602001909291905050509050919050565b600060149054906101000a900460ff1681565b60036020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60055481565b610d29611f36565b610d9b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610e055750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015610e52575080600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050115b8015610efd57508173ffffffffffffffffffffffffffffffffffffffff16600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110610eba57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b610f52576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260568152602001806137496056913960600191505060405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061107c6001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050612d8090919063ffffffff16565b8154811061108657fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106110fb57fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111996001600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050612d8090919063ffffffff16565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020816111e3919061369d565b506111ee8383612dca565b156111fe576111fd8383612fd8565b5b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f6dc84b66cc948d847632b9d829f7cb1cb904fbf2c084554a9bc22ad9d845334060405160405180910390a3505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636eafa6c390916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156112ee57600080fd5b505af4158015611302573d6000803e3d6000fd5b505050506040513d602081101561131857600080fd5b81019080805190602001909291905050509050919050565b611338611f36565b6113aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b83600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611549576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806137f96027913960400191505060405180910390fd5b6000600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156115da57600080fd5b505af41580156115ee573d6000803e3d6000fd5b505050506040513d602081101561160457600080fd5b81019080805190602001909291905050509050600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6395073a799091336040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b1580156116da57600080fd5b505af41580156116ee573d6000803e3d6000fd5b505050506040513d602081101561170457600080fd5b81019080805190602001909291905050501561194557600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63832a21479091338888886040518663ffffffff1660e01b8152600401808681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060006040518083038186803b15801561184d57600080fd5b505af4158015611861573d6000803e3d6000fd5b50505050600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63c1e728e99091336040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b15801561192857600080fd5b505af415801561193c573d6000803e3d6000fd5b50505050611a91565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63d4a092729091338888886040518663ffffffff1660e01b8152600401808681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060006040518083038186803b158015611a7857600080fd5b505af4158015611a8c573d6000803e3d6000fd5b505050505b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63d4a0927290913342600260008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b630944c59490916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611b7d57600080fd5b505af4158015611b91573d6000803e3d6000fd5b505050506040513d6020811015611ba757600080fd5b810190808051906020019092919050505060006040518663ffffffff1660e01b8152600401808681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019550505050505060006040518083038186803b158015611c8e57600080fd5b505af4158015611ca2573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f7cebb17173a9ed273d2b7538f64395c0ebf352ff743f1cf8ce66b437a61442134288604051808381526020018281526020019250505060405180910390a36000600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611da457600080fd5b505af4158015611db8573d6000803e3d6000fd5b505050506040513d6020811015611dce57600080fd5b81019080805190602001909291905050509050818114611e37578673ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040518082815260200191505060405180910390a25b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015611f2a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611ee0575b50505050509050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611f78613409565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b60046020528160005260406000208181548110611fad57fe5b906000526020600020016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060806060600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636cfa387390916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561207357600080fd5b505af4158015612087573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060608110156120b157600080fd5b8101908080516401000000008111156120c957600080fd5b828101905060208101848111156120df57600080fd5b81518560208202830111640100000000821117156120fc57600080fd5b5050929190602001805164010000000081111561211857600080fd5b8281019050602081018481111561212e57600080fd5b815185602082028301116401000000008211171561214b57600080fd5b5050929190602001805164010000000081111561216757600080fd5b8281019050602081018481111561217d57600080fd5b815185602082028301116401000000008211171561219a57600080fd5b50509291905050509250925092509193909250565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636eafa6c390916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561224057600080fd5b505af4158015612254573d6000803e3d6000fd5b505050506040513d602081101561226a57600080fd5b81019080805190602001909291905050509050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156123875750600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b636eafa6c390916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561234957600080fd5b505af415801561235d573d6000803e3d6000fd5b505050506040513d602081101561237357600080fd5b810190808051906020019092919050505081105b6123dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806137156034913960400191505060405180910390fd5b60008090505b81811015612433576000806123f685612b3b565b91509150811561240f5761240a8582612fd8565b612416565b5050612433565b505061242c60018261341190919063ffffffff16565b90506123e2565b505050565b612440611f36565b6124b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000811161250b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806138426021913960400191505060405180910390fd5b600554811415612566576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806138206022913960400191505060405180910390fd5b806005819055507fc68a9b88effd8a11611ff410efbc83569f0031b7bc70dd455b61344c7f0a042f816040518082815260200191505060405180910390a150565b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561263957600080fd5b505af415801561264d573d6000803e3d6000fd5b505050506040513d602081101561266357600080fd5b8101908080519060200190929190505050600061267f856121af565b146126945769d3c21bcecceda1000000612697565b60005b91509150915091565b6126a8611f36565b61271a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156127845750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156128175750600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b61286c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252605a81526020018061379f605a913960600191505060405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f828d2be040dede7698182e08dfa8bfbd663c879aee772509c4a2bd961d0ed43f60405160405180910390a35050565b612a0a611f36565b612a7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b612a8581613499565b50565b600060149054906101000a900460ff1615612b0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff021916908315150217905550612b2f33613499565b612b3881612438565b50565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612b7857600080fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63d938ec7b90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612c0957600080fd5b505af4158015612c1d573d6000803e3d6000fd5b505050506040513d6020811015612c3357600080fd5b810190808051906020019092919050505090506000600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b637c6bb8629091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015612d0b57600080fd5b505af4158015612d1f573d6000803e3d6000fd5b505050506040513d6020811015612d3557600080fd5b81019080805190602001909291905050509050600554612d5e8242612d8090919063ffffffff16565b10612d7157600182935093505050612d7b565b6000829350935050505b915091565b6000612dc283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135dd565b905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6395073a799091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015612e8f57600080fd5b505af4158015612ea3573d6000803e3d6000fd5b505050506040513d6020811015612eb957600080fd5b81019080805190602001909291905050508015612fd05750600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6395073a799091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015612f9457600080fd5b505af4158015612fa8573d6000803e3d6000fd5b505050506040513d6020811015612fbe57600080fd5b81019080805190602001909291905050505b905092915050565b6001612fe38361125d565b148015612ff65750612ff58282612dca565b5b1561300057613405565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561309157600080fd5b505af41580156130a5573d6000803e3d6000fd5b505050506040513d60208110156130bb57600080fd5b81019080805190602001909291905050509050600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63c1e728e99091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b15801561319157600080fd5b505af41580156131a5573d6000803e3d6000fd5b50505050600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b63c1e728e99091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b15801561326c57600080fd5b505af4158015613280573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fe21a44017b6fa1658d84e937d56ff408501facdb4ff7427c479ac460d76f789360405160405180910390a36000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002073a3d1ef4f8119cb6b0ada6fa14d5d40d9e6b7594b6359d556a890916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561336f57600080fd5b505af4158015613383573d6000803e3d6000fd5b505050506040513d602081101561339957600080fd5b81019080805190602001909291905050509050818114613402578373ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040518082815260200191505060405180910390a25b50505b5050565b600033905090565b60008082840190508381101561348f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561351f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806136ef6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600083831115829061368a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561364f578082015181840152602081019050613634565b50505050905090810190601f16801561367c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b8154818355818111156136c4578183600052602060002091820191016136c391906136c9565b5b505050565b6136eb91905b808211156136e75760008160009055506001016136cf565b5090565b9056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373746f6b656e2061646472206e756c6c206f7220747279696e6720746f2072656d6f766520746f6f206d616e79207265706f727473746f6b656e2061646472206e756c6c206f72206f7261636c652061646472206e756c6c206f7220696e646578206f6620746f6b656e206f7261636c65206e6f74206d617070656420746f206f7261636c652061646472746f6b656e206164647220776173206e756c6c206f72206f7261636c65206164647220776173206e756c6c206f72206f7261636c652061646472206973206e6f7420616e206f7261636c6520666f7220746f6b656e206164647273656e64657220776173206e6f7420616e206f7261636c6520666f7220746f6b656e20616464727265706f72744578706972795365636f6e6473206861736e2774206368616e6765647265706f727420657870697279207365636f6e6473206d757374206265203e2030a165627a7a7230582060b57140fb588509ccc502157dbe00d246dd2ba1d27546ce5a6cef6c8681293b0029
External libraries
AddressSortedLinkedListWithMedian : 0xa3d1eF4f8119CB6B0aDa6fa14D5d40D9E6b7594B