Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 1,055 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Update Result | 20167009 | 627 days ago | IN | 0 ETH | 0.00136885 | ||||
| Update Result | 17946391 | 938 days ago | IN | 0 ETH | 0.0042203 | ||||
| Update Result | 17940134 | 939 days ago | IN | 0 ETH | 0.00539508 | ||||
| Update Result | 17937605 | 940 days ago | IN | 0 ETH | 0.02305126 | ||||
| Update Result | 17646321 | 980 days ago | IN | 0 ETH | 0.00428248 | ||||
| Update Result | 17643795 | 981 days ago | IN | 0 ETH | 0.00959747 | ||||
| Update Result | 17304741 | 1028 days ago | IN | 0 ETH | 0.00755153 | ||||
| Update Result | 17138644 | 1052 days ago | IN | 0 ETH | 0.0126374 | ||||
| Update Result | 17136136 | 1052 days ago | IN | 0 ETH | 0.00968896 | ||||
| Update Result | 17091765 | 1058 days ago | IN | 0 ETH | 0.01101683 | ||||
| Update Result | 17089257 | 1059 days ago | IN | 0 ETH | 0.01695664 | ||||
| Update Result | 17085899 | 1059 days ago | IN | 0 ETH | 0.03456471 | ||||
| Update Result | 17083396 | 1060 days ago | IN | 0 ETH | 0.0263579 | ||||
| Update Result | 17080886 | 1060 days ago | IN | 0 ETH | 0.0183361 | ||||
| Update Result | 17078383 | 1060 days ago | IN | 0 ETH | 0.01258605 | ||||
| Update Result | 17075867 | 1061 days ago | IN | 0 ETH | 0.0287294 | ||||
| Update Result | 17073363 | 1061 days ago | IN | 0 ETH | 0.01320527 | ||||
| Update Result | 17069545 | 1062 days ago | IN | 0 ETH | 0.00880662 | ||||
| Update Result | 17064672 | 1062 days ago | IN | 0 ETH | 0.00755366 | ||||
| Update Result | 17062181 | 1063 days ago | IN | 0 ETH | 0.00933003 | ||||
| Update Result | 17059683 | 1063 days ago | IN | 0 ETH | 0.00753455 | ||||
| Update Result | 17057196 | 1063 days ago | IN | 0 ETH | 0.00716607 | ||||
| Update Result | 17054696 | 1064 days ago | IN | 0 ETH | 0.0071726 | ||||
| Update Result | 17052208 | 1064 days ago | IN | 0 ETH | 0.00819414 | ||||
| Update Result | 17049718 | 1064 days ago | IN | 0 ETH | 0.00727984 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
UniswapConsecutiveSlotsPriceFeedMedianizer
Compiler Version
v0.6.7+commit.b8d736ae
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2022-02-27
*/
// Verified using https://dapp.tools
// hevm: flattened sources of /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/UniswapConsecutiveSlotsPriceFeedMedianizer.sol
pragma solidity =0.6.7;
////// /nix/store/3d3msxain9q01swpn63dsh9wl2hsal24-geb-treasury-reimbursement/dapp/geb-treasury-reimbursement/src/math/GebMath.sol
/* pragma solidity 0.6.7; */
contract GebMath {
uint256 public constant RAY = 10 ** 27;
uint256 public constant WAD = 10 ** 18;
function ray(uint x) public pure returns (uint z) {
z = multiply(x, 10 ** 9);
}
function rad(uint x) public pure returns (uint z) {
z = multiply(x, 10 ** 27);
}
function minimum(uint x, uint y) public pure returns (uint z) {
z = (x <= y) ? x : y;
}
function addition(uint x, uint y) public pure returns (uint z) {
z = x + y;
require(z >= x, "uint-uint-add-overflow");
}
function subtract(uint x, uint y) public pure returns (uint z) {
z = x - y;
require(z <= x, "uint-uint-sub-underflow");
}
function multiply(uint x, uint y) public pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, "uint-uint-mul-overflow");
}
function rmultiply(uint x, uint y) public pure returns (uint z) {
z = multiply(x, y) / RAY;
}
function rdivide(uint x, uint y) public pure returns (uint z) {
z = multiply(x, RAY) / y;
}
function wdivide(uint x, uint y) public pure returns (uint z) {
z = multiply(x, WAD) / y;
}
function wmultiply(uint x, uint y) public pure returns (uint z) {
z = multiply(x, y) / WAD;
}
function rpower(uint x, uint n, uint base) public pure returns (uint z) {
assembly {
switch x case 0 {switch n case 0 {z := base} default {z := 0}}
default {
switch mod(n, 2) case 0 { z := base } default { z := x }
let half := div(base, 2) // for rounding.
for { n := div(n, 2) } n { n := div(n,2) } {
let xx := mul(x, x)
if iszero(eq(div(xx, x), x)) { revert(0,0) }
let xxRound := add(xx, half)
if lt(xxRound, xx) { revert(0,0) }
x := div(xxRound, base)
if mod(n,2) {
let zx := mul(z, x)
if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
let zxRound := add(zx, half)
if lt(zxRound, zx) { revert(0,0) }
z := div(zxRound, base)
}
}
}
}
}
}
////// /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/univ2/interfaces/IUniswapV2Factory.sol
/* pragma solidity 0.6.7; */
interface IUniswapV2Factory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}
////// /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/univ2/interfaces/IUniswapV2Pair.sol
/* pragma solidity 0.6.7; */
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function kLast() external view returns (uint);
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
////// /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/univ2/libs/UniswapV2Library.sol
/* pragma solidity 0.6.7; */
/* import '../interfaces/IUniswapV2Pair.sol'; */
/* import '../interfaces/IUniswapV2Factory.sol'; */
contract UniswapV2Library {
// --- Math ---
function uniAddition(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x, 'UniswapV2Library: add-overflow');
}
function uniSubtract(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, 'UniswapV2Library: sub-underflow');
}
function uniMultiply(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, 'UniswapV2Library: mul-overflow');
}
// returns sorted token addresses, used to handle return values from pairs sorted in this order
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES');
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS');
}
// Modified Uniswap function to work with dapp.tools (CREATE2 throws)
function pairFor(address factory, address tokenA, address tokenB) internal view returns (address pair) {
(address token0, address token1) = sortTokens(tokenA, tokenB);
return IUniswapV2Factory(factory).getPair(tokenA, tokenB);
}
// fetches and sorts the reserves for a pair; modified from the initial Uniswap version in order to work with dapp.tools
function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
(address token0,) = sortTokens(tokenA, tokenB);
(uint reserve0, uint reserve1,) = IUniswapV2Pair(IUniswapV2Factory(factory).getPair(tokenA, tokenB)).getReserves();
(reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
}
// Given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) {
require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT');
require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
amountB = uniMultiply(amountA, reserveB) / reserveA;
}
// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint amountInWithFee = uniMultiply(amountIn, 997);
uint numerator = uniMultiply(amountInWithFee, reserveOut);
uint denominator = uniAddition(uniMultiply(reserveIn, 1000), amountInWithFee);
amountOut = numerator / denominator;
}
// given an output amount of an asset and pair reserves, returns a required input amount of the other asset
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint numerator = uniMultiply(uniMultiply(reserveIn, amountOut), 1000);
uint denominator = uniMultiply(uniSubtract(reserveOut, amountOut), 997);
amountIn = uniAddition((numerator / denominator), 1);
}
// performs chained getAmountOut calculations on any number of pairs
function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) {
require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');
amounts = new uint[](path.length);
amounts[0] = amountIn;
for (uint i; i < path.length - 1; i++) {
(uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]);
amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
}
}
// performs chained getAmountIn calculations on any number of pairs
function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) {
require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');
amounts = new uint[](path.length);
amounts[amounts.length - 1] = amountOut;
for (uint i = path.length - 1; i > 0; i--) {
(uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]);
amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
}
}
}
////// /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/univ2/libs/BabylonianMath.sol
// SPDX-License-Identifier: GPL-3.0-or-later
/* pragma solidity 0.6.7; */
// computes square roots using the babylonian method
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
contract BabylonianMath {
function sqrt(uint y) internal pure returns (uint z) {
if (y > 3) {
z = y;
uint x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
// else z = 0
}
}
////// /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/univ2/libs/FixedPointMath.sol
// SPDX-License-Identifier: GPL-3.0-or-later
/* pragma solidity 0.6.7; */
/* import './BabylonianMath.sol'; */
// Contract for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
contract FixedPointMath is BabylonianMath {
// range: [0, 2**112 - 1]
// resolution: 1 / 2**112
struct uq112x112 {
uint224 _x;
}
// range: [0, 2**144 - 1]
// resolution: 1 / 2**112
struct uq144x112 {
uint _x;
}
uint8 private constant RESOLUTION = 112;
uint private constant Q112 = uint(1) << RESOLUTION;
uint private constant Q224 = Q112 << RESOLUTION;
// encode a uint112 as a UQ112x112
function encode(uint112 x) internal pure returns (uq112x112 memory) {
return uq112x112(uint224(x) << RESOLUTION);
}
// encodes a uint144 as a UQ144x112
function encode144(uint144 x) internal pure returns (uq144x112 memory) {
return uq144x112(uint256(x) << RESOLUTION);
}
// divide a UQ112x112 by a uint112, returning a UQ112x112
function div(uq112x112 memory self, uint112 x) internal pure returns (uq112x112 memory) {
require(x != 0, 'FixedPoint: DIV_BY_ZERO');
return uq112x112(self._x / uint224(x));
}
// multiply a UQ112x112 by a uint, returning a UQ144x112
// reverts on overflow
function mul(uq112x112 memory self, uint y) internal pure returns (uq144x112 memory) {
uint z;
require(y == 0 || (z = uint(self._x) * y) / y == uint(self._x), "FixedPoint: MULTIPLICATION_OVERFLOW");
return uq144x112(z);
}
// returns a UQ112x112 which represents the ratio of the numerator to the denominator
// equivalent to encode(numerator).divide(denominator)
function frac(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) {
require(denominator > 0, "FixedPoint: DIV_BY_ZERO");
return uq112x112((uint224(numerator) << RESOLUTION) / denominator);
}
// decode a UQ112x112 into a uint112 by truncating after the radix point
function decode(uq112x112 memory self) internal pure returns (uint112) {
return uint112(self._x >> RESOLUTION);
}
// decode a UQ144x112 into a uint144 by truncating after the radix point
function decode144(uq144x112 memory self) internal pure returns (uint144) {
return uint144(self._x >> RESOLUTION);
}
// take the reciprocal of a UQ112x112
function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) {
require(self._x != 0, 'FixedPoint: ZERO_RECIPROCAL');
return uq112x112(uint224(Q224 / self._x));
}
// square root of a UQ112x112
function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {
return uq112x112(uint224(super.sqrt(uint256(self._x)) << 56));
}
}
////// /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/univ2/libs/UniswapV2OracleLibrary.sol
/* pragma solidity 0.6.7; */
/* import '../interfaces/IUniswapV2Pair.sol'; */
/* import './FixedPointMath.sol'; */
// Contract with helper methods for oracles that are concerned with computing average prices
contract UniswapV2OracleLibrary is FixedPointMath {
// Helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1]
function currentBlockTimestamp() internal view returns (uint32) {
return uint32(block.timestamp % 2 ** 32);
}
// Produces the cumulative price using counterfactuals to save gas and avoid a call to sync.
function currentCumulativePrices(
address pair
) internal view returns (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) {
blockTimestamp = currentBlockTimestamp();
price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast();
price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast();
// if time has elapsed since the last update on the pair, mock the accumulated price values
(uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IUniswapV2Pair(pair).getReserves();
if (blockTimestampLast != blockTimestamp) {
// subtraction overflow is desired
uint32 timeElapsed = blockTimestamp - blockTimestampLast;
// addition overflow is desired
// counterfactual
price0Cumulative += uint(frac(reserve1, reserve0)._x) * timeElapsed;
// counterfactual
price1Cumulative += uint(frac(reserve0, reserve1)._x) * timeElapsed;
}
}
}
////// /nix/store/jhkj8my1hkpiklhhkl8xyzpxwpzix5fj-geb-uniswap-median/dapp/geb-uniswap-median/src/UniswapConsecutiveSlotsPriceFeedMedianizer.sol
/* pragma solidity 0.6.7; */
/* import "geb-treasury-reimbursement/math/GebMath.sol"; */
/* import './univ2/interfaces/IUniswapV2Factory.sol'; */
/* import './univ2/interfaces/IUniswapV2Pair.sol'; */
/* import './univ2/libs/UniswapV2Library.sol'; */
/* import './univ2/libs/UniswapV2OracleLibrary.sol'; */
abstract contract ConverterFeedLike_2 {
function getResultWithValidity() virtual external view returns (uint256,bool);
function updateResult(address) virtual external;
}
abstract contract IncreasingRewardRelayerLike_1 {
function reimburseCaller(address) virtual external;
}
contract UniswapConsecutiveSlotsPriceFeedMedianizer is GebMath, UniswapV2Library, UniswapV2OracleLibrary {
// --- Auth ---
mapping (address => uint) public authorizedAccounts;
/**
* @notice Add auth to an account
* @param account Account to add auth to
*/
function addAuthorization(address account) virtual external isAuthorized {
authorizedAccounts[account] = 1;
emit AddAuthorization(account);
}
/**
* @notice Remove auth from an account
* @param account Account to remove auth from
*/
function removeAuthorization(address account) virtual external isAuthorized {
authorizedAccounts[account] = 0;
emit RemoveAuthorization(account);
}
/**
* @notice Checks whether msg.sender can call an authed function
**/
modifier isAuthorized {
require(authorizedAccounts[msg.sender] == 1, "UniswapConsecutiveSlotsPriceFeedMedianizer/account-not-authorized");
_;
}
// --- Observations ---
struct UniswapObservation {
uint timestamp;
uint price0Cumulative;
uint price1Cumulative;
}
struct ConverterFeedObservation {
uint timestamp;
uint timeAdjustedPrice;
}
// --- Uniswap Vars ---
// Default amount of targetToken used when calculating the denominationToken output
uint256 public defaultAmountIn;
// Token for which the contract calculates the medianPrice for
address public targetToken;
// Pair token from the Uniswap pair
address public denominationToken;
address public uniswapPair;
IUniswapV2Factory public uniswapFactory;
UniswapObservation[] public uniswapObservations;
// --- Converter Feed Vars ---
// Latest converter price accumulator snapshot
uint256 public converterPriceCumulative;
ConverterFeedLike_2 public converterFeed;
ConverterFeedObservation[] public converterFeedObservations;
// --- General Vars ---
// Symbol - you want to change this every deployment
bytes32 public symbol = "raiusd";
uint8 public granularity;
// When the price feed was last updated
uint256 public lastUpdateTime;
// Total number of updates
uint256 public updates;
/**
The ideal amount of time over which the moving average should be computed, e.g. 24 hours.
In practice it can and most probably will be different than the actual window over which the contract medianizes.
**/
uint256 public windowSize;
// Maximum window size used to determine if the median is 'valid' (close to the real one) or not
uint256 public maxWindowSize;
// Stored for gas savings. Equals windowSize / granularity
uint256 public periodSize;
// This is the denominator for computing
uint256 public converterFeedScalingFactor;
// The last computed median price
uint256 private medianPrice;
// Manual flag that can be set by governance and indicates if a result is valid or not
uint256 public validityFlag;
// Contract relaying the SF reward to addresses that update this oracle
IncreasingRewardRelayerLike_1 public relayer;
// --- Events ---
event AddAuthorization(address account);
event RemoveAuthorization(address account);
event ModifyParameters(
bytes32 parameter,
address addr
);
event ModifyParameters(
bytes32 parameter,
uint256 val
);
event UpdateResult(uint256 medianPrice, uint256 lastUpdateTime);
event FailedConverterFeedUpdate(bytes reason);
event FailedUniswapPairSync(bytes reason);
event FailedReimburseCaller(bytes revertReason);
constructor(
address converterFeed_,
address uniswapFactory_,
uint256 defaultAmountIn_,
uint256 windowSize_,
uint256 converterFeedScalingFactor_,
uint256 maxWindowSize_,
uint8 granularity_
) public {
require(uniswapFactory_ != address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/null-uniswap-factory");
require(granularity_ > 1, 'UniswapConsecutiveSlotsPriceFeedMedianizer/null-granularity');
require(windowSize_ > 0, 'UniswapConsecutiveSlotsPriceFeedMedianizer/null-window-size');
require(maxWindowSize_ > windowSize_, 'UniswapConsecutiveSlotsPriceFeedMedianizer/invalid-max-window-size');
require(defaultAmountIn_ > 0, 'UniswapConsecutiveSlotsPriceFeedMedianizer/invalid-default-amount-in');
require(converterFeedScalingFactor_ > 0, 'UniswapConsecutiveSlotsPriceFeedMedianizer/null-feed-scaling-factor');
require(
(periodSize = windowSize_ / granularity_) * granularity_ == windowSize_,
'UniswapConsecutiveSlotsPriceFeedMedianizer/window-not-evenly-divisible'
);
authorizedAccounts[msg.sender] = 1;
converterFeed = ConverterFeedLike_2(converterFeed_);
uniswapFactory = IUniswapV2Factory(uniswapFactory_);
defaultAmountIn = defaultAmountIn_;
windowSize = windowSize_;
maxWindowSize = maxWindowSize_;
converterFeedScalingFactor = converterFeedScalingFactor_;
granularity = granularity_;
lastUpdateTime = now;
validityFlag = 1;
// Emit events
emit AddAuthorization(msg.sender);
emit ModifyParameters(bytes32("converterFeed"), converterFeed_);
emit ModifyParameters(bytes32("maxWindowSize"), maxWindowSize_);
}
// --- Administration ---
/**
* @notice Modify address parameters
* @param parameter Name of the parameter to modify
* @param data New parameter value
**/
function modifyParameters(bytes32 parameter, address data) external isAuthorized {
require(data != address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/null-data");
if (parameter == "converterFeed") {
require(data != address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/null-converter-feed");
converterFeed = ConverterFeedLike_2(data);
}
else if (parameter == "targetToken") {
require(uniswapPair == address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/pair-already-set");
targetToken = data;
if (denominationToken != address(0)) {
uniswapPair = uniswapFactory.getPair(targetToken, denominationToken);
require(uniswapPair != address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/null-uniswap-pair");
}
}
else if (parameter == "denominationToken") {
require(uniswapPair == address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/pair-already-set");
denominationToken = data;
if (targetToken != address(0)) {
uniswapPair = uniswapFactory.getPair(targetToken, denominationToken);
require(uniswapPair != address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/null-uniswap-pair");
}
}
else if (parameter == "relayer") {
relayer = IncreasingRewardRelayerLike_1(data);
}
else revert("UniswapConsecutiveSlotsPriceFeedMedianizer/modify-unrecognized-param");
emit ModifyParameters(parameter, data);
}
/**
* @notice Modify uint256 parameters
* @param parameter Name of the parameter to modify
* @param data New parameter value
**/
function modifyParameters(bytes32 parameter, uint256 data) external isAuthorized {
if (parameter == "validityFlag") {
require(either(data == 1, data == 0), "UniswapConsecutiveSlotsPriceFeedMedianizer/invalid-data");
validityFlag = data;
}
else if (parameter == "defaultAmountIn") {
require(data > 0, "UniswapConsecutiveSlotsPriceFeedMedianizer/invalid-default-amount-in");
defaultAmountIn = data;
}
else if (parameter == "maxWindowSize") {
require(data > windowSize, 'UniswapConsecutiveSlotsPriceFeedMedianizer/invalid-max-window-size');
maxWindowSize = data;
}
else revert("UniswapConsecutiveSlotsPriceFeedMedianizer/modify-unrecognized-param");
emit ModifyParameters(parameter, data);
}
// --- General Utils ---
function either(bool x, bool y) internal pure returns (bool z) {
assembly{ z := or(x, y)}
}
function both(bool x, bool y) private pure returns (bool z) {
assembly{ z := and(x, y)}
}
/**
* @notice Returns the oldest observations (relative to the current index in the Uniswap/Converter lists)
**/
function getFirstObservationsInWindow()
private view returns (UniswapObservation storage firstUniswapObservation, ConverterFeedObservation storage firstConverterFeedObservation) {
uint256 earliestObservationIndex = earliestObservationIndex();
firstUniswapObservation = uniswapObservations[earliestObservationIndex];
firstConverterFeedObservation = converterFeedObservations[earliestObservationIndex];
}
/**
@notice It returns the time passed since the first observation in the window
**/
function timeElapsedSinceFirstObservation() public view returns (uint256) {
if (updates > 1) {
(
UniswapObservation storage firstUniswapObservation,
) = getFirstObservationsInWindow();
return subtract(now, firstUniswapObservation.timestamp);
}
return 0;
}
/**
* @notice Calculate the median price using the latest observations and the latest Uniswap pair prices
* @param price0Cumulative Cumulative price for the first token in the pair
* @param price1Cumulative Cumulative price for the second token in the pair
**/
function getMedianPrice(uint256 price0Cumulative, uint256 price1Cumulative) private view returns (uint256) {
if (updates > 1) {
(
UniswapObservation storage firstUniswapObservation,
) = getFirstObservationsInWindow();
uint timeSinceFirst = subtract(now, firstUniswapObservation.timestamp);
(address token0,) = sortTokens(targetToken, denominationToken);
uint256 uniswapAmountOut;
if (token0 == targetToken) {
uniswapAmountOut = uniswapComputeAmountOut(
firstUniswapObservation.price0Cumulative, price0Cumulative, timeSinceFirst, defaultAmountIn
);
} else {
uniswapAmountOut = uniswapComputeAmountOut(
firstUniswapObservation.price1Cumulative, price1Cumulative, timeSinceFirst, defaultAmountIn
);
}
return converterComputeAmountOut(timeSinceFirst, uniswapAmountOut);
}
return medianPrice;
}
/**
* @notice Returns the index of the earliest observation in the window
**/
function earliestObservationIndex() public view returns (uint256) {
if (updates <= granularity) {
return 0;
}
return subtract(updates, uint(granularity));
}
/**
* @notice Get the observation list length
**/
function getObservationListLength() public view returns (uint256, uint256) {
return (uniswapObservations.length, converterFeedObservations.length);
}
// --- Uniswap Utils ---
/**
* @notice Given the Uniswap cumulative prices of the start and end of a period, and the length of the period, compute the average
* price in terms of how much amount out is received for the amount in.
* @param priceCumulativeStart Old snapshot of the cumulative price of a token
* @param priceCumulativeEnd New snapshot of the cumulative price of a token
* @param timeElapsed Total time elapsed
* @param amountIn Amount of target tokens we want to find the price for
**/
function uniswapComputeAmountOut(
uint256 priceCumulativeStart,
uint256 priceCumulativeEnd,
uint256 timeElapsed,
uint256 amountIn
) public pure returns (uint256 amountOut) {
require(priceCumulativeEnd >= priceCumulativeStart, "UniswapConverterBasicAveragePriceFeedMedianizer/invalid-end-cumulative");
require(timeElapsed > 0, "UniswapConsecutiveSlotsPriceFeedMedianizer/null-time-elapsed");
// Overflow is desired
uq112x112 memory priceAverage = uq112x112(
uint224((priceCumulativeEnd - priceCumulativeStart) / timeElapsed)
);
amountOut = decode144(mul(priceAverage, amountIn));
}
// --- Converter Utils ---
/**
* @notice Calculate the price of an amount of tokens using the converter price feed as well as the time elapsed between
* the latest timestamp and the timestamp of the earliest observation in the window.
* Used after the contract determines the amount of Uniswap pair denomination tokens for amountIn target tokens
* @param timeElapsed Time elapsed between now and the earliest observation in the window.
* @param amountIn Amount of denomination tokens to calculate the price for
**/
function converterComputeAmountOut(
uint256 timeElapsed,
uint256 amountIn
) public view returns (uint256 amountOut) {
require(timeElapsed > 0, "UniswapConsecutiveSlotsPriceFeedMedianizer/null-time-elapsed");
uint256 priceAverage = converterPriceCumulative / timeElapsed;
amountOut = multiply(amountIn, priceAverage) / converterFeedScalingFactor;
}
// --- Core Logic ---
/**
* @notice Update the internal median price
**/
function updateResult(address feeReceiver) external {
require(address(relayer) != address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/null-relayer");
require(uniswapPair != address(0), "UniswapConsecutiveSlotsPriceFeedMedianizer/null-uniswap-pair");
// Get final fee receiver
address finalFeeReceiver = (feeReceiver == address(0)) ? msg.sender : feeReceiver;
// Update the converter's median price first
try converterFeed.updateResult(finalFeeReceiver) {}
catch (bytes memory converterRevertReason) {
emit FailedConverterFeedUpdate(converterRevertReason);
}
// Get the observation for the current period
uint256 timeElapsedSinceLatest = (uniswapObservations.length == 0) ?
subtract(now, lastUpdateTime) : subtract(now, uniswapObservations[uniswapObservations.length - 1].timestamp);
// We only want to commit updates once per period (i.e. windowSize / granularity)
if (uniswapObservations.length > 0) {
require(timeElapsedSinceLatest >= periodSize, "UniswapConsecutiveSlotsPriceFeedMedianizer/not-enough-time-elapsed");
}
// Update Uniswap pair
try IUniswapV2Pair(uniswapPair).sync() {}
catch (bytes memory uniswapRevertReason) {
emit FailedUniswapPairSync(uniswapRevertReason);
}
// Get Uniswap cumulative prices
(uint uniswapPrice0Cumulative, uint uniswapPrice1Cumulative,) = currentCumulativePrices(uniswapPair);
// Add new observations
updateObservations(timeElapsedSinceLatest, uniswapPrice0Cumulative, uniswapPrice1Cumulative);
// Calculate latest medianPrice
medianPrice = getMedianPrice(uniswapPrice0Cumulative, uniswapPrice1Cumulative);
lastUpdateTime = now;
updates = addition(updates, 1);
emit UpdateResult(medianPrice, lastUpdateTime);
// Try to reward the caller
try relayer.reimburseCaller(finalFeeReceiver) {
} catch (bytes memory revertReason) {
emit FailedReimburseCaller(revertReason);
}
}
/**
* @notice Push new observation data in the observation arrays
* @param timeElapsedSinceLatest Time elapsed between now and the earliest observation in the window
* @param uniswapPrice0Cumulative Latest cumulative price of the first token in a Uniswap pair
* @param uniswapPrice1Cumulative Latest cumulative price of the second tokens in a Uniswap pair
**/
function updateObservations(
uint256 timeElapsedSinceLatest,
uint256 uniswapPrice0Cumulative,
uint256 uniswapPrice1Cumulative
) internal {
// Add converter feed observation
(uint256 priceFeedValue, bool hasValidValue) = converterFeed.getResultWithValidity();
require(hasValidValue, "UniswapConsecutiveSlotsPriceFeedMedianizer/invalid-converter-price-feed");
uint256 newTimeAdjustedPrice = multiply(priceFeedValue, timeElapsedSinceLatest);
// Add converter observation
converterFeedObservations.push(ConverterFeedObservation(now, newTimeAdjustedPrice));
// Add Uniswap observation
uniswapObservations.push(UniswapObservation(now, uniswapPrice0Cumulative, uniswapPrice1Cumulative));
// Add the new update
converterPriceCumulative = addition(converterPriceCumulative, newTimeAdjustedPrice);
// Subtract the earliest update
if (updates >= granularity) {
(
,
ConverterFeedObservation storage firstConverterFeedObservation
) = getFirstObservationsInWindow();
converterPriceCumulative = subtract(converterPriceCumulative, firstConverterFeedObservation.timeAdjustedPrice);
}
}
// --- Getters ---
/**
* @notice Fetch the latest medianPrice or revert if is is null
**/
function read() external view returns (uint256) {
require(
both(both(both(medianPrice > 0, updates > granularity), timeElapsedSinceFirstObservation() <= maxWindowSize), validityFlag == 1),
"UniswapConsecutiveSlotsPriceFeedMedianizer/invalid-price-feed"
);
return medianPrice;
}
/**
* @notice Fetch the latest medianPrice and whether it is null or not
**/
function getResultWithValidity() external view returns (uint256, bool) {
return (
medianPrice,
both(both(both(medianPrice > 0, updates > granularity), timeElapsedSinceFirstObservation() <= maxWindowSize), validityFlag == 1)
);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"converterFeed_","type":"address"},{"internalType":"address","name":"uniswapFactory_","type":"address"},{"internalType":"uint256","name":"defaultAmountIn_","type":"uint256"},{"internalType":"uint256","name":"windowSize_","type":"uint256"},{"internalType":"uint256","name":"converterFeedScalingFactor_","type":"uint256"},{"internalType":"uint256","name":"maxWindowSize_","type":"uint256"},{"internalType":"uint8","name":"granularity_","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"AddAuthorization","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"FailedConverterFeedUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"revertReason","type":"bytes"}],"name":"FailedReimburseCaller","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"FailedUniswapPairSync","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"RemoveAuthorization","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"medianPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastUpdateTime","type":"uint256"}],"name":"UpdateResult","type":"event"},{"inputs":[],"name":"RAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WAD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"addition","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorizedAccounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeElapsed","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"converterComputeAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"converterFeed","outputs":[{"internalType":"contract ConverterFeedLike_2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"converterFeedObservations","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"timeAdjustedPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"converterFeedScalingFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"converterPriceCumulative","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultAmountIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"denominationToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"earliestObservationIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getObservationListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getResultWithValidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"granularity","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWindowSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"minimum","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"multiply","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"periodSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"rad","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"ray","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"rdivide","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"read","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"relayer","outputs":[{"internalType":"contract IncreasingRewardRelayerLike_1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"rmultiply","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"n","type":"uint256"},{"internalType":"uint256","name":"base","type":"uint256"}],"name":"rpower","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"subtract","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeElapsedSinceFirstObservation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"priceCumulativeStart","type":"uint256"},{"internalType":"uint256","name":"priceCumulativeEnd","type":"uint256"},{"internalType":"uint256","name":"timeElapsed","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"uniswapComputeAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"uniswapFactory","outputs":[{"internalType":"contract IUniswapV2Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uniswapObservations","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"price0Cumulative","type":"uint256"},{"internalType":"uint256","name":"price1Cumulative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"feeReceiver","type":"address"}],"name":"updateResult","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validityFlag","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"wdivide","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"windowSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"wmultiply","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"}]Contract Creation Code
60806040527f7261697573640000000000000000000000000000000000000000000000000000600a553480156200003557600080fd5b506040516200420d3803806200420d833981810160405260e08110156200005b57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141562000130576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f8152602001806200418b603f913960400191505060405180910390fd5b60018160ff16116200018e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001806200410c603b913960400191505060405180910390fd5b60008411620001e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180620040d1603b913960400191505060405180910390fd5b83821162000243576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260428152602001806200408f6042913960600191505060405180910390fd5b600085116200029e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526044815260200180620041476044913960600191505060405180910390fd5b60008311620002f9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526043815260200180620041ca6043913960600191505060405180910390fd5b838160ff168260ff1686816200030b57fe5b04601081905502146200036a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526046815260200180620040496046913960600191505060405180910390fd5b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555086600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460018190555083600e8190555081600f819055508260118190555080600b60006101000a81548160ff021916908360ff16021790555042600c8190555060016013819055507f599a298163e1678bb1c676052a8930bf0b8a1261ed6e01b8a2391e55f700010233604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17fd91f38cf03346b5dc15fb60f9076f866295231ad3c3841a1051f8443f25170d17f636f6e766572746572466565640000000000000000000000000000000000000088604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a17fac7c5c1afaef770ec56ac6268cd3f2fbb1035858ead2601d6553157c33036c3a7f6d617857696e646f7753697a650000000000000000000000000000000000000083604051808381526020018281526020019250505060405180910390a150505050505050613a6f80620005da6000396000f3fe608060405234801561001057600080fd5b506004361061027f5760003560e01c806368a82ef61161015c578063bc3501e2116100ce578063d6e882dc11610087578063d6e882dc14610b0f578063dd2d2a1214610b65578063e4463eb214610bb1578063f6b9fdfb14610bcf578063f752fdc314610c19578063fe4f589014610c655761027f565b8063bc3501e214610a01578063bd9e799d14610a1f578063c5cb2dcc14610a6b578063c816841b14610a89578063c8f33c9114610ad3578063d4ef172214610af15761027f565b806394f3f81d1161012057806394f3f81d146108cd57806395d89b41146109115780639df055f51461092f578063a0685e841461094d578063a087163714610997578063b1940058146109e35761027f565b806368a82ef6146107df5780636a146024146107fd5780638406c0791461081b5780638a14117a146108655780638bdb2afa146108835761027f565b80633c8bb3e6116101f55780634fd0ada8116101b95780634fd0ada8146106bc57806354f363a3146106e5578063552033c414610731578063556f0dc71461074f57806357de26a4146107735780636614f010146107915761027f565b80633c8bb3e6146105805780633ef5e445146105cc57806341938b021461061857806346f3e81c14610636578063495df025146106785761027f565b806324ba58841161024757806324ba588414610407578063303aa80f1461045f57806331c9626a146104af578063327107f7146104cd57806335b28153146105175780633c3f91251461055b5761027f565b8063056640b7146102845780630ac91638146102d05780630d88ed89146103195780631021344714610379578063165c4a16146103bb575b600080fd5b6102ba6004803603604081101561029a57600080fd5b810190808035906020019092919080359060200190929190505050610c9d565b6040518082815260200191505060405180910390f35b6102fc600480360360208110156102e657600080fd5b8101908080359060200190929190505050610cc6565b604051808381526020018281526020019250505060405180910390f35b6103636004803603608081101561032f57600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190505050610cf7565b6040518082815260200191505060405180910390f35b6103a56004803603602081101561038f57600080fd5b8101908080359060200190929190505050610e1e565b6040518082815260200191505060405180910390f35b6103f1600480360360408110156103d157600080fd5b810190808035906020019092919080359060200190929190505050610e35565b6040518082815260200191505060405180910390f35b6104496004803603602081101561041d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610eca565b6040518082815260200191505060405180910390f35b61048b6004803603602081101561047557600080fd5b8101908080359060200190929190505050610ee2565b60405180848152602001838152602001828152602001935050505060405180910390f35b6104b7610f19565b6040518082815260200191505060405180910390f35b6104d5610f1f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105596004803603602081101561052d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f45565b005b610563611086565b604051808381526020018281526020019250505060405180910390f35b6105b66004803603604081101561059657600080fd5b81019080803590602001909291908035906020019092919050505061109d565b6040518082815260200191505060405180910390f35b610602600480360360408110156105e257600080fd5b8101908080359060200190929190803590602001909291905050506110c2565b6040518082815260200191505060405180910390f35b610620611145565b6040518082815260200191505060405180910390f35b6106626004803603602081101561064c57600080fd5b810190808035906020019092919050505061114b565b6040518082815260200191505060405180910390f35b6106ba6004803603602081101561068e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061116a565b005b6106c46118d1565b60405180838152602001821515151581526020019250505060405180910390f35b61071b600480360360408110156106fb57600080fd5b810190808035906020019092919080359060200190929190505050611927565b6040518082815260200191505060405180910390f35b6107396119aa565b6040518082815260200191505060405180910390f35b6107576119ba565b604051808260ff1660ff16815260200191505060405180910390f35b61077b6119cd565b6040518082815260200191505060405180910390f35b6107dd600480360360408110156107a757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a74565b005b6107e7612502565b6040518082815260200191505060405180910390f35b610805612508565b6040518082815260200191505060405180910390f35b610823612514565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61086d61253a565b6040518082815260200191505060405180910390f35b61088b612540565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61090f600480360360208110156108e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612566565b005b6109196126a7565b6040518082815260200191505060405180910390f35b6109376126ad565b6040518082815260200191505060405180910390f35b6109556126b3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109cd600480360360408110156109ad57600080fd5b8101908080359060200190929190803590602001909291905050506126d9565b6040518082815260200191505060405180910390f35b6109eb612702565b6040518082815260200191505060405180910390f35b610a09612708565b6040518082815260200191505060405180910390f35b610a5560048036036040811015610a3557600080fd5b810190808035906020019092919080359060200190929190505050612740565b6040518082815260200191505060405180910390f35b610a736127c8565b6040518082815260200191505060405180910390f35b610a91612812565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610adb612838565b6040518082815260200191505060405180910390f35b610af961283e565b6040518082815260200191505060405180910390f35b610b4f60048036036060811015610b2557600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050612844565b6040518082815260200191505060405180910390f35b610b9b60048036036040811015610b7b57600080fd5b81019080803590602001909291908035906020019092919050505061290a565b6040518082815260200191505060405180910390f35b610bb9612924565b6040518082815260200191505060405180910390f35b610bd761292a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c4f60048036036040811015610c2f57600080fd5b810190808035906020019092919080359060200190929190505050612950565b6040518082815260200191505060405180910390f35b610c9b60048036036040811015610c7b57600080fd5b810190808035906020019092919080359060200190929190505050612975565b005b60006b033b2e3c9fd0803ce8000000610cb68484610e35565b81610cbd57fe5b04905092915050565b60098181548110610cd357fe5b90600052602060002090600202016000915090508060000154908060010154905082565b600084841015610d52576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806139b26046913960600191505060405180910390fd5b60008311610dab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180613916603c913960400191505060405180910390fd5b610db3613603565b60405180602001604052808588880381610dc957fe5b047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050610dff610dfa8285612c56565b612d2c565b71ffffffffffffffffffffffffffffffffffff16915050949350505050565b6000610e2e82633b9aca00610e35565b9050919050565b600080821480610e525750828283850292508281610e4f57fe5b04145b610ec4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f75696e742d75696e742d6d756c2d6f766572666c6f770000000000000000000081525060200191505060405180910390fd5b92915050565b60006020528060005260406000206000915090505481565b60068181548110610eef57fe5b90600052602060002090600302016000915090508060000154908060010154908060020154905083565b60135481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f599a298163e1678bb1c676052a8930bf0b8a1261ed6e01b8a2391e55f700010281604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600680549050600980549050915091509091565b6000670de0b6b3a76400006110b28484610e35565b816110b957fe5b04905092915050565b600081830390508281111561113f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f75696e742d75696e742d7375622d756e646572666c6f7700000000000000000081525060200191505060405180910390fd5b92915050565b600f5481565b6000611163826b033b2e3c9fd0803ce8000000610e35565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff16601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611212576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001806138ab6037913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c81526020018061386f603c913960400191505060405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146112f557816112f7565b335b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663495df025826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561139a57600080fd5b505af19250505080156113ab575060015b611483573d80600081146113db576040519150601f19603f3d011682016040523d82523d6000602084013e6113e0565b606091505b507f321dc066db92f97ab7f8b6f080147cb31cc027a61c0b6c026f055a39009be70f816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611443578082015181840152602081019050611428565b50505050905090810190601f1680156114705780820380516001836020036101000a031916815260200191505b509250505060405180910390a150611484565b5b600080600680549050146114c7576114c2426006600160068054905003815481106114ab57fe5b9060005260206000209060030201600001546110c2565b6114d4565b6114d342600c546110c2565b5b9050600060068054905011156115405760105481101561153f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260428152602001806139f86042913960600191505060405180910390fd5b5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156115aa57600080fd5b505af19250505080156115bb575060015b611693573d80600081146115eb576040519150601f19603f3d011682016040523d82523d6000602084013e6115f0565b606091505b507ff64c46db4bf4aeeff8f4a6001e70e2e8cac802c514905f29bdd5659efc75b8b0816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611653578082015181840152602081019050611638565b50505050905090810190601f1680156116805780820380516001836020036101000a031916815260200191505b509250505060405180910390a150611694565b5b6000806116c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612d41565b50915091506116d2838383612f8c565b6116dc82826131b9565b60128190555042600c819055506116f6600d546001611927565b600d819055507ff85e44c6c3597d176b8d59bfbf500dfdb2badfc8cf91e6d960b16583a5807e48601254600c54604051808381526020018281526020019250505060405180910390a1601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d7fb67a856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156117e057600080fd5b505af19250505080156117f1575060015b6118c9573d8060008114611821576040519150601f19603f3d011682016040523d82523d6000602084013e611826565b606091505b507facc18fe32f7716216416b1673ee8570f5b04c7a4012a84d130f3221632003ad9816040518080602001828103825283818151815260200191508051906020019080838360005b8381101561188957808201518184015260208101905061186e565b50505050905090810190601f1680156118b65780820380516001836020036101000a031916815260200191505b509250505060405180910390a1506118ca565b5b5050505050565b60008060125461191f611914611902600060125411600b60009054906101000a900460ff1660ff16600d54116132df565b600f5461190d612708565b11156132df565b6001601354146132df565b915091509091565b60008183019050828110156119a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f75696e742d75696e742d6164642d6f766572666c6f770000000000000000000081525060200191505060405180910390fd5b92915050565b6b033b2e3c9fd0803ce800000081565b600b60009054906101000a900460ff1681565b6000611a17611a0c6119fa600060125411600b60009054906101000a900460ff1660ff16600d54116132df565b600f54611a05612708565b11156132df565b6001601354146132df565b611a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180613975603d913960400191505060405180910390fd5b601254905090565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611b0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806138e26034913960400191505060405180910390fd5b7f636f6e7665727465724665656400000000000000000000000000000000000000821415611c8557600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180613683603e913960400191505060405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612493565b7f746172676574546f6b656e00000000000000000000000000000000000000000082141561202b57600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611d54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180613648603b913960400191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461202657600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a43905600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015611f0257600080fd5b505afa158015611f16573d6000803e3d6000fd5b505050506040513d6020811015611f2c57600080fd5b8101908080519060200190929190505050600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612025576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c81526020018061386f603c913960400191505060405180910390fd5b5b612492565b7f64656e6f6d696e6174696f6e546f6b656e0000000000000000000000000000008214156123d157600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180613648603b913960400191505060405180910390fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146123cc57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a43905600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b1580156122a857600080fd5b505afa1580156122bc573d6000803e3d6000fd5b505050506040513d60208110156122d257600080fd5b8101908080519060200190929190505050600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156123cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c81526020018061386f603c913960400191505060405180910390fd5b5b612491565b7f72656c617965720000000000000000000000000000000000000000000000000082141561243f5780601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612490565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001806137a66044913960600191505060405180910390fd5b5b5b5b7fd91f38cf03346b5dc15fb60f9076f866295231ad3c3841a1051f8443f25170d18282604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b600d5481565b670de0b6b3a764000081565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e5481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146125fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f8834a87e641e9716be4f34527af5d23e11624f1ddeefede6ad75a9acfc31b90381604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600a5481565b60075481565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000816126f2846b033b2e3c9fd0803ce8000000610e35565b816126f957fe5b04905092915050565b60115481565b60006001600d54111561273857600061271f6132ec565b5090506127304282600001546110c2565b91505061273d565b600090505b90565b600080831161279a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180613916603c913960400191505060405180910390fd5b600083600754816127a757fe5b0490506011546127b78483610e35565b816127be57fe5b0491505092915050565b6000600b60009054906101000a900460ff1660ff16600d54116127ee576000905061280f565b61280c600d54600b60009054906101000a900460ff1660ff166110c2565b90505b90565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c5481565b60015481565b600083600081146128ea57600284066000811461286357859250612867565b8392505b50600283046002850494505b84156128e457858602868782041461288a57600080fd5b8181018181101561289a57600080fd5b858104975060028706156128d75787850285898204141589151516156128bf57600080fd5b838101818110156128cf57600080fd5b878104965050505b5050600285049450612873565b50612902565b83600081146128fc5760009250612900565b8392505b505b509392505050565b60008183111561291a578161291c565b825b905092915050565b60105481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008161296584670de0b6b3a7640000610e35565b8161296c57fe5b04905092915050565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612a0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b7f76616c6964697479466c61670000000000000000000000000000000000000000821415612aa557612a44600182146000831461333a565b612a99576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001806136c16037913960400191505060405180910390fd5b80601381905550612c13565b7f64656661756c74416d6f756e74496e0000000000000000000000000000000000821415612b325760008111612b26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001806137ea6044913960600191505060405180910390fd5b80600181905550612c12565b7f6d617857696e646f7753697a6500000000000000000000000000000000000000821415612bc057600e548111612bb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260428152602001806136f86042913960600191505060405180910390fd5b80600f81905550612c11565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001806137a66044913960600191505060405180910390fd5b5b5b7fac7c5c1afaef770ec56ac6268cd3f2fbb1035858ead2601d6553157c33036c3a8282604051808381526020018281526020019250505060405180910390a15050565b612c5e613634565b600080831480612cbf575083600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16838486600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160292508281612cbc57fe5b04145b612d14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806139526023913960400191505060405180910390fd5b60405180602001604052808281525091505092915050565b6000607060ff168260000151901c9050919050565b6000806000612d4e613347565b90508373ffffffffffffffffffffffffffffffffffffffff16635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b158015612d9657600080fd5b505afa158015612daa573d6000803e3d6000fd5b505050506040513d6020811015612dc057600080fd5b810190808051906020019092919050505092508373ffffffffffffffffffffffffffffffffffffffff16635a3d54936040518163ffffffff1660e01b815260040160206040518083038186803b158015612e1957600080fd5b505afa158015612e2d573d6000803e3d6000fd5b505050506040513d6020811015612e4357600080fd5b8101908080519060200190929190505050915060008060008673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612ea157600080fd5b505afa158015612eb5573d6000803e3d6000fd5b505050506040513d6060811015612ecb57600080fd5b810190808051906020019092919080519060200190929190805190602001909291905050509250925092508363ffffffff168163ffffffff1614612f8257600081850390508063ffffffff16612f21848661335d565b600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602870196508063ffffffff16612f59858561335d565b600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160286019550505b5050509193909250565b600080600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634fd0ada86040518163ffffffff1660e01b8152600401604080518083038186803b158015612ff657600080fd5b505afa15801561300a573d6000803e3d6000fd5b505050506040513d604081101561302057600080fd5b8101908080519060200190929190805190602001909291905050509150915080613095576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604781526020018061373a6047913960600191505060405180910390fd5b60006130a18387610e35565b9050600960405180604001604052804281526020018381525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010155505060066040518060600160405280428152602001878152602001868152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020155505061316b60075482611927565b600781905550600b60009054906101000a900460ff1660ff16600d54106131b15760006131966132ec565b9150506131a960075482600101546110c2565b600781905550505b505050505050565b60006001600d5411156132d35760006131d06132ec565b50905060006131e34283600001546110c2565b90506000613235600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661348c565b5090506000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156132a9576132a284600101548885600154610cf7565b90506132be565b6132bb84600201548785600154610cf7565b90505b6132c88382612740565b9450505050506132d9565b60125490505b92915050565b6000818316905092915050565b60008060006132f96127c8565b90506006818154811061330857fe5b906000526020600020906003020192506009818154811061332557fe5b90600052602060002090600202019150509091565b6000818317905092915050565b6000640100000000428161335757fe5b06905090565b613365613603565b6000826dffffffffffffffffffffffffffff16116133eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f4669786564506f696e743a204449565f42595f5a45524f00000000000000000081525060200191505060405180910390fd5b6040518060200160405280836dffffffffffffffffffffffffffff16607060ff16866dffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168161346257fe5b047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415613514576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806137816025913960400191505060405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161061354e578284613551565b83835b8092508193505050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156135fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f556e697377617056324c6962726172793a205a45524f5f41444452455353000081525060200191505060405180910390fd5b9250929050565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b604051806020016040528060008152509056fe556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f706169722d616c72656164792d736574556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d636f6e7665727465722d66656564556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d64617461556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d6d61782d77696e646f772d73697a65556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d636f6e7665727465722d70726963652d66656564556e697377617056324c6962726172793a204944454e544943414c5f414444524553534553556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6d6f646966792d756e7265636f676e697a65642d706172616d556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d64656661756c742d616d6f756e742d696e556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6163636f756e742d6e6f742d617574686f72697a6564556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d756e69737761702d70616972556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d72656c61796572556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d64617461556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d74696d652d656c61707365644669786564506f696e743a204d554c5449504c49434154494f4e5f4f564552464c4f57556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d70726963652d66656564556e6973776170436f6e7665727465724261736963417665726167655072696365466565644d656469616e697a65722f696e76616c69642d656e642d63756d756c6174697665556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e6f742d656e6f7567682d74696d652d656c6170736564a2646970667358221220ccbab3eb4d1ee182532906f4fba117fb601846344316e3b4e2d7bd702ba7e5c664736f6c63430006070033556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f77696e646f772d6e6f742d6576656e6c792d646976697369626c65556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d6d61782d77696e646f772d73697a65556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d77696e646f772d73697a65556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d6772616e756c6172697479556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d64656661756c742d616d6f756e742d696e556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d756e69737761702d666163746f7279556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d666565642d7363616c696e672d666163746f720000000000000000000000005e2bc99c193c11024456115a5f868ac2d502dfb80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000070800000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000003
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061027f5760003560e01c806368a82ef61161015c578063bc3501e2116100ce578063d6e882dc11610087578063d6e882dc14610b0f578063dd2d2a1214610b65578063e4463eb214610bb1578063f6b9fdfb14610bcf578063f752fdc314610c19578063fe4f589014610c655761027f565b8063bc3501e214610a01578063bd9e799d14610a1f578063c5cb2dcc14610a6b578063c816841b14610a89578063c8f33c9114610ad3578063d4ef172214610af15761027f565b806394f3f81d1161012057806394f3f81d146108cd57806395d89b41146109115780639df055f51461092f578063a0685e841461094d578063a087163714610997578063b1940058146109e35761027f565b806368a82ef6146107df5780636a146024146107fd5780638406c0791461081b5780638a14117a146108655780638bdb2afa146108835761027f565b80633c8bb3e6116101f55780634fd0ada8116101b95780634fd0ada8146106bc57806354f363a3146106e5578063552033c414610731578063556f0dc71461074f57806357de26a4146107735780636614f010146107915761027f565b80633c8bb3e6146105805780633ef5e445146105cc57806341938b021461061857806346f3e81c14610636578063495df025146106785761027f565b806324ba58841161024757806324ba588414610407578063303aa80f1461045f57806331c9626a146104af578063327107f7146104cd57806335b28153146105175780633c3f91251461055b5761027f565b8063056640b7146102845780630ac91638146102d05780630d88ed89146103195780631021344714610379578063165c4a16146103bb575b600080fd5b6102ba6004803603604081101561029a57600080fd5b810190808035906020019092919080359060200190929190505050610c9d565b6040518082815260200191505060405180910390f35b6102fc600480360360208110156102e657600080fd5b8101908080359060200190929190505050610cc6565b604051808381526020018281526020019250505060405180910390f35b6103636004803603608081101561032f57600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190505050610cf7565b6040518082815260200191505060405180910390f35b6103a56004803603602081101561038f57600080fd5b8101908080359060200190929190505050610e1e565b6040518082815260200191505060405180910390f35b6103f1600480360360408110156103d157600080fd5b810190808035906020019092919080359060200190929190505050610e35565b6040518082815260200191505060405180910390f35b6104496004803603602081101561041d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610eca565b6040518082815260200191505060405180910390f35b61048b6004803603602081101561047557600080fd5b8101908080359060200190929190505050610ee2565b60405180848152602001838152602001828152602001935050505060405180910390f35b6104b7610f19565b6040518082815260200191505060405180910390f35b6104d5610f1f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105596004803603602081101561052d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f45565b005b610563611086565b604051808381526020018281526020019250505060405180910390f35b6105b66004803603604081101561059657600080fd5b81019080803590602001909291908035906020019092919050505061109d565b6040518082815260200191505060405180910390f35b610602600480360360408110156105e257600080fd5b8101908080359060200190929190803590602001909291905050506110c2565b6040518082815260200191505060405180910390f35b610620611145565b6040518082815260200191505060405180910390f35b6106626004803603602081101561064c57600080fd5b810190808035906020019092919050505061114b565b6040518082815260200191505060405180910390f35b6106ba6004803603602081101561068e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061116a565b005b6106c46118d1565b60405180838152602001821515151581526020019250505060405180910390f35b61071b600480360360408110156106fb57600080fd5b810190808035906020019092919080359060200190929190505050611927565b6040518082815260200191505060405180910390f35b6107396119aa565b6040518082815260200191505060405180910390f35b6107576119ba565b604051808260ff1660ff16815260200191505060405180910390f35b61077b6119cd565b6040518082815260200191505060405180910390f35b6107dd600480360360408110156107a757600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a74565b005b6107e7612502565b6040518082815260200191505060405180910390f35b610805612508565b6040518082815260200191505060405180910390f35b610823612514565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61086d61253a565b6040518082815260200191505060405180910390f35b61088b612540565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61090f600480360360208110156108e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612566565b005b6109196126a7565b6040518082815260200191505060405180910390f35b6109376126ad565b6040518082815260200191505060405180910390f35b6109556126b3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109cd600480360360408110156109ad57600080fd5b8101908080359060200190929190803590602001909291905050506126d9565b6040518082815260200191505060405180910390f35b6109eb612702565b6040518082815260200191505060405180910390f35b610a09612708565b6040518082815260200191505060405180910390f35b610a5560048036036040811015610a3557600080fd5b810190808035906020019092919080359060200190929190505050612740565b6040518082815260200191505060405180910390f35b610a736127c8565b6040518082815260200191505060405180910390f35b610a91612812565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610adb612838565b6040518082815260200191505060405180910390f35b610af961283e565b6040518082815260200191505060405180910390f35b610b4f60048036036060811015610b2557600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050612844565b6040518082815260200191505060405180910390f35b610b9b60048036036040811015610b7b57600080fd5b81019080803590602001909291908035906020019092919050505061290a565b6040518082815260200191505060405180910390f35b610bb9612924565b6040518082815260200191505060405180910390f35b610bd761292a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c4f60048036036040811015610c2f57600080fd5b810190808035906020019092919080359060200190929190505050612950565b6040518082815260200191505060405180910390f35b610c9b60048036036040811015610c7b57600080fd5b810190808035906020019092919080359060200190929190505050612975565b005b60006b033b2e3c9fd0803ce8000000610cb68484610e35565b81610cbd57fe5b04905092915050565b60098181548110610cd357fe5b90600052602060002090600202016000915090508060000154908060010154905082565b600084841015610d52576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806139b26046913960600191505060405180910390fd5b60008311610dab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180613916603c913960400191505060405180910390fd5b610db3613603565b60405180602001604052808588880381610dc957fe5b047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050610dff610dfa8285612c56565b612d2c565b71ffffffffffffffffffffffffffffffffffff16915050949350505050565b6000610e2e82633b9aca00610e35565b9050919050565b600080821480610e525750828283850292508281610e4f57fe5b04145b610ec4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f75696e742d75696e742d6d756c2d6f766572666c6f770000000000000000000081525060200191505060405180910390fd5b92915050565b60006020528060005260406000206000915090505481565b60068181548110610eef57fe5b90600052602060002090600302016000915090508060000154908060010154908060020154905083565b60135481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414610fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b60016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f599a298163e1678bb1c676052a8930bf0b8a1261ed6e01b8a2391e55f700010281604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600680549050600980549050915091509091565b6000670de0b6b3a76400006110b28484610e35565b816110b957fe5b04905092915050565b600081830390508281111561113f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f75696e742d75696e742d7375622d756e646572666c6f7700000000000000000081525060200191505060405180910390fd5b92915050565b600f5481565b6000611163826b033b2e3c9fd0803ce8000000610e35565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff16601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611212576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001806138ab6037913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156112ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c81526020018061386f603c913960400191505060405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146112f557816112f7565b335b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663495df025826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b15801561139a57600080fd5b505af19250505080156113ab575060015b611483573d80600081146113db576040519150601f19603f3d011682016040523d82523d6000602084013e6113e0565b606091505b507f321dc066db92f97ab7f8b6f080147cb31cc027a61c0b6c026f055a39009be70f816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611443578082015181840152602081019050611428565b50505050905090810190601f1680156114705780820380516001836020036101000a031916815260200191505b509250505060405180910390a150611484565b5b600080600680549050146114c7576114c2426006600160068054905003815481106114ab57fe5b9060005260206000209060030201600001546110c2565b6114d4565b6114d342600c546110c2565b5b9050600060068054905011156115405760105481101561153f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260428152602001806139f86042913960600191505060405180910390fd5b5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156115aa57600080fd5b505af19250505080156115bb575060015b611693573d80600081146115eb576040519150601f19603f3d011682016040523d82523d6000602084013e6115f0565b606091505b507ff64c46db4bf4aeeff8f4a6001e70e2e8cac802c514905f29bdd5659efc75b8b0816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611653578082015181840152602081019050611638565b50505050905090810190601f1680156116805780820380516001836020036101000a031916815260200191505b509250505060405180910390a150611694565b5b6000806116c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612d41565b50915091506116d2838383612f8c565b6116dc82826131b9565b60128190555042600c819055506116f6600d546001611927565b600d819055507ff85e44c6c3597d176b8d59bfbf500dfdb2badfc8cf91e6d960b16583a5807e48601254600c54604051808381526020018281526020019250505060405180910390a1601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d7fb67a856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156117e057600080fd5b505af19250505080156117f1575060015b6118c9573d8060008114611821576040519150601f19603f3d011682016040523d82523d6000602084013e611826565b606091505b507facc18fe32f7716216416b1673ee8570f5b04c7a4012a84d130f3221632003ad9816040518080602001828103825283818151815260200191508051906020019080838360005b8381101561188957808201518184015260208101905061186e565b50505050905090810190601f1680156118b65780820380516001836020036101000a031916815260200191505b509250505060405180910390a1506118ca565b5b5050505050565b60008060125461191f611914611902600060125411600b60009054906101000a900460ff1660ff16600d54116132df565b600f5461190d612708565b11156132df565b6001601354146132df565b915091509091565b60008183019050828110156119a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f75696e742d75696e742d6164642d6f766572666c6f770000000000000000000081525060200191505060405180910390fd5b92915050565b6b033b2e3c9fd0803ce800000081565b600b60009054906101000a900460ff1681565b6000611a17611a0c6119fa600060125411600b60009054906101000a900460ff1660ff16600d54116132df565b600f54611a05612708565b11156132df565b6001601354146132df565b611a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180613975603d913960400191505060405180910390fd5b601254905090565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414611b0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260348152602001806138e26034913960400191505060405180910390fd5b7f636f6e7665727465724665656400000000000000000000000000000000000000821415611c8557600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180613683603e913960400191505060405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612493565b7f746172676574546f6b656e00000000000000000000000000000000000000000082141561202b57600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611d54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180613648603b913960400191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461202657600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a43905600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015611f0257600080fd5b505afa158015611f16573d6000803e3d6000fd5b505050506040513d6020811015611f2c57600080fd5b8101908080519060200190929190505050600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415612025576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c81526020018061386f603c913960400191505060405180910390fd5b5b612492565b7f64656e6f6d696e6174696f6e546f6b656e0000000000000000000000000000008214156123d157600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b815260200180613648603b913960400191505060405180910390fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146123cc57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a43905600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b1580156122a857600080fd5b505afa1580156122bc573d6000803e3d6000fd5b505050506040513d60208110156122d257600080fd5b8101908080519060200190929190505050600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156123cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c81526020018061386f603c913960400191505060405180910390fd5b5b612491565b7f72656c617965720000000000000000000000000000000000000000000000000082141561243f5780601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612490565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001806137a66044913960600191505060405180910390fd5b5b5b5b7fd91f38cf03346b5dc15fb60f9076f866295231ad3c3841a1051f8443f25170d18282604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b600d5481565b670de0b6b3a764000081565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e5481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146125fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f8834a87e641e9716be4f34527af5d23e11624f1ddeefede6ad75a9acfc31b90381604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600a5481565b60075481565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000816126f2846b033b2e3c9fd0803ce8000000610e35565b816126f957fe5b04905092915050565b60115481565b60006001600d54111561273857600061271f6132ec565b5090506127304282600001546110c2565b91505061273d565b600090505b90565b600080831161279a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180613916603c913960400191505060405180910390fd5b600083600754816127a757fe5b0490506011546127b78483610e35565b816127be57fe5b0491505092915050565b6000600b60009054906101000a900460ff1660ff16600d54116127ee576000905061280f565b61280c600d54600b60009054906101000a900460ff1660ff166110c2565b90505b90565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c5481565b60015481565b600083600081146128ea57600284066000811461286357859250612867565b8392505b50600283046002850494505b84156128e457858602868782041461288a57600080fd5b8181018181101561289a57600080fd5b858104975060028706156128d75787850285898204141589151516156128bf57600080fd5b838101818110156128cf57600080fd5b878104965050505b5050600285049450612873565b50612902565b83600081146128fc5760009250612900565b8392505b505b509392505050565b60008183111561291a578161291c565b825b905092915050565b60105481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008161296584670de0b6b3a7640000610e35565b8161296c57fe5b04905092915050565b60016000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612a0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604181526020018061382e6041913960600191505060405180910390fd5b7f76616c6964697479466c61670000000000000000000000000000000000000000821415612aa557612a44600182146000831461333a565b612a99576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001806136c16037913960400191505060405180910390fd5b80601381905550612c13565b7f64656661756c74416d6f756e74496e0000000000000000000000000000000000821415612b325760008111612b26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001806137ea6044913960600191505060405180910390fd5b80600181905550612c12565b7f6d617857696e646f7753697a6500000000000000000000000000000000000000821415612bc057600e548111612bb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260428152602001806136f86042913960600191505060405180910390fd5b80600f81905550612c11565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260448152602001806137a66044913960600191505060405180910390fd5b5b5b7fac7c5c1afaef770ec56ac6268cd3f2fbb1035858ead2601d6553157c33036c3a8282604051808381526020018281526020019250505060405180910390a15050565b612c5e613634565b600080831480612cbf575083600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16838486600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160292508281612cbc57fe5b04145b612d14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806139526023913960400191505060405180910390fd5b60405180602001604052808281525091505092915050565b6000607060ff168260000151901c9050919050565b6000806000612d4e613347565b90508373ffffffffffffffffffffffffffffffffffffffff16635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b158015612d9657600080fd5b505afa158015612daa573d6000803e3d6000fd5b505050506040513d6020811015612dc057600080fd5b810190808051906020019092919050505092508373ffffffffffffffffffffffffffffffffffffffff16635a3d54936040518163ffffffff1660e01b815260040160206040518083038186803b158015612e1957600080fd5b505afa158015612e2d573d6000803e3d6000fd5b505050506040513d6020811015612e4357600080fd5b8101908080519060200190929190505050915060008060008673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612ea157600080fd5b505afa158015612eb5573d6000803e3d6000fd5b505050506040513d6060811015612ecb57600080fd5b810190808051906020019092919080519060200190929190805190602001909291905050509250925092508363ffffffff168163ffffffff1614612f8257600081850390508063ffffffff16612f21848661335d565b600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602870196508063ffffffff16612f59858561335d565b600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160286019550505b5050509193909250565b600080600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634fd0ada86040518163ffffffff1660e01b8152600401604080518083038186803b158015612ff657600080fd5b505afa15801561300a573d6000803e3d6000fd5b505050506040513d604081101561302057600080fd5b8101908080519060200190929190805190602001909291905050509150915080613095576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604781526020018061373a6047913960600191505060405180910390fd5b60006130a18387610e35565b9050600960405180604001604052804281526020018381525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010155505060066040518060600160405280428152602001878152602001868152509080600181540180825580915050600190039060005260206000209060030201600090919091909150600082015181600001556020820151816001015560408201518160020155505061316b60075482611927565b600781905550600b60009054906101000a900460ff1660ff16600d54106131b15760006131966132ec565b9150506131a960075482600101546110c2565b600781905550505b505050505050565b60006001600d5411156132d35760006131d06132ec565b50905060006131e34283600001546110c2565b90506000613235600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661348c565b5090506000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156132a9576132a284600101548885600154610cf7565b90506132be565b6132bb84600201548785600154610cf7565b90505b6132c88382612740565b9450505050506132d9565b60125490505b92915050565b6000818316905092915050565b60008060006132f96127c8565b90506006818154811061330857fe5b906000526020600020906003020192506009818154811061332557fe5b90600052602060002090600202019150509091565b6000818317905092915050565b6000640100000000428161335757fe5b06905090565b613365613603565b6000826dffffffffffffffffffffffffffff16116133eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f4669786564506f696e743a204449565f42595f5a45524f00000000000000000081525060200191505060405180910390fd5b6040518060200160405280836dffffffffffffffffffffffffffff16607060ff16866dffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168161346257fe5b047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415613514576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806137816025913960400191505060405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161061354e578284613551565b83835b8092508193505050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156135fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f556e697377617056324c6962726172793a205a45524f5f41444452455353000081525060200191505060405180910390fd5b9250929050565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b604051806020016040528060008152509056fe556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f706169722d616c72656164792d736574556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d636f6e7665727465722d66656564556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d64617461556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d6d61782d77696e646f772d73697a65556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d636f6e7665727465722d70726963652d66656564556e697377617056324c6962726172793a204944454e544943414c5f414444524553534553556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6d6f646966792d756e7265636f676e697a65642d706172616d556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d64656661756c742d616d6f756e742d696e556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6163636f756e742d6e6f742d617574686f72697a6564556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d756e69737761702d70616972556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d72656c61796572556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d64617461556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e756c6c2d74696d652d656c61707365644669786564506f696e743a204d554c5449504c49434154494f4e5f4f564552464c4f57556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f696e76616c69642d70726963652d66656564556e6973776170436f6e7665727465724261736963417665726167655072696365466565644d656469616e697a65722f696e76616c69642d656e642d63756d756c6174697665556e6973776170436f6e7365637574697665536c6f74735072696365466565644d656469616e697a65722f6e6f742d656e6f7567682d74696d652d656c6170736564a2646970667358221220ccbab3eb4d1ee182532906f4fba117fb601846344316e3b4e2d7bd702ba7e5c664736f6c63430006070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005e2bc99c193c11024456115a5f868ac2d502dfb80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000070800000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000003
-----Decoded View---------------
Arg [0] : converterFeed_ (address): 0x5e2bc99C193c11024456115A5f868AC2D502dfB8
Arg [1] : uniswapFactory_ (address): 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
Arg [2] : defaultAmountIn_ (uint256): 1000000000000000000
Arg [3] : windowSize_ (uint256): 28800
Arg [4] : converterFeedScalingFactor_ (uint256): 1000000000000000000
Arg [5] : maxWindowSize_ (uint256): 86400
Arg [6] : granularity_ (uint8): 3
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000005e2bc99c193c11024456115a5f868ac2d502dfb8
Arg [1] : 0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f
Arg [2] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000007080
Arg [4] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.