Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x98b8414715b3faf5367bc01bf2c5f9edc1d7bb368d35585a95a4a165e424a001 | 0x7889515b | 789143 | 286 days 10 hrs ago | 0x0f3bf5c241b6625c0fa781ed137fde6786b2e66f | IN | 0xc3e272f76b3740c2acf8e5272cbef06d70e14ff3 | 0 ETH | 0.001080850889 ETH | |
0x04647cb0ed45f251e970c6b8d9c57aef620ae4fdc9598c03082136d232b35f7f | 0x60806040 | 219906 | 314 days 4 hrs ago | 0x904b5993fc92979eeedc19ccc58bed6b7216667c | IN | Create: OracleRouterCreator | 0 ETH | 0.026076887676 ETH |
[ Download CSV Export ]
Latest 3 internal transactions
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0x98b8414715b3faf5367bc01bf2c5f9edc1d7bb368d35585a95a4a165e424a001 | 789143 | 286 days 10 hrs ago | 0xc3e272f76b3740c2acf8e5272cbef06d70e14ff3 | 0xb1afceed90f97f5cd52e46b1810e4be97a04a793 | 0 ETH | ||
0x98b8414715b3faf5367bc01bf2c5f9edc1d7bb368d35585a95a4a165e424a001 | 789143 | 286 days 10 hrs ago | 0xc3e272f76b3740c2acf8e5272cbef06d70e14ff3 | 0xb1afceed90f97f5cd52e46b1810e4be97a04a793 | 0 ETH | ||
0x98b8414715b3faf5367bc01bf2c5f9edc1d7bb368d35585a95a4a165e424a001 | 789143 | 286 days 10 hrs ago | 0xc3e272f76b3740c2acf8e5272cbef06d70e14ff3 | Contract Creation | 0 ETH |
[ Download CSV Export ]
Contract Name:
OracleRouterCreator
Compiler Version
v0.7.4+commit.3f05b770
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.4; pragma experimental ABIEncoderV2; import "./OracleRouter.sol"; // A factory to deploy OracleRouter. Each path should be deployed only once. contract OracleRouterCreator { mapping(bytes32 => address) public routers; event NewOracleRouter( address router, string collateral, string underlyingAsset, OracleRouter.Route[] path ); /** * @notice Geth hash key of given path. * @param path [(oracle, isInverse)]. The OracleRouterCreator never verifies whether the path is reasonable. * collateral() and underlyingAsset() only shows correct value if the collateral token is in * the 1st item and the underlying asset is always in the last item. * @return @return The encoded bytes of data */ function getPathHash(OracleRouter.Route[] memory path) public pure returns (bytes32) { return keccak256(abi.encode(path)); } /** * @notice Create an OracleRouter. Revert if the router is already deployed. * @param path [(oracle, isInverse)]. The OracleRouterCreator never verifies whether the path is reasonable. * collateral() and underlyingAsset() only shows correct value if the collateral token is in * the 1st item and the underlying asset is always in the last item. * @return instance The address of the created OracleRouter */ function createOracleRouter(OracleRouter.Route[] memory path) public returns (address instance) { require(path.length > 0, "empty path"); bytes32 key = getPathHash(path); require(routers[key] == address(0), "already deployed"); OracleRouter router = new OracleRouter(path); instance = address(router); routers[key] = instance; emit NewOracleRouter(instance, router.collateral(), router.underlyingAsset(), path); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.4; pragma experimental ABIEncoderV2; import "../../libraries/SafeMathExt.sol"; import "../../interface/IOracle.sol"; // An oracle router calculates the asset price with a given path. // A path is [(oracle, isInverse)]. The OracleRouter never verifies whether the path is reasonable. // collateral() and underlyingAsset() only shows correct value if the collateral token is in the 1st item // and the underlying asset is always in the last item. // // Example 1: underlying = eth, collateral = usd, oracle1 = eth/usd = 1000 // [(oracle1, false)], return oracle1 = 1000 // // Example 2: underlying = usd, collateral = eth, oracle1 = eth/usd // [(oracle1, true)], return (1 / oracle1) = 0.001 // // Example 3: underlying = btc, collateral = eth, oracle1 = btc/usd = 10000, oracle2 = eth/usd = 1000 // [(oracle2, true), (oracle1, false)], return (1 / oracle2) * oracle1 = 10 // // Example 4: underlying = eth, collateral = btc, oracle1 = btc/usd = 10000, oracle2 = usd/eth = 0.001 // [(oracle1, true), (oracle2, true)], return (1 / oracle1) * (1 / oracle2) = 0.1 // // Example 5: underlying = xxx, collateral = eth, oracle1 = btc/usd = 10000, oracle2 = eth/usd = 1000, oracle3 = xxx/btc = 2 // [(oracle2, true), (oracle1, false), (oracle3, false)], return (1 / oracle2) * oracle1 * oracle3 = 20 // contract OracleRouter { using SafeMathExt for int256; using SafeMathExt for uint256; struct Route { address oracle; bool isInverse; } struct RouteDump { address oracle; bool isInverse; string underlyingAsset; string collateral; } string public constant source = "OracleRouter"; Route[] internal _path; constructor(Route[] memory path_) { require(path_.length > 0, "empty path"); for (uint256 i = 0; i < path_.length; i++) { require(path_[i].oracle != address(0), "empty oracle"); _path.push(Route({ oracle: path_[i].oracle, isInverse: path_[i].isInverse })); } } /** * @dev Get collateral symbol. * * The OracleRouter never verifies whether the path is reasonable. * collateral() and underlyingAsset() only shows correct value if the collateral token is in * the 1st item and the underlying asset is always in the last item. * @return symbol string */ function collateral() public view returns (string memory) { if (_path[0].isInverse) { return IOracle(_path[0].oracle).underlyingAsset(); } else { return IOracle(_path[0].oracle).collateral(); } } /** * @dev Get underlying asset symbol. * * The OracleRouter never verifies whether the path is reasonable. * collateral() and underlyingAsset() only shows correct value if the collateral token is in * the 1st item and the underlying asset is always in the last item. * @return symbol string */ function underlyingAsset() public view returns (string memory) { uint256 i = _path.length - 1; if (_path[i].isInverse) { return IOracle(_path[i].oracle).collateral(); } else { return IOracle(_path[i].oracle).underlyingAsset(); } } /** * @dev Mark price. */ function priceTWAPLong() external returns (int256 newPrice, uint256 newTimestamp) { newPrice = Constant.SIGNED_ONE; for (uint256 i = 0; i < _path.length; i++) { (int256 p, uint256 t) = IOracle(_path[i].oracle).priceTWAPLong(); if (_path[i].isInverse && p != 0) { p = Constant.SIGNED_ONE.wdiv(p); } newPrice = newPrice.wmul(p); newTimestamp = newTimestamp.max(t); } } /** * @dev Index price. */ function priceTWAPShort() external returns (int256 newPrice, uint256 newTimestamp) { newPrice = Constant.SIGNED_ONE; for (uint256 i = 0; i < _path.length; i++) { (int256 p, uint256 t) = IOracle(_path[i].oracle).priceTWAPShort(); if (_path[i].isInverse && p != 0) { p = Constant.SIGNED_ONE.wdiv(p); } newPrice = newPrice.wmul(p); newTimestamp = newTimestamp.max(t); } } /** * @dev The market is closed if the market is not in its regular trading period. */ function isMarketClosed() external returns (bool) { for (uint256 i = 0; i < _path.length; i++) { if (IOracle(_path[i].oracle).isMarketClosed()) { return true; } } return false; } /** * @dev The oracle service was shutdown and never online again. */ function isTerminated() external returns (bool) { for (uint256 i = 0; i < _path.length; i++) { if (IOracle(_path[i].oracle).isTerminated()) { return true; } } return false; } /** * @dev Dump the addresses */ function getPath() external view returns (Route[] memory) { return _path; } /** * @dev Dump the path with info */ function dumpPath() external view returns (RouteDump[] memory) { RouteDump[] memory ret = new RouteDump[](_path.length); for (uint256 i = 0; i < _path.length; i++) { ret[i].oracle = _path[i].oracle; ret[i].isInverse = _path[i].isInverse; ret[i].underlyingAsset = IOracle(_path[i].oracle).underlyingAsset(); ret[i].collateral = IOracle(_path[i].oracle).collateral(); } return ret; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.4; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/math/SignedSafeMathUpgradeable.sol"; import "./Constant.sol"; import "./Utils.sol"; enum Round { CEIL, FLOOR } library SafeMathExt { using SafeMathUpgradeable for uint256; using SignedSafeMathUpgradeable for int256; /* * @dev Always half up for uint256 */ function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.mul(y).add(Constant.UNSIGNED_ONE / 2) / Constant.UNSIGNED_ONE; } /* * @dev Always half up for uint256 */ function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.mul(Constant.UNSIGNED_ONE).add(y / 2).div(y); } /* * @dev Always half up for uint256 */ function wfrac( uint256 x, uint256 y, uint256 z ) internal pure returns (uint256 r) { r = x.mul(y).add(z / 2).div(z); } /* * @dev Always half up if no rounding parameter */ function wmul(int256 x, int256 y) internal pure returns (int256 z) { z = roundHalfUp(x.mul(y), Constant.SIGNED_ONE) / Constant.SIGNED_ONE; } /* * @dev Always half up if no rounding parameter */ function wdiv(int256 x, int256 y) internal pure returns (int256 z) { if (y < 0) { y = neg(y); x = neg(x); } z = roundHalfUp(x.mul(Constant.SIGNED_ONE), y).div(y); } /* * @dev Always half up if no rounding parameter */ function wfrac( int256 x, int256 y, int256 z ) internal pure returns (int256 r) { int256 t = x.mul(y); if (z < 0) { z = neg(z); t = neg(t); } r = roundHalfUp(t, z).div(z); } function wmul( int256 x, int256 y, Round round ) internal pure returns (int256 z) { z = div(x.mul(y), Constant.SIGNED_ONE, round); } function wdiv( int256 x, int256 y, Round round ) internal pure returns (int256 z) { z = div(x.mul(Constant.SIGNED_ONE), y, round); } function wfrac( int256 x, int256 y, int256 z, Round round ) internal pure returns (int256 r) { int256 t = x.mul(y); r = div(t, z, round); } function abs(int256 x) internal pure returns (int256) { return x >= 0 ? x : neg(x); } function neg(int256 a) internal pure returns (int256) { return SignedSafeMathUpgradeable.sub(int256(0), a); } /* * @dev ROUND_HALF_UP rule helper. * You have to call roundHalfUp(x, y) / y to finish the rounding operation. * 0.5 ≈ 1, 0.4 ≈ 0, -0.5 ≈ -1, -0.4 ≈ 0 */ function roundHalfUp(int256 x, int256 y) internal pure returns (int256) { require(y > 0, "roundHalfUp only supports y > 0"); if (x >= 0) { return x.add(y / 2); } return x.sub(y / 2); } /* * @dev Division, rounding ceil or rounding floor */ function div( int256 x, int256 y, Round round ) internal pure returns (int256 divResult) { require(y != 0, "division by zero"); divResult = x.div(y); if (x % y == 0) { return divResult; } bool isSameSign = Utils.hasTheSameSign(x, y); if (round == Round.CEIL && isSameSign) { divResult = divResult.add(1); } if (round == Round.FLOOR && !isSameSign) { divResult = divResult.sub(1); } } function max(int256 a, int256 b) internal pure returns (int256) { return a >= b ? a : b; } function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.7.4; interface IOracle { /** * @dev The market is closed if the market is not in its regular trading period. */ function isMarketClosed() external returns (bool); /** * @dev The oracle service was shutdown and never online again. */ function isTerminated() external returns (bool); /** * @dev Get collateral symbol. */ function collateral() external view returns (string memory); /** * @dev Get underlying asset symbol. */ function underlyingAsset() external view returns (string memory); /** * @dev Mark price. */ function priceTWAPLong() external returns (int256 newPrice, uint256 newTimestamp); /** * @dev Index price. */ function priceTWAPShort() external returns (int256 newPrice, uint256 newTimestamp); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ 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; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @title SignedSafeMath * @dev Signed math operations with safety checks that revert on error. */ library SignedSafeMathUpgradeable { int256 constant private _INT256_MIN = -2**255; /** * @dev Returns the multiplication of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow"); int256 c = a * b; require(c / a == b, "SignedSafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two signed integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0, "SignedSafeMath: division by zero"); require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow"); int256 c = a / b; return c; } /** * @dev Returns the subtraction of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow"); return c; } /** * @dev Returns the addition of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow"); return c; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.4; library Constant { address internal constant INVALID_ADDRESS = address(0); int256 internal constant SIGNED_ONE = 10**18; uint256 internal constant UNSIGNED_ONE = 10**18; uint256 internal constant PRIVILEGE_DEPOSIT = 0x1; uint256 internal constant PRIVILEGE_WITHDRAW = 0x2; uint256 internal constant PRIVILEGE_TRADE = 0x4; uint256 internal constant PRIVILEGE_LIQUIDATE = 0x8; uint256 internal constant PRIVILEGE_GUARD = PRIVILEGE_DEPOSIT | PRIVILEGE_WITHDRAW | PRIVILEGE_TRADE | PRIVILEGE_LIQUIDATE; // max number of uint256 uint256 internal constant SET_ALL_PERPETUALS_TO_EMERGENCY_STATE = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.4; import "@openzeppelin/contracts/utils/EnumerableSet.sol"; import "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/math/SignedSafeMathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import "./SafeMathExt.sol"; library Utils { using SafeMathExt for int256; using SafeMathExt for uint256; using SafeMathUpgradeable for uint256; using SignedSafeMathUpgradeable for int256; using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; using EnumerableSetUpgradeable for EnumerableSetUpgradeable.Bytes32Set; /* * @dev Check if two numbers have the same sign. Zero has the same sign with any number */ function hasTheSameSign(int256 x, int256 y) internal pure returns (bool) { if (x == 0 || y == 0) { return true; } return (x ^ y) >> 255 == 0; } /** * @dev Check if the trader has opened position in the trade. * Example: 2, 1 => true; 2, -1 => false; -2, -3 => true * @param amount The position of the trader after the trade * @param delta The update position amount of the trader after the trade * @return True if the trader has opened position in the trade */ function hasOpenedPosition(int256 amount, int256 delta) internal pure returns (bool) { if (amount == 0) { return false; } return Utils.hasTheSameSign(amount, delta); } /* * @dev Split the delta to two numbers. * Use for splitting the trading amount to the amount to close position and the amount to open position. * Examples: 2, 1 => 0, 1; 2, -1 => -1, 0; 2, -3 => -2, -1 */ function splitAmount(int256 amount, int256 delta) internal pure returns (int256, int256) { if (Utils.hasTheSameSign(amount, delta)) { return (0, delta); } else if (amount.abs() >= delta.abs()) { return (delta, 0); } else { return (amount.neg(), amount.add(delta)); } } /* * @dev Check if amount will be away from zero or cross zero if added the delta. * Use for checking if trading amount will make trader open position. * Example: 2, 1 => true; 2, -1 => false; 2, -3 => true */ function isOpen(int256 amount, int256 delta) internal pure returns (bool) { return Utils.hasTheSameSign(amount, delta) || amount.abs() < delta.abs(); } /* * @dev Get the id of the current chain */ function chainID() internal pure returns (uint256 id) { assembly { id := chainid() } } // function toArray( // EnumerableSet.AddressSet storage set, // uint256 begin, // uint256 end // ) internal view returns (address[] memory result) { // require(end > begin, "begin should be lower than end"); // uint256 length = set.length(); // if (begin >= length) { // return result; // } // uint256 safeEnd = end.min(length); // result = new address[](safeEnd.sub(begin)); // for (uint256 i = begin; i < safeEnd; i++) { // result[i.sub(begin)] = set.at(i); // } // return result; // } function toArray( EnumerableSetUpgradeable.AddressSet storage set, uint256 begin, uint256 end ) internal view returns (address[] memory result) { require(end > begin, "begin should be lower than end"); uint256 length = set.length(); if (begin >= length) { return result; } uint256 safeEnd = end.min(length); result = new address[](safeEnd.sub(begin)); for (uint256 i = begin; i < safeEnd; i++) { result[i.sub(begin)] = set.at(i); } return result; } function toArray( EnumerableSetUpgradeable.Bytes32Set storage set, uint256 begin, uint256 end ) internal view returns (bytes32[] memory result) { require(end > begin, "begin should be lower than end"); uint256 length = set.length(); if (begin >= length) { return result; } uint256 safeEnd = end.min(length); result = new bytes32[](safeEnd.sub(begin)); for (uint256 i = begin; i < safeEnd; i++) { result[i.sub(begin)] = set.at(i); } return result; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"router","type":"address"},{"indexed":false,"internalType":"string","name":"collateral","type":"string"},{"indexed":false,"internalType":"string","name":"underlyingAsset","type":"string"},{"components":[{"internalType":"address","name":"oracle","type":"address"},{"internalType":"bool","name":"isInverse","type":"bool"}],"indexed":false,"internalType":"struct OracleRouter.Route[]","name":"path","type":"tuple[]"}],"name":"NewOracleRouter","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"oracle","type":"address"},{"internalType":"bool","name":"isInverse","type":"bool"}],"internalType":"struct OracleRouter.Route[]","name":"path","type":"tuple[]"}],"name":"createOracleRouter","outputs":[{"internalType":"address","name":"instance","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"oracle","type":"address"},{"internalType":"bool","name":"isInverse","type":"bool"}],"internalType":"struct OracleRouter.Route[]","name":"path","type":"tuple[]"}],"name":"getPathHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"routers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50611b66806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620000465760003560e01c80635801d66f146200004b5780637889515b146200007a578063aa1fce6914620000a0575b600080fd5b620000626200005c366004620003c7565b620000b7565b60405162000071919062000635565b60405180910390f35b620000916200008b366004620003c7565b620000e9565b604051620000719190620005ac565b62000091620000b136600462000480565b6200032d565b600081604051602001620000cc919062000619565b604051602081830303815290604052805190602001209050919050565b600080825111620001175760405162461bcd60e51b81526004016200010e9062000675565b60405180910390fd5b60006200012483620000b7565b6000818152602081905260409020549091506001600160a01b0316156200015f5760405162461bcd60e51b81526004016200010e906200063e565b600083604051620001709062000348565b6200017c919062000619565b604051809103906000f08015801562000199573d6000803e3d6000fd5b5060008381526020819052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03851690811790915581517fd8dfeb4500000000000000000000000000000000000000000000000000000000815291519396508694507faa12a8903c780c1b4d3d993af516ecb732ab70b8363e9095d81da857d4358dc1938593919263d8dfeb45926004808301939192829003018186803b1580156200025357600080fd5b505afa15801562000268573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000292919081019062000499565b836001600160a01b0316637158da7c6040518163ffffffff1660e01b815260040160006040518083038186803b158015620002cc57600080fd5b505afa158015620002e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200030b919081019062000499565b876040516200031e9493929190620005c0565b60405180910390a15050919050565b6000602081905290815260409020546001600160a01b031681565b61142c806200070583390190565b60006040828403121562000368578081fd5b6040516040810181811067ffffffffffffffff821117156200038657fe5b60405290508082356001600160a01b0381168114620003a457600080fd5b815260208301358015158114620003ba57600080fd5b6020919091015292915050565b60006020808385031215620003da578182fd5b823567ffffffffffffffff80821115620003f2578384fd5b818501915085601f83011262000406578384fd5b8135818111156200041357fe5b620004228485830201620006ac565b81815284810192508385016040808402860187018a101562000442578788fd5b8795505b8386101562000472576200045b8a8362000356565b855260019590950194938601939081019062000446565b509098975050505050505050565b60006020828403121562000492578081fd5b5035919050565b600060208284031215620004ab578081fd5b815167ffffffffffffffff80821115620004c3578283fd5b818401915084601f830112620004d7578283fd5b815181811115620004e457fe5b620004f9601f8201601f1916602001620006ac565b915080825285602082850101111562000510578384fd5b62000523816020840160208601620006d1565b50949350505050565b6000815180845260208085019450808401835b838110156200057357815180516001600160a01b03168852830151151583880152604090960195908201906001016200053f565b509495945050505050565b6000815180845262000598816020860160208601620006d1565b601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b60006001600160a01b038616825260806020830152620005e460808301866200057e565b8281036040840152620005f881866200057e565b905082810360608401526200060e81856200052c565b979650505050505050565b6000602082526200062e60208301846200052c565b9392505050565b90815260200190565b60208082526010908201527f616c7265616479206465706c6f79656400000000000000000000000000000000604082015260600190565b6020808252600a908201527f656d707479207061746800000000000000000000000000000000000000000000604082015260600190565b60405181810167ffffffffffffffff81118282101715620006c957fe5b604052919050565b60005b83811015620006ee578181015183820152602001620006d4565b83811115620006fe576000848401525b5050505056fe60806040523480156200001157600080fd5b506040516200142c3803806200142c8339810160408190526200003491620001df565b6000815111620000615760405162461bcd60e51b81526004016200005890620002bd565b60405180910390fd5b60005b8151811015620001655760006001600160a01b03168282815181106200008657fe5b6020026020010151600001516001600160a01b03161415620000bc5760405162461bcd60e51b8152600401620000589062000297565b60006040518060400160405280848481518110620000d657fe5b6020026020010151600001516001600160a01b03168152602001848481518110620000fd57fe5b602090810291909101810151810151151590915282546001818101855560009485529382902083519101805493909201511515600160a01b0260ff60a01b196001600160a01b039092166001600160a01b031990941693909317169190911790550162000064565b505062000305565b6000604082840312156200017f578081fd5b604080519081016001600160401b03811182821017156200019c57fe5b604052825190915081906001600160a01b0381168114620001bc57600080fd5b815260208301518015158114620001d257600080fd5b6020919091015292915050565b60006020808385031215620001f2578182fd5b82516001600160401b038082111562000209578384fd5b818501915085601f8301126200021d578384fd5b8151818111156200022a57fe5b620002398485830201620002e1565b81815284810192508385016040808402860187018a101562000259578788fd5b8795505b838610156200028957620002728a836200016d565b85526001959095019493860193908101906200025d565b509098975050505050505050565b6020808252600c908201526b656d707479206f7261636c6560a01b604082015260600190565b6020808252600a90820152690cadae0e8f240e0c2e8d60b31b604082015260600190565b6040518181016001600160401b0381118282101715620002fd57fe5b604052919050565b61111780620003156000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80639410b9e211610076578063ccbdbee21161005b578063ccbdbee214610123578063d1cc99761461012b578063d8dfeb4514610133576100a3565b80639410b9e2146100f9578063b7e86c1f1461010e576100a3565b80630e222f9b146100a8578063555b37be146100c757806367e828bf146100dc5780637158da7c146100f1575b600080fd5b6100b061013b565b6040516100be929190611003565b60405180910390f35b6100cf610273565b6040516100be9190610f9e565b6100e46102ec565b6040516100be9190611011565b6100e4610325565b610101610443565b6040516100be9190610efa565b6101166106a2565b6040516100be9190610ff8565b6100b061076f565b6101166108a2565b6100e4610967565b670de0b6b3a76400006000805b60005481101561026e576000806000838154811061016257fe5b6000918252602082200154604080517f0e222f9b00000000000000000000000000000000000000000000000000000000815281516001600160a01b0390931693630e222f9b93600480840194939192918390030190829087803b1580156101c857600080fd5b505af11580156101dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102009190610e14565b915091506000838154811061021157fe5b600091825260209091200154600160a01b900460ff16801561023257508115155b1561024c57610249670de0b6b3a764000083610a7c565b91505b6102568583610ac9565b94506102628482610afe565b93505050600101610148565b509091565b60606000805480602002602001604051908101604052809291908181526020016000905b828210156102e257600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900460ff16151581830152825260019092019101610297565b5050505090505b90565b6040518060400160405280600c81526020017f4f7261636c65526f75746572000000000000000000000000000000000000000081525081565b600080546060916000198201918290811061033c57fe5b600091825260209091200154600160a01b900460ff16156103ef576000818154811061036457fe5b60009182526020822001546040805163d8dfeb4560e01b815290516001600160a01b039092169263d8dfeb4592600480840193829003018186803b1580156103ab57600080fd5b505afa1580156103bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103e79190810190610e37565b9150506102e9565b600081815481106103fc57fe5b600091825260208220015460408051631c56369f60e21b815290516001600160a01b0390921692637158da7c92600480840193829003018186803b1580156103ab57600080fd5b600054606090819067ffffffffffffffff8111801561046157600080fd5b5060405190808252806020026020018201604052801561049b57816020015b610488610dce565b8152602001906001900390816104805790505b50905060005b60005481101561069c57600081815481106104b857fe5b60009182526020909120015482516001600160a01b03909116908390839081106104de57fe5b60209081029190910101516001600160a01b039091169052600080548290811061050457fe5b9060005260206000200160000160149054906101000a900460ff1682828151811061052b57fe5b602090810291909101810151911515910152600080548290811061054b57fe5b600091825260208220015460408051631c56369f60e21b815290516001600160a01b0390921692637158da7c92600480840193829003018186803b15801561059257600080fd5b505afa1580156105a6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105ce9190810190610e37565b8282815181106105da57fe5b602002602001015160400181905250600081815481106105f657fe5b60009182526020822001546040805163d8dfeb4560e01b815290516001600160a01b039092169263d8dfeb4592600480840193829003018186803b15801561063d57600080fd5b505afa158015610651573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106799190810190610e37565b82828151811061068557fe5b6020908102919091010151606001526001016104a1565b50905090565b6000805b60005481101561076757600081815481106106bd57fe5b9060005260206000200160000160009054906101000a90046001600160a01b03166001600160a01b031663b7e86c1f6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561071857600080fd5b505af115801561072c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107509190610df4565b1561075f5760019150506102e9565b6001016106a6565b506000905090565b670de0b6b3a76400006000805b60005481101561026e576000806000838154811061079657fe5b6000918252602082200154604080517fccbdbee200000000000000000000000000000000000000000000000000000000815281516001600160a01b039093169363ccbdbee293600480840194939192918390030190829087803b1580156107fc57600080fd5b505af1158015610810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108349190610e14565b915091506000838154811061084557fe5b600091825260209091200154600160a01b900460ff16801561086657508115155b156108805761087d670de0b6b3a764000083610a7c565b91505b61088a8583610ac9565b94506108968482610afe565b9350505060010161077c565b6000805b60005481101561076757600081815481106108bd57fe5b9060005260206000200160000160009054906101000a90046001600160a01b03166001600160a01b031663d1cc99766040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561091857600080fd5b505af115801561092c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109509190610df4565b1561095f5760019150506102e9565b6001016108a6565b60606000808154811061097657fe5b600091825260209091200154600160a01b900460ff1615610a28576000808154811061099e57fe5b600091825260208220015460408051631c56369f60e21b815290516001600160a01b0390921692637158da7c92600480840193829003018186803b1580156109e557600080fd5b505afa1580156109f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a219190810190610e37565b90506102e9565b60008081548110610a3557fe5b60009182526020822001546040805163d8dfeb4560e01b815290516001600160a01b039092169263d8dfeb4592600480840193829003018186803b1580156109e557600080fd5b600080821215610a9d57610a8f82610b17565b9150610a9a83610b17565b92505b610ac282610abc610ab686670de0b6b3a7640000610b24565b85610bcd565b90610c4c565b9392505050565b6000670de0b6b3a7640000610aef610ae18585610b24565b670de0b6b3a7640000610bcd565b81610af657fe5b059392505050565b600081831015610b0e5781610ac2565b50815b92915050565b6000610b11600083610d04565b600082610b3357506000610b11565b82600019148015610b475750600160ff1b82145b15610b835760405162461bcd60e51b81526004018080602001828103825260278152602001806110976027913960400191505060405180910390fd5b82820282848281610b9057fe5b0514610ac25760405162461bcd60e51b81526004018080602001828103825260278152602001806110976027913960400191505060405180910390fd5b6000808213610c23576040805162461bcd60e51b815260206004820152601f60248201527f726f756e6448616c665570206f6e6c7920737570706f7274732079203e203000604482015290519081900360640190fd5b60008312610c3f57610c388360028405610d69565b9050610b11565b610ac28360028405610d04565b600081610ca0576040805162461bcd60e51b815260206004820181905260248201527f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f604482015290519081900360640190fd5b81600019148015610cb45750600160ff1b83145b15610cf05760405162461bcd60e51b81526004018080602001828103825260218152602001806110766021913960400191505060405180910390fd5b6000828481610cfb57fe5b05949350505050565b6000818303818312801590610d195750838113155b80610d2e5750600083128015610d2e57508381135b610ac25760405162461bcd60e51b81526004018080602001828103825260248152602001806110be6024913960400191505060405180910390fd5b6000828201818312801590610d7e5750838112155b80610d935750600083128015610d9357508381125b610ac25760405162461bcd60e51b81526004018080602001828103825260218152602001806110556021913960400191505060405180910390fd5b604080516080810182526000808252602082015260609181018290528181019190915290565b600060208284031215610e05578081fd5b81518015158114610ac2578182fd5b60008060408385031215610e26578081fd5b505080516020909101519092909150565b600060208284031215610e48578081fd5b815167ffffffffffffffff80821115610e5f578283fd5b818401915084601f830112610e72578283fd5b815181811115610e7e57fe5b604051601f8201601f191681016020018381118282101715610e9c57fe5b604052818152838201602001871015610eb3578485fd5b610ec4826020830160208701611024565b9695505050505050565b60008151808452610ee6816020860160208601611024565b601f01601f19169290920160200192915050565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015610f9057603f19898403018552815160806001600160a01b03825116855288820151151589860152878201518189870152610f5f82870182610ece565b91505060608083015192508582038187015250610f7c8183610ece565b968901969450505090860190600101610f1e565b509098975050505050505050565b602080825282518282018190526000919060409081850190868401855b82811015610feb57815180516001600160a01b031685528601511515868501529284019290850190600101610fbb565b5091979650505050505050565b901515815260200190565b918252602082015260400190565b600060208252610ac26020830184610ece565b60005b8381101561103f578181015183820152602001611027565b8381111561104e576000848401525b5050505056fe5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f775369676e6564536166654d6174683a206469766973696f6e206f766572666c6f775369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f77a2646970667358221220a4c2a47d962be5d1086ee09a986ddb5e8caf1659b21283a450f1ea231291460964736f6c63430007040033a2646970667358221220e94c2323e8b7b06673c8441c3ac5fcf2b8d4471a29d8860bf475560339309e8764736f6c63430007040033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.