Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- TWAPOracle
- Optimization enabled
- true
- Compiler version
- v0.8.28+commit.7893614a
- Optimization runs
- 200
- EVM Version
- paris
- Verified at
- 2026-02-26T13:34:40.704177Z
Constructor Arguments
000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a270000000000000000000000008588dbbce840390435fcbd8e72c087ed1799a540
Arg [0] (address) : 0xa1077a294dde1b09bb078844df40758a5d0f9a27
Arg [1] (address) : 0x8588dbbce840390435fcbd8e72c087ed1799a540
TWAPOracle.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// --- Interfaces ---
interface IUniswapV2Pair {
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function token0() external view returns (address);
function token1() external view returns (address);
}
interface IERC20Decimals { function decimals() external view returns (uint8); }
interface ITWAPToken {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function mint(address to, uint amount) external;
}
// --- Libraries ---
library FixedPoint {
struct uq112x112 { uint224 _x; }
struct uq144x112 { uint _x; }
uint8 private constant RESOLUTION = 112;
function encode(uint112 x) internal pure returns (uq112x112 memory) {
return uq112x112(uint224(x) << RESOLUTION);
}
function mul(uq112x112 memory self, uint y) internal pure returns (uq144x112 memory) {
return uq144x112(self._x * y);
}
function fraction(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) {
if (denominator == 0) revert("FixedPoint: DIV_BY_ZERO");
return uq112x112((uint224(numerator) << RESOLUTION) / denominator);
}
function decode144(uq144x112 memory self) internal pure returns (uint144) {
return uint144(self._x >> RESOLUTION);
}
function rpow(uint x, uint n) internal pure returns (uint z) {
z = n % 2 != 0 ? x : 1e18;
for (n /= 2; n != 0; n /= 2) {
x = (x * x) / 1e18;
if (n % 2 != 0) z = (z * x) / 1e18;
}
}
}
library UniswapV2OracleLibrary {
using FixedPoint for *;
function currentBlockTimestamp() internal view returns (uint) { return block.timestamp; }
function currentCumulativePrices(address pair) internal view returns (uint price0Cumulative, uint price1Cumulative, uint blockTimestamp) {
blockTimestamp = currentBlockTimestamp();
price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast();
price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast();
(uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IUniswapV2Pair(pair).getReserves();
if (blockTimestampLast != blockTimestamp) {
uint32 timeElapsed = uint32(blockTimestamp - blockTimestampLast);
unchecked {
price0Cumulative += uint(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed;
price1Cumulative += uint(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed;
}
}
}
struct PriceData { uint price0Cumulative; uint price1Cumulative; }
function batchCumulativePrices(address[] memory pairs) internal view returns (PriceData[] memory prices, uint blockTimestamp) {
blockTimestamp = currentBlockTimestamp();
prices = new PriceData[](pairs.length);
for (uint i; i < pairs.length; ) {
IUniswapV2Pair pair = IUniswapV2Pair(pairs[i]);
uint price0Cumulative = pair.price0CumulativeLast();
uint price1Cumulative = pair.price1CumulativeLast();
(uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = pair.getReserves();
if (blockTimestampLast != blockTimestamp) {
uint32 timeElapsed = uint32(blockTimestamp - blockTimestampLast);
unchecked {
price0Cumulative += uint(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed;
price1Cumulative += uint(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed;
}
}
prices[i] = PriceData(price0Cumulative, price1Cumulative);
unchecked { ++i; }
}
}
}
// --- Oracle Contract ---
contract TWAPOracle {
using FixedPoint for *;
struct Observation { uint timestamp; uint price0Cumulative; uint price1Cumulative; }
struct ReferenceStable { address stable; address pair; bool isWplsToken0; uint8 stableDecimals; bool active; }
struct PairInfo { address pair; bool isToken0; }
// Errors
error UnknownPair(); error PairAlreadyAdded(); error InvalidPair(); error InvalidTWAPWindow();
error Unauthorized(); error PeriodNotElapsed(); error RewardsNotEnabled(); error InsufficientBalanceForReward();
error AlreadyLaunched(); error NoValidReferences(); error StalePrice(); error InsufficientObservations(); error InvalidIndex();
address public immutable wpls;
ITWAPToken public immutable twapToken; // The separated token
mapping(address => uint) public wards;
function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
modifier auth() { if (wards[msg.sender] != 1) revert Unauthorized(); _; }
bool public rewardsEnabled;
// Constants (Using the responsive 15m settings)
uint public constant PERIOD_SIZE = 900;
uint public constant MIN_WINDOW = 900;
uint public constant MAX_WINDOW = 7200;
uint public constant REWARD_WINDOW = 1350;
uint public constant DECAY_RATE = 500000000000000000; // 0.5
uint public constant DECAY_PERIOD = 225;
// Reward Config
uint public constant BASE_REWARD_RATE = 13888888888888888;
uint public constant INITIAL_SUPPLY = 1_000_000 * 10 ** 18;
uint public constant MIN_HOLDING_DIVISOR = 555;
// State
mapping(address => Observation[5]) public observations;
mapping(address => uint8) public observationHeads;
address[] public livePairs;
mapping(address => PairInfo) public tokenToPairInfo;
address[] public pricedTokens;
ReferenceStable[] public referenceStables;
uint public lastSuperUpdateTimestamp;
// Events
event PriceUpdated(address indexed token, address indexed pair, uint price0Cumulative, uint price1Cumulative, uint timestamp);
event Reward(address indexed updater, uint amount);
event RewardsLaunched();
event Rely(address indexed usr);
event Deny(address indexed usr);
event ReferenceAdded(address indexed stable, address indexed pair, bool isWplsToken0, uint8 stableDecimals);
event ReferenceUpdated(uint indexed index, bool active);
event ReferenceRemoved(uint indexed index, address indexed pair);
event DirectPairAdded(address indexed token, address indexed pair, bool isToken0);
event DirectPairRemoved(address indexed token);
event SuperUpdate(uint timestamp, uint updatedPairs);
constructor(address _wpls, address _twapToken) {
wpls = _wpls;
twapToken = ITWAPToken(_twapToken);
wards[msg.sender] = 1;
emit Rely(msg.sender);
}
// --- Views ---
function getMinHoldingForReward() public view returns (uint) {
return twapToken.totalSupply() / MIN_HOLDING_DIVISOR;
}
function launch() external auth {
if (rewardsEnabled) revert AlreadyLaunched();
rewardsEnabled = true;
emit RewardsLaunched();
}
// --- Admin Logic ---
function _isPairLive(address pair) internal view returns (bool) {
for (uint i = 0; i < livePairs.length; i++) {
if (livePairs[i] == pair) return true;
}
return false;
}
function addReferenceStable(address stable, address pair, bool isWplsToken0) external auth {
address token0 = IUniswapV2Pair(pair).token0();
address token1 = IUniswapV2Pair(pair).token1();
if ((isWplsToken0 && token0 != wpls) || (!isWplsToken0 && token1 != wpls)) revert InvalidPair();
if (stable != token0 && stable != token1) revert InvalidPair();
uint8 stableDecimals = IERC20Decimals(stable).decimals();
if (stableDecimals > 18) revert("Stable decimals >18");
referenceStables.push(ReferenceStable(stable, pair, isWplsToken0, stableDecimals, true));
if (!_isPairLive(pair)) {
if (observationHeads[pair] == 0) {
(uint price0Cumulative, uint price1Cumulative, ) = UniswapV2OracleLibrary.currentCumulativePrices(pair);
observations[pair][0] = Observation(block.timestamp, price0Cumulative, price1Cumulative);
observationHeads[pair] = 1;
}
livePairs.push(pair);
}
emit ReferenceAdded(stable, pair, isWplsToken0, stableDecimals);
}
function updateReference(uint index, bool active) external auth {
if (index >= referenceStables.length) revert("Invalid index");
referenceStables[index].active = active;
emit ReferenceUpdated(index, active);
}
function addDirectPair(address token, address pair, bool isToken0) external auth {
if (tokenToPairInfo[token].pair != address(0)) revert PairAlreadyAdded();
address token0 = IUniswapV2Pair(pair).token0();
address token1 = IUniswapV2Pair(pair).token1();
if ((isToken0 && token0 != token) || (!isToken0 && token1 != token)) revert InvalidPair();
tokenToPairInfo[token] = PairInfo(pair, isToken0);
pricedTokens.push(token);
if (!_isPairLive(pair)) {
if (observationHeads[pair] == 0) {
(uint price0Cumulative, uint price1Cumulative, ) = UniswapV2OracleLibrary.currentCumulativePrices(pair);
observations[pair][0] = Observation(block.timestamp, price0Cumulative, price1Cumulative);
observationHeads[pair] = 1;
}
livePairs.push(pair);
}
emit DirectPairAdded(token, pair, isToken0);
}
function removeDirectPair(address token) external auth {
PairInfo memory info = tokenToPairInfo[token];
if (info.pair == address(0)) revert UnknownPair();
delete tokenToPairInfo[token];
for (uint i = 0; i < pricedTokens.length; i++) {
if (pricedTokens[i] == token) { pricedTokens[i] = pricedTokens[pricedTokens.length - 1]; pricedTokens.pop(); break; }
}
address pair = info.pair;
bool isStillReference = false;
for (uint i = 0; i < referenceStables.length; i++) {
if (referenceStables[i].pair == pair) { isStillReference = true; break; }
}
if (!isStillReference) {
_removeLivePair(pair);
delete observations[pair];
delete observationHeads[pair];
}
emit DirectPairRemoved(token);
}
function removeReferenceStable(uint index) external auth {
if (index >= referenceStables.length) revert InvalidIndex();
address pair = referenceStables[index].pair;
referenceStables[index] = referenceStables[referenceStables.length - 1];
referenceStables.pop();
bool isStillUsed = false;
for (uint i = 0; i < pricedTokens.length; i++) {
if (tokenToPairInfo[pricedTokens[i]].pair == pair) { isStillUsed = true; break; }
}
if (!isStillUsed) {
for (uint i = 0; i < referenceStables.length; i++) {
if (referenceStables[i].pair == pair) { isStillUsed = true; break; }
}
}
if (!isStillUsed) {
_removeLivePair(pair);
delete observations[pair];
delete observationHeads[pair];
}
emit ReferenceRemoved(index, pair);
}
function _removeLivePair(address pair) internal {
for (uint i = 0; i < livePairs.length; i++) {
if (livePairs[i] == pair) { livePairs[i] = livePairs[livePairs.length - 1]; livePairs.pop(); break; }
}
}
// --- Core Logic ---
function superUpdate() public {
uint currentTimestamp = block.timestamp;
if (currentTimestamp - lastSuperUpdateTimestamp < MIN_WINDOW) revert PeriodNotElapsed();
uint totalPairs = livePairs.length;
address[] memory pairsToUpdate = new address[](totalPairs);
uint updateCount = 0;
for (uint i = 0; i < totalPairs; ) {
address pair = livePairs[i];
uint8 head = observationHeads[pair];
uint8 lastIdx = (head == 0) ? 4 : head - 1;
if (currentTimestamp - observations[pair][lastIdx].timestamp >= PERIOD_SIZE) {
pairsToUpdate[updateCount] = pair;
unchecked { ++updateCount; }
}
unchecked { ++i; }
}
if (updateCount > 0) {
address[] memory activeBatch = new address[](updateCount);
for (uint i = 0; i < updateCount; i++) { activeBatch[i] = pairsToUpdate[i]; }
(UniswapV2OracleLibrary.PriceData[] memory prices, ) = UniswapV2OracleLibrary.batchCumulativePrices(activeBatch);
for (uint i = 0; i < updateCount; i++) { _applyUpdate(activeBatch[i], prices[i], currentTimestamp); }
if (rewardsEnabled && twapToken.balanceOf(msg.sender) >= getMinHoldingForReward()) {
uint reward = calculateReward(currentTimestamp);
if (reward > 0) _mintReward(msg.sender, reward);
}
}
lastSuperUpdateTimestamp = currentTimestamp;
emit SuperUpdate(currentTimestamp, updateCount);
}
function _applyUpdate(address pair, UniswapV2OracleLibrary.PriceData memory price, uint blockTimestamp) private {
uint8 head = observationHeads[pair];
observations[pair][head] = Observation(blockTimestamp, price.price0Cumulative, price.price1Cumulative);
observationHeads[pair] = (head + 1) % 5;
emit PriceUpdated(address(0), pair, price.price0Cumulative, price.price1Cumulative, blockTimestamp);
}
function getMedianPrice(address pair, bool needPrice0, uint currentCumulative, uint currentTimestamp) internal view returns (uint224 medianPrice) {
Observation[5] memory obsArray;
for(uint i=0; i<5; i++) { obsArray[i] = observations[pair][i]; }
for (uint i = 1; i < 5; ) {
Observation memory key = obsArray[i]; uint j = i;
while (j > 0 && obsArray[j-1].timestamp < key.timestamp) { obsArray[j] = obsArray[j-1]; j--; }
obsArray[j] = key; unchecked { ++i; }
}
uint224[] memory segmentPrices = new uint224[](5);
uint count = 0; uint prevCum = currentCumulative; uint prevTs = currentTimestamp;
for (uint i = 0; i < 5; i++) {
if (obsArray[i].timestamp == 0) continue;
uint timeElapsed = prevTs - obsArray[i].timestamp;
if (timeElapsed < MIN_WINDOW || timeElapsed > MAX_WINDOW) continue;
uint obsCum = needPrice0 ? obsArray[i].price0Cumulative : obsArray[i].price1Cumulative;
uint segmentTWAP = (prevCum - obsCum) / timeElapsed;
segmentPrices[count] = uint224(segmentTWAP); count++;
prevCum = obsCum; prevTs = obsArray[i].timestamp;
if (count >= 3) break; // Rolling Window
}
if (count < 3) revert InsufficientObservations();
for (uint i = 1; i < count; ) {
uint224 key = segmentPrices[i]; uint j = i;
while (j > 0 && segmentPrices[j - 1] > key) { segmentPrices[j] = segmentPrices[j - 1]; j--; }
segmentPrices[j] = key; unchecked { ++i; }
}
if (count % 2 == 1) { medianPrice = segmentPrices[count / 2]; }
else { medianPrice = (segmentPrices[count / 2 - 1] + segmentPrices[count / 2]) / 2; }
}
function _getNormalizedPriceFromRef(ReferenceStable memory ref) internal view returns (uint priceNormalized) {
(uint112 reserve0, uint112 reserve1, ) = IUniswapV2Pair(ref.pair).getReserves();
uint wplsReserve = ref.isWplsToken0 ? uint(reserve0) : uint(reserve1);
if (wplsReserve == 0) return 0;
(uint price0Cumulative, uint price1Cumulative, uint blockTimestamp) = UniswapV2OracleLibrary.currentCumulativePrices(ref.pair);
bool needPrice0 = ref.isWplsToken0;
uint224 medianPrice = getMedianPrice(ref.pair, needPrice0, needPrice0 ? price0Cumulative : price1Cumulative, blockTimestamp);
uint scalar = 1e18 * (10 ** (18 - ref.stableDecimals));
FixedPoint.uq144x112 memory fullPrice = FixedPoint.uq112x112(medianPrice).mul(scalar);
priceNormalized = fullPrice._x >> 112;
}
function getWplsPriceInUsd() public view returns (uint priceWad) {
uint validCount = 0; uint[] memory prices = new uint[](referenceStables.length);
for (uint i = 0; i < referenceStables.length; i++) {
ReferenceStable memory ref = referenceStables[i];
if (!ref.active) continue;
uint price = _getNormalizedPriceFromRef(ref);
if (price == 0) continue;
prices[validCount] = price; validCount++;
}
if (validCount == 0) revert NoValidReferences();
for (uint i = 0; i < validCount; i++) {
for (uint j = i + 1; j < validCount; j++) {
if (prices[i] > prices[j]) { uint temp = prices[i]; prices[i] = prices[j]; prices[j] = temp; }
}
}
if (validCount % 2 == 1) { priceWad = prices[validCount / 2]; }
else { priceWad = (prices[validCount / 2 - 1] + prices[validCount / 2]) / 2; }
}
function getPriceInUsd(address token, uint amountIn) public view returns (uint amountOutUsd) {
if (token == wpls) { return (amountIn * getWplsPriceInUsd()) / 1e18; }
PairInfo memory info = tokenToPairInfo[token];
if (info.pair != address(0)) {
(uint price0Cumulative, uint price1Cumulative, uint blockTimestamp) = UniswapV2OracleLibrary.currentCumulativePrices(info.pair);
uint224 medianPrice = getMedianPrice(info.pair, info.isToken0, info.isToken0 ? price0Cumulative : price1Cumulative, blockTimestamp);
FixedPoint.uq144x112 memory temp = FixedPoint.uq112x112(medianPrice).mul(amountIn);
uint amountInWpls = temp._x >> 112;
amountOutUsd = (amountInWpls * getWplsPriceInUsd()) / 1e18;
} else { revert UnknownPair(); }
}
// --- Rewards ---
function _mintReward(address updater, uint reward) private {
if (!rewardsEnabled) revert RewardsNotEnabled();
if (reward == 0) return;
twapToken.mint(updater, reward); // Calls the external token contract
emit Reward(updater, reward);
}
function calculateReward(uint currentTime) internal view returns (uint) {
if (!rewardsEnabled) return 0;
uint timeSinceLast = currentTime - lastSuperUpdateTimestamp;
if (timeSinceLast < MIN_WINDOW) return 0;
uint effectiveTime = timeSinceLast - MIN_WINDOW;
uint peakEffectiveTime = REWARD_WINDOW - MIN_WINDOW;
uint timeBasedReward;
if (effectiveTime <= peakEffectiveTime) {
timeBasedReward = BASE_REWARD_RATE * effectiveTime;
} else {
uint cappedExtra = effectiveTime - peakEffectiveTime;
uint decayIntervals = cappedExtra / DECAY_PERIOD;
uint decayFactor = FixedPoint.rpow(DECAY_RATE, decayIntervals);
uint peakReward = BASE_REWARD_RATE * peakEffectiveTime;
timeBasedReward = (peakReward * decayFactor) / 1e18;
}
uint supplyFactor = 1e18;
uint currentSupply = twapToken.totalSupply(); // Read from external token
if (currentSupply > INITIAL_SUPPLY) {
uint a = INITIAL_SUPPLY; uint b = currentSupply;
supplyFactor = (2 * a * 1e18) / (a + b);
}
return (timeBasedReward * supplyFactor) / 1e18;
}
function getTokens() external view returns (address[] memory) { return pricedTokens; }
function getReferenceCount() external view returns (uint) { return referenceStables.length; }
function getPricedTokenCount() external view returns (uint) { return pricedTokens.length; }
function getCurrentReward() external view returns (uint) { return calculateReward(block.timestamp); }
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"paris","compilationTarget":{"TWAPOracle.sol":"TWAPOracle"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_wpls","internalType":"address"},{"type":"address","name":"_twapToken","internalType":"address"}]},{"type":"error","name":"AlreadyLaunched","inputs":[]},{"type":"error","name":"InsufficientBalanceForReward","inputs":[]},{"type":"error","name":"InsufficientObservations","inputs":[]},{"type":"error","name":"InvalidIndex","inputs":[]},{"type":"error","name":"InvalidPair","inputs":[]},{"type":"error","name":"InvalidTWAPWindow","inputs":[]},{"type":"error","name":"NoValidReferences","inputs":[]},{"type":"error","name":"PairAlreadyAdded","inputs":[]},{"type":"error","name":"PeriodNotElapsed","inputs":[]},{"type":"error","name":"RewardsNotEnabled","inputs":[]},{"type":"error","name":"StalePrice","inputs":[]},{"type":"error","name":"Unauthorized","inputs":[]},{"type":"error","name":"UnknownPair","inputs":[]},{"type":"event","name":"Deny","inputs":[{"type":"address","name":"usr","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"DirectPairAdded","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"address","name":"pair","internalType":"address","indexed":true},{"type":"bool","name":"isToken0","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"DirectPairRemoved","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PriceUpdated","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"address","name":"pair","internalType":"address","indexed":true},{"type":"uint256","name":"price0Cumulative","internalType":"uint256","indexed":false},{"type":"uint256","name":"price1Cumulative","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ReferenceAdded","inputs":[{"type":"address","name":"stable","internalType":"address","indexed":true},{"type":"address","name":"pair","internalType":"address","indexed":true},{"type":"bool","name":"isWplsToken0","internalType":"bool","indexed":false},{"type":"uint8","name":"stableDecimals","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"ReferenceRemoved","inputs":[{"type":"uint256","name":"index","internalType":"uint256","indexed":true},{"type":"address","name":"pair","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ReferenceUpdated","inputs":[{"type":"uint256","name":"index","internalType":"uint256","indexed":true},{"type":"bool","name":"active","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"Rely","inputs":[{"type":"address","name":"usr","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Reward","inputs":[{"type":"address","name":"updater","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsLaunched","inputs":[],"anonymous":false},{"type":"event","name":"SuperUpdate","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false},{"type":"uint256","name":"updatedPairs","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"BASE_REWARD_RATE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DECAY_PERIOD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DECAY_RATE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"INITIAL_SUPPLY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_WINDOW","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_HOLDING_DIVISOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_WINDOW","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"PERIOD_SIZE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"REWARD_WINDOW","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addDirectPair","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"pair","internalType":"address"},{"type":"bool","name":"isToken0","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addReferenceStable","inputs":[{"type":"address","name":"stable","internalType":"address"},{"type":"address","name":"pair","internalType":"address"},{"type":"bool","name":"isWplsToken0","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deny","inputs":[{"type":"address","name":"usr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMinHoldingForReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amountOutUsd","internalType":"uint256"}],"name":"getPriceInUsd","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amountIn","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPricedTokenCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getReferenceCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getTokens","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"priceWad","internalType":"uint256"}],"name":"getWplsPriceInUsd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastSuperUpdateTimestamp","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"launch","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"livePairs","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"observationHeads","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"timestamp","internalType":"uint256"},{"type":"uint256","name":"price0Cumulative","internalType":"uint256"},{"type":"uint256","name":"price1Cumulative","internalType":"uint256"}],"name":"observations","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pricedTokens","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"stable","internalType":"address"},{"type":"address","name":"pair","internalType":"address"},{"type":"bool","name":"isWplsToken0","internalType":"bool"},{"type":"uint8","name":"stableDecimals","internalType":"uint8"},{"type":"bool","name":"active","internalType":"bool"}],"name":"referenceStables","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rely","inputs":[{"type":"address","name":"usr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeDirectPair","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeReferenceStable","inputs":[{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"rewardsEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"superUpdate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"pair","internalType":"address"},{"type":"bool","name":"isToken0","internalType":"bool"}],"name":"tokenToPairInfo","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ITWAPToken"}],"name":"twapToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateReference","inputs":[{"type":"uint256","name":"index","internalType":"uint256"},{"type":"bool","name":"active","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"wards","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"wpls","inputs":[]}]
Contract Creation Code
0x60c060405234801561001057600080fd5b506040516136f83803806136f883398101604081905261002f9161009e565b6001600160a01b03808316608052811660a0523360008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250506100d1565b80516001600160a01b038116811461009957600080fd5b919050565b600080604083850312156100b157600080fd5b6100ba83610082565b91506100c860208401610082565b90509250929050565b60805160a0516135d16101276000396000818161049a01528181610af301528181610e8f015281816122730152612750015260008181610366015281816113cf015281816114150152611a4a01526135d16000f3fe608060405234801561001057600080fd5b506004361061021c5760003560e01c80639586a54211610125578063cdd00f69116100ad578063d525ed091161007c578063d525ed09146104cf578063deb96634146104e2578063e5831dca146104eb578063e837d9a9146104fe578063fc9654ab1461030e57600080fd5b8063cdd00f691461047a578063d0578a0114610482578063d2b8a22914610495578063d2fd9f6c146104bc57600080fd5b8063aa6ca808116100f4578063aa6ca808146103cb578063b1d06528146103e0578063b5fcf194146103f3578063bf353dbb14610406578063bf608cce1461042657600080fd5b80639586a542146103a05780639c52a7f1146103a85780639e5702be146103bb578063a4ef1357146103c357600080fd5b80632ff2e9dc116101a857806365fae35e1161017757806365fae35e1461032a5780636b598bbe1461033d578063802fe35d146103505780638aec854214610359578063927ef7fa1461036157600080fd5b80632ff2e9dc146102f55780634ae7ee1d1461030657806352b65c4b1461030e57806362e2c8481461031757600080fd5b80631c0541bd116101ef5780631c0541bd146102835780631dafe16b146102b85780631de40e49146102d55780631e9d4904146102e45780632cefe72c146102ec57600080fd5b806301339c2114610221578063024599661461022b5780630e40fe9f1461025e5780630e8e81271461027a575b600080fd5b61022961054e565b005b61023e610239366004613103565b6105d8565b604080519384526020840192909252908201526060015b60405180910390f35b61026c663157def08c0e3881565b604051908152602001610255565b61026c61054681565b6102a661029136600461312f565b60036020526000908152604090205460ff1681565b60405160ff9091168152602001610255565b6001546102c59060ff1681565b6040519015158152602001610255565b61026c6706f05b59d3b2000081565b61026c60e181565b61026c61022b81565b61026c69d3c21bcecceda100000081565b60065461026c565b61026c61038481565b610229610325366004613168565b61060e565b61022961033836600461312f565b6106ff565b61022961034b366004613194565b610773565b61026c60085481565b61026c610adc565b6103887f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610255565b61026c610aec565b6102296103b636600461312f565b610b7d565b610229610bf0565b61026c610f70565b6103d3611268565b60405161025591906131db565b6102296103ee366004613194565b6112ca565b61022961040136600461312f565b6117ae565b61026c61041436600461312f565b60006020819052908152604090205481565b61045b61043436600461312f565b6005602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610255565b60075461026c565b61026c610490366004613103565b611a46565b6103887f000000000000000000000000000000000000000000000000000000000000000081565b6103886104ca366004613227565b611bb7565b6103886104dd366004613227565b611be1565b61026c611c2081565b6102296104f9366004613227565b611bf1565b61051161050c366004613227565b611f14565b604080516001600160a01b0396871681529590941660208601529115159284019290925260ff90911660608301521515608082015260a001610255565b3360009081526020819052604090205460011461057d576040516282b42960e81b815260040160405180910390fd5b60015460ff16156105a1576040516319f4db0f60e31b815260040160405180910390fd5b6001805460ff1916811790556040517fa4d24b6714a5db779b2a933bdca578dbf6e9380ae4de745e84d4a6dd457204d590600090a1565b600260205281600052604060002081600581106105f457600080fd5b600302018054600182015460029092015490935090915083565b3360009081526020819052604090205460011461063d576040516282b42960e81b815260040160405180910390fd5b60075482106106835760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064015b60405180910390fd5b806007838154811061069757610697613240565b906000526020600020906002020160010160166101000a81548160ff021916908315150217905550817f1023261e84bada852098da9e423248e8fc3184408932bed6e2050195c13cfad9826040516106f3911515815260200190565b60405180910390a25050565b3360009081526020819052604090205460011461072e576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b336000908152602081905260409020546001146107a2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0383811660009081526005602052604090205416156107db5760405163a5d832e360e01b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083f9190613256565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a59190613256565b90508280156108c65750846001600160a01b0316826001600160a01b031614155b806108ec5750821580156108ec5750846001600160a01b0316816001600160a01b031614155b1561090a57604051630793df6360e21b815260040160405180910390fd5b6040805180820182526001600160a01b0380871682528515156020808401918252898316600081815260059092529481209351845492511515600160a01b026001600160a81b0319909316931692909217179091556006805460018101825591527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b03191690911790556109a784611f6f565b610a86576001600160a01b03841660009081526003602052604081205460ff169003610a3a576000806109d986611fce565b506040805160608101825242815260208082019485528183019384526001600160a01b038b16600090815260028083528482209351845595516001808501919091559451929095019190915560039052909120805460ff1916909117905550505b600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0386161790555b836001600160a01b0316856001600160a01b03167f5b99e368449b8061a5e6c9aa2ba8d3557d64befc230df2b329603e412e721abb85604051610acd911515815260200190565b60405180910390a35050505050565b6000610ae742612179565b905090565b600061022b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b739190613273565b610ae791906132b8565b33600090815260208190526040902054600114610bac576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b600854429061038490610c0390836132cc565b1015610c225760405163f0aaee6560e01b815260040160405180910390fd5b60045460008167ffffffffffffffff811115610c4057610c406132df565b604051908082528060200260200182016040528015610c69578160200160208202803683370190505b5090506000805b83811015610d6057600060048281548110610c8d57610c8d613240565b60009182526020808320909101546001600160a01b03168083526003909152604082205490925060ff16908115610cce57610cc96001836132f5565b610cd1565b60045b6001600160a01b03841660009081526002602052604090209091506103849060ff831660058110610d0457610d04613240565b6003020154610d13908a6132cc565b10610d525782868681518110610d2b57610d2b613240565b60200260200101906001600160a01b031690816001600160a01b0316815250508460010194505b836001019350505050610c70565b508015610f2c5760008167ffffffffffffffff811115610d8257610d826132df565b604051908082528060200260200182016040528015610dab578160200160208202803683370190505b50905060005b82811015610e0557838181518110610dcb57610dcb613240565b6020026020010151828281518110610de557610de5613240565b6001600160a01b0390921660209283029190910190910152600101610db1565b506000610e1182612372565b50905060005b83811015610e6457610e5c838281518110610e3457610e34613240565b6020026020010151838381518110610e4e57610e4e613240565b6020026020010151896125ea565b600101610e17565b5060015460ff168015610f055750610e7a610aec565b6040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610ede573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f029190613273565b10155b15610f29576000610f1587612179565b90508015610f2757610f2733826126fb565b505b50505b600884905560408051858152602081018390527f3a00c122e9fd49a4a88111ff00ae627346ec777223f410d9c595b32348ca4958910160405180910390a150505050565b6007546000908190819067ffffffffffffffff811115610f9257610f926132df565b604051908082528060200260200182016040528015610fbb578160200160208202803683370190505b50905060005b6007548110156110b157600060078281548110610fe057610fe0613240565b60009182526020918290206040805160a081018252600290930290910180546001600160a01b0390811684526001909101549081169383019390935260ff600160a01b84048116151591830191909152600160a81b830481166060830152600160b01b90920490911615156080820181905290915061105f57506110a9565b600061106a826127e7565b90508060000361107b5750506110a9565b8084868151811061108e5761108e613240565b6020908102919091010152846110a38161330e565b95505050505b600101610fc1565b50816000036110d357604051630f5ac0cb60e01b815260040160405180910390fd5b60005b828110156111b85760006110eb826001613327565b90505b838110156111af5782818151811061110857611108613240565b602002602001015183838151811061112257611122613240565b602002602001015111156111a757600083838151811061114457611144613240565b6020026020010151905083828151811061116057611160613240565b602002602001015184848151811061117a5761117a613240565b6020026020010181815250508084838151811061119957611199613240565b602002602001018181525050505b6001016110ee565b506001016110d6565b506111c460028361333a565b6001036111f657806111d76002846132b8565b815181106111e7576111e7613240565b60200260200101519250505090565b60028161120382856132b8565b8151811061121357611213613240565b602002602001015182600160028661122b91906132b8565b61123591906132cc565b8151811061124557611245613240565b60200260200101516112579190613327565b61126191906132b8565b9250505090565b606060068054806020026020016040519081016040528092919081815260200182805480156112c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112a2575b5050505050905090565b336000908152602081905260409020546001146112f9576040516282b42960e81b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611339573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061135d9190613256565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561139f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c39190613256565b905082801561140457507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b8061144a57508215801561144a57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614155b1561146857604051630793df6360e21b815260040160405180910390fd5b816001600160a01b0316856001600160a01b03161415801561149c5750806001600160a01b0316856001600160a01b031614155b156114ba57604051630793df6360e21b815260040160405180910390fd5b6000856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151e919061334e565b905060128160ff16111561156a5760405162461bcd60e51b81526020600482015260136024820152720a6e8c2c4d8ca40c8cac6d2dac2d8e6407c627606b1b604482015260640161067a565b6040805160a0810182526001600160a01b0380891682528781166020830190815287151593830193845260ff80861660608501908152600160808601818152600780549283018155600052955160029091027fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688810180549287166001600160a01b03199093169290921790915592517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68990930180549651915195511515600160b01b0260ff60b01b1996909316600160a81b029590951661ffff60a81b19911515600160a01b026001600160a81b0319909716939094169290921794909417161791909117905561167a85611f6f565b611759576001600160a01b03851660009081526003602052604081205460ff16900361170d576000806116ac87611fce565b506040805160608101825242815260208082019485528183019384526001600160a01b038c16600090815260028083528482209351845595516001808501919091559451929095019190915560039052909120805460ff1916909117905550505b600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0387161790555b60408051851515815260ff831660208201526001600160a01b0380881692908916917f5c235f9dae8874242a4334347008c0a971ff3e006b75b4444854aadda93f5fa5910160405180910390a3505050505050565b336000908152602081905260409020546001146117dd576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03818116600090815260056020908152604091829020825180840190935254928316808352600160a01b90930460ff161515908201529061183857604051633fb801a560e21b815260040160405180910390fd5b6001600160a01b038216600090815260056020526040812080546001600160a81b03191690555b60065481101561195a57826001600160a01b03166006828154811061188657611886613240565b6000918252602090912001546001600160a01b03160361195257600680546118b0906001906132cc565b815481106118c0576118c0613240565b600091825260209091200154600680546001600160a01b0390921691839081106118ec576118ec613240565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600680548061192b5761192b613371565b600082815260209020810160001990810180546001600160a01b031916905501905561195a565b60010161185f565b5080516000805b6007548110156119bb57826001600160a01b03166007828154811061198857611988613240565b60009182526020909120600160029092020101546001600160a01b0316036119b357600191506119bb565b600101611961565b5080611a0c576119ca82612944565b6001600160a01b03821660009081526002602052604081206119eb9161306d565b6001600160a01b0382166000908152600360205260409020805460ff191690555b6040516001600160a01b038516907fd4bab7746d82129d0d621d803f51fe4b9961fe75c4ddfb9537ebd8f5fa283be790600090a250505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611aad57670de0b6b3a7640000611a92610f70565b611a9c9084613387565b611aa691906132b8565b9050611bb1565b6001600160a01b03838116600090815260056020908152604091829020825180840190935254928316808352600160a01b90930460ff161515908201529015611b96576000806000611b028460000151611fce565b9250925092506000611b2e856000015186602001518760200151611b265785611b28565b865b85612a45565b90506000611b5c886040518060200160405280856001600160e01b0316815250612ee690919063ffffffff16565b805190915060701c670de0b6b3a7640000611b75610f70565b611b7f9083613387565b611b8991906132b8565b9750505050505050611baf565b604051633fb801a560e21b815260040160405180910390fd5b505b92915050565b60068181548110611bc757600080fd5b6000918252602090912001546001600160a01b0316905081565b60048181548110611bc757600080fd5b33600090815260208190526040902054600114611c20576040516282b42960e81b815260040160405180910390fd5b6007548110611c42576040516363df817160e01b815260040160405180910390fd5b600060078281548110611c5757611c57613240565b600091825260209091206001600290920201810154600780546001600160a01b03909216935091611c87916132cc565b81548110611c9757611c97613240565b906000526020600020906002020160078381548110611cb857611cb8613240565b60009182526020909120825460029092020180546001600160a01b039283166001600160a01b031991821617825560019384018054949092018054949093169084168117835581546001600160a81b031990941617600160a01b9384900460ff908116151590940217808355815460ff60a81b198216600160a81b9182900486169091029081178455915461ffff60a81b1990911660ff60b01b1990921691909117600160b01b918290049093161515029190911790556007805480611d8057611d80613371565b60008281526020812060026000199093019283020180546001600160a01b031916815560010180546001600160b81b03191690559155805b600654811015611e2457826001600160a01b03166005600060068481548110611de357611de3613240565b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541603611e1c5760019150611e24565b600101611db8565b5080611e895760005b600754811015611e8757826001600160a01b031660078281548110611e5457611e54613240565b60009182526020909120600160029092020101546001600160a01b031603611e7f5760019150611e87565b600101611e2d565b505b80611ed957611e9782612944565b6001600160a01b0382166000908152600260205260408120611eb89161306d565b6001600160a01b0382166000908152600360205260409020805460ff191690555b6040516001600160a01b0383169084907f49ff40d27a8ec667036d08fcb65529885bbe7d8acc745a4439b5eb119ad735f990600090a3505050565b60078181548110611f2457600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0391821692509081169060ff600160a01b8204811691600160a81b8104821691600160b01b9091041685565b6000805b600454811015611fc557826001600160a01b031660048281548110611f9a57611f9a613240565b6000918252602090912001546001600160a01b031603611fbd5750600192915050565b600101611f73565b50600092915050565b60008080429050836001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120379190613273565b9250836001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa158015612077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209b9190613273565b91506000806000866001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156120e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210491906133b5565b925092509250838163ffffffff161461216f57600061212963ffffffff8316866132cc565b90508063ffffffff1661213c8486612f22565b516001600160e01b031602969096019563ffffffff811661215d8585612f22565b516001600160e01b0316029590950194505b5050509193909250565b60015460009060ff1661218e57506000919050565b60006008548361219e91906132cc565b90506103848110156121b35750600092915050565b60006121c1610384836132cc565b905060006121d36103846105466132cc565b905060008183116121f6576121ef83663157def08c0e38613387565b9050612262565b600061220283856132cc565b9050600061221160e1836132b8565b905060006122276706f05b59d3b2000083612fd2565b9050600061223c86663157def08c0e38613387565b9050670de0b6b3a76400006122518383613387565b61225b91906132b8565b9450505050505b6000670de0b6b3a7640000905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f39190613273565b905069d3c21bcecceda10000008111156123495769d3c21bcecceda10000008161231d8183613327565b612328836002613387565b61233a90670de0b6b3a7640000613387565b61234491906132b8565b935050505b670de0b6b3a764000061235c8385613387565b61236691906132b8565b98975050505050505050565b8051606090429067ffffffffffffffff811115612391576123916132df565b6040519080825280602002602001820160405280156123d657816020015b60408051808201909152600080825260208201528152602001906001900390816123af5790505b50915060005b83518110156125e45760008482815181106123f9576123f9613240565b602002602001015190506000816001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612443573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124679190613273565b90506000826001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124cd9190613273565b90506000806000856001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612512573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253691906133b5565b925092509250878163ffffffff16146125a157600061255b63ffffffff83168a6132cc565b90508063ffffffff1661256e8486612f22565b516001600160e01b031602959095019463ffffffff811661258f8585612f22565b516001600160e01b0316029490940193505b6040518060400160405280868152602001858152508988815181106125c8576125c8613240565b60200260200101819052508660010196505050505050506123dc565b50915091565b6001600160a01b03831660008181526003602090815260408083205481516060810183528681528751818501528784015181840152948452600290925290912060ff9091169190826005811061264257612642613240565b6003020160008201518160000155602082015181600101556040820151816002015590505060058160016126769190613405565b612680919061341e565b6001600160a01b0385166000818152600360209081526040808320805460ff191660ff969096169590951790945586518782015185519182529181019190915292830185905290917f9a3f414f907ddb77231900d221b663199d0a42096ca010e25f0bb7292c409b4e9060600160405180910390a350505050565b60015460ff1661271e5760405163072e9ae360e31b815260040160405180910390fd5b8060000361272a575050565b6040516340c10f1960e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561279457600080fd5b505af11580156127a8573d6000803e3d6000fd5b50505050816001600160a01b03167f619caafabdd75649b302ba8419e48cccf64f37f1983ac4727cfb38b57703ffc9826040516106f391815260200190565b600080600083602001516001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561282e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285291906133b5565b50915091506000846040015161287157816001600160701b031661287c565b826001600160701b03165b90508060000361289157506000949350505050565b60008060006128a38860200151611fce565b92509250925060008860400151905060006128d08a6020015183846128c857866128ca565b875b86612a45565b905060008a6060015160126128e591906132f5565b6128f090600a613527565b61290290670de0b6b3a7640000613387565b90506000612930826040518060200160405280866001600160e01b0316815250612ee690919063ffffffff16565b5160701c9c9b505050505050505050505050565b60005b600454811015612a4157816001600160a01b03166004828154811061296e5761296e613240565b6000918252602090912001546001600160a01b031603612a395760048054612998906001906132cc565b815481106129a8576129a8613240565b600091825260209091200154600480546001600160a01b0390921691839081106129d4576129d4613240565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004805480612a1357612a13613371565b600082815260209020810160001990810180546001600160a01b03191690550190555050565b600101612947565b5050565b6000612a4f61307f565b60005b6005811015612ad0576001600160a01b03871660009081526002602052604090208160058110612a8457612a84613240565b600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828260058110612ac357612ac3613240565b6020020152600101612a52565b5060015b6005811015612b9c576000828260058110612af157612af1613240565b60200201519050815b600081118015612b2b5750815184612b136001846132cc565b60058110612b2357612b23613240565b602002015151105b15612b7a5783612b3c6001836132cc565b60058110612b4c57612b4c613240565b6020020151848260058110612b6357612b63613240565b602002015280612b7281613536565b915050612afa565b81848260058110612b8d57612b8d613240565b60200201525050600101612ad4565b5060408051600580825260c082019092526000916020820160a08036833701905050905060008585825b6005811015612cfd57858160058110612be157612be1613240565b60200201515115612cf5576000868260058110612c0057612c00613240565b602002015151612c1090846132cc565b9050610384811080612c235750611c2081115b15612c2e5750612cf5565b60008b612c5557878360058110612c4757612c47613240565b602002015160400151612c71565b878360058110612c6757612c67613240565b6020020151602001515b9050600082612c8083886132cc565b612c8a91906132b8565b905080888881518110612c9f57612c9f613240565b6001600160e01b039092166020928302919091019091015286612cc18161330e565b975050819550888460058110612cd957612cd9613240565b602002015151945060038710612cf157505050612cfd565b5050505b600101612bc6565b506003831015612d205760405163aad0df1d60e01b815260040160405180910390fd5b60015b83811015612e2d576000858281518110612d3f57612d3f613240565b6020026020010151905060008290505b600081118015612d9357506001600160e01b03821687612d706001846132cc565b81518110612d8057612d80613240565b60200260200101516001600160e01b0316115b15612df85786612da46001836132cc565b81518110612db457612db4613240565b6020026020010151878281518110612dce57612dce613240565b6001600160e01b039092166020928302919091019091015280612df081613536565b915050612d4f565b81878281518110612e0b57612e0b613240565b6001600160e01b03909216602092830291909101909101525050600101612d23565b50612e3960028461333a565b600103612e6b5783612e4c6002856132b8565b81518110612e5c57612e5c613240565b60200260200101519550612ed9565b600284612e7882866132b8565b81518110612e8857612e88613240565b6020026020010151856001600287612ea091906132b8565b612eaa91906132cc565b81518110612eba57612eba613240565b6020026020010151612ecc919061354d565b612ed6919061356c565b95505b5050505050949350505050565b60408051602081019091526000815260405180602001604052808385600001516001600160e01b0316612f199190613387565b90529392505050565b604080516020810190915260008152816001600160701b0316600003612f8a5760405162461bcd60e51b815260206004820152601760248201527f4669786564506f696e743a204449565f42595f5a45524f000000000000000000604482015260640161067a565b604080516020810190915280612fc06001600160701b0385166dffffffffffffffffffffffffffff60701b607088901b1661356c565b6001600160e01b031690529392505050565b6000612fdf60028361333a565b600003612ff457670de0b6b3a7640000612ff6565b825b90506130036002836132b8565b91505b8115611bb157670de0b6b3a764000061301f8480613387565b61302991906132b8565b925061303660028361333a565b1561305b57670de0b6b3a764000061304e8483613387565b61305891906132b8565b90505b6130666002836132b8565b9150613006565b5061307c90600f8101906130c8565b50565b6040518060a001604052806005905b6130b260405180606001604052806000815260200160008152602001600081525090565b81526020019060019003908161308e5790505090565b5b808211156130ea5760008082556001820181905560028201556003016130c9565b5090565b6001600160a01b038116811461307c57600080fd5b6000806040838503121561311657600080fd5b8235613121816130ee565b946020939093013593505050565b60006020828403121561314157600080fd5b813561314c816130ee565b9392505050565b8035801515811461316357600080fd5b919050565b6000806040838503121561317b57600080fd5b8235915061318b60208401613153565b90509250929050565b6000806000606084860312156131a957600080fd5b83356131b4816130ee565b925060208401356131c4816130ee565b91506131d260408501613153565b90509250925092565b602080825282518282018190526000918401906040840190835b8181101561321c5783516001600160a01b03168352602093840193909201916001016131f5565b509095945050505050565b60006020828403121561323957600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561326857600080fd5b815161314c816130ee565b60006020828403121561328557600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000826132c7576132c761328c565b500490565b81810381811115611bb157611bb16132a2565b634e487b7160e01b600052604160045260246000fd5b60ff8281168282160390811115611bb157611bb16132a2565b600060018201613320576133206132a2565b5060010190565b80820180821115611bb157611bb16132a2565b6000826133495761334961328c565b500690565b60006020828403121561336057600080fd5b815160ff8116811461314c57600080fd5b634e487b7160e01b600052603160045260246000fd5b8082028115828204841417611bb157611bb16132a2565b80516001600160701b038116811461316357600080fd5b6000806000606084860312156133ca57600080fd5b6133d38461339e565b92506133e16020850161339e565b9150604084015163ffffffff811681146133fa57600080fd5b809150509250925092565b60ff8181168382160190811115611bb157611bb16132a2565b600060ff8316806134315761343161328c565b8060ff84160691505092915050565b6001815b600184111561347b5780850481111561345f5761345f6132a2565b600184161561346d57908102905b60019390931c928002613444565b935093915050565b60008261349257506001611bb1565b8161349f57506000611bb1565b81600181146134b557600281146134bf576134db565b6001915050611bb1565b60ff8411156134d0576134d06132a2565b50506001821b611bb1565b5060208310610133831016604e8410600b84101617156134fe575081810a611bb1565b61350b6000198484613440565b806000190482111561351f5761351f6132a2565b029392505050565b600061314c60ff841683613483565b600081613545576135456132a2565b506000190190565b6001600160e01b038181168382160190811115611bb157611bb16132a2565b60006001600160e01b038316806135855761358561328c565b6001600160e01b0392909216919091049291505056fea2646970667358221220270af78b4c0c0fdeb8105ffe02398205e126724695125b5d4a918ef5866376d964736f6c634300081c0033000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a270000000000000000000000008588dbbce840390435fcbd8e72c087ed1799a540
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061021c5760003560e01c80639586a54211610125578063cdd00f69116100ad578063d525ed091161007c578063d525ed09146104cf578063deb96634146104e2578063e5831dca146104eb578063e837d9a9146104fe578063fc9654ab1461030e57600080fd5b8063cdd00f691461047a578063d0578a0114610482578063d2b8a22914610495578063d2fd9f6c146104bc57600080fd5b8063aa6ca808116100f4578063aa6ca808146103cb578063b1d06528146103e0578063b5fcf194146103f3578063bf353dbb14610406578063bf608cce1461042657600080fd5b80639586a542146103a05780639c52a7f1146103a85780639e5702be146103bb578063a4ef1357146103c357600080fd5b80632ff2e9dc116101a857806365fae35e1161017757806365fae35e1461032a5780636b598bbe1461033d578063802fe35d146103505780638aec854214610359578063927ef7fa1461036157600080fd5b80632ff2e9dc146102f55780634ae7ee1d1461030657806352b65c4b1461030e57806362e2c8481461031757600080fd5b80631c0541bd116101ef5780631c0541bd146102835780631dafe16b146102b85780631de40e49146102d55780631e9d4904146102e45780632cefe72c146102ec57600080fd5b806301339c2114610221578063024599661461022b5780630e40fe9f1461025e5780630e8e81271461027a575b600080fd5b61022961054e565b005b61023e610239366004613103565b6105d8565b604080519384526020840192909252908201526060015b60405180910390f35b61026c663157def08c0e3881565b604051908152602001610255565b61026c61054681565b6102a661029136600461312f565b60036020526000908152604090205460ff1681565b60405160ff9091168152602001610255565b6001546102c59060ff1681565b6040519015158152602001610255565b61026c6706f05b59d3b2000081565b61026c60e181565b61026c61022b81565b61026c69d3c21bcecceda100000081565b60065461026c565b61026c61038481565b610229610325366004613168565b61060e565b61022961033836600461312f565b6106ff565b61022961034b366004613194565b610773565b61026c60085481565b61026c610adc565b6103887f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2781565b6040516001600160a01b039091168152602001610255565b61026c610aec565b6102296103b636600461312f565b610b7d565b610229610bf0565b61026c610f70565b6103d3611268565b60405161025591906131db565b6102296103ee366004613194565b6112ca565b61022961040136600461312f565b6117ae565b61026c61041436600461312f565b60006020819052908152604090205481565b61045b61043436600461312f565b6005602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610255565b60075461026c565b61026c610490366004613103565b611a46565b6103887f0000000000000000000000008588dbbce840390435fcbd8e72c087ed1799a54081565b6103886104ca366004613227565b611bb7565b6103886104dd366004613227565b611be1565b61026c611c2081565b6102296104f9366004613227565b611bf1565b61051161050c366004613227565b611f14565b604080516001600160a01b0396871681529590941660208601529115159284019290925260ff90911660608301521515608082015260a001610255565b3360009081526020819052604090205460011461057d576040516282b42960e81b815260040160405180910390fd5b60015460ff16156105a1576040516319f4db0f60e31b815260040160405180910390fd5b6001805460ff1916811790556040517fa4d24b6714a5db779b2a933bdca578dbf6e9380ae4de745e84d4a6dd457204d590600090a1565b600260205281600052604060002081600581106105f457600080fd5b600302018054600182015460029092015490935090915083565b3360009081526020819052604090205460011461063d576040516282b42960e81b815260040160405180910390fd5b60075482106106835760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064015b60405180910390fd5b806007838154811061069757610697613240565b906000526020600020906002020160010160166101000a81548160ff021916908315150217905550817f1023261e84bada852098da9e423248e8fc3184408932bed6e2050195c13cfad9826040516106f3911515815260200190565b60405180910390a25050565b3360009081526020819052604090205460011461072e576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b336000908152602081905260409020546001146107a2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0383811660009081526005602052604090205416156107db5760405163a5d832e360e01b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083f9190613256565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610881573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a59190613256565b90508280156108c65750846001600160a01b0316826001600160a01b031614155b806108ec5750821580156108ec5750846001600160a01b0316816001600160a01b031614155b1561090a57604051630793df6360e21b815260040160405180910390fd5b6040805180820182526001600160a01b0380871682528515156020808401918252898316600081815260059092529481209351845492511515600160a01b026001600160a81b0319909316931692909217179091556006805460018101825591527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b03191690911790556109a784611f6f565b610a86576001600160a01b03841660009081526003602052604081205460ff169003610a3a576000806109d986611fce565b506040805160608101825242815260208082019485528183019384526001600160a01b038b16600090815260028083528482209351845595516001808501919091559451929095019190915560039052909120805460ff1916909117905550505b600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0386161790555b836001600160a01b0316856001600160a01b03167f5b99e368449b8061a5e6c9aa2ba8d3557d64befc230df2b329603e412e721abb85604051610acd911515815260200190565b60405180910390a35050505050565b6000610ae742612179565b905090565b600061022b7f0000000000000000000000008588dbbce840390435fcbd8e72c087ed1799a5406001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b739190613273565b610ae791906132b8565b33600090815260208190526040902054600114610bac576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b600854429061038490610c0390836132cc565b1015610c225760405163f0aaee6560e01b815260040160405180910390fd5b60045460008167ffffffffffffffff811115610c4057610c406132df565b604051908082528060200260200182016040528015610c69578160200160208202803683370190505b5090506000805b83811015610d6057600060048281548110610c8d57610c8d613240565b60009182526020808320909101546001600160a01b03168083526003909152604082205490925060ff16908115610cce57610cc96001836132f5565b610cd1565b60045b6001600160a01b03841660009081526002602052604090209091506103849060ff831660058110610d0457610d04613240565b6003020154610d13908a6132cc565b10610d525782868681518110610d2b57610d2b613240565b60200260200101906001600160a01b031690816001600160a01b0316815250508460010194505b836001019350505050610c70565b508015610f2c5760008167ffffffffffffffff811115610d8257610d826132df565b604051908082528060200260200182016040528015610dab578160200160208202803683370190505b50905060005b82811015610e0557838181518110610dcb57610dcb613240565b6020026020010151828281518110610de557610de5613240565b6001600160a01b0390921660209283029190910190910152600101610db1565b506000610e1182612372565b50905060005b83811015610e6457610e5c838281518110610e3457610e34613240565b6020026020010151838381518110610e4e57610e4e613240565b6020026020010151896125ea565b600101610e17565b5060015460ff168015610f055750610e7a610aec565b6040516370a0823160e01b81523360048201527f0000000000000000000000008588dbbce840390435fcbd8e72c087ed1799a5406001600160a01b0316906370a0823190602401602060405180830381865afa158015610ede573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f029190613273565b10155b15610f29576000610f1587612179565b90508015610f2757610f2733826126fb565b505b50505b600884905560408051858152602081018390527f3a00c122e9fd49a4a88111ff00ae627346ec777223f410d9c595b32348ca4958910160405180910390a150505050565b6007546000908190819067ffffffffffffffff811115610f9257610f926132df565b604051908082528060200260200182016040528015610fbb578160200160208202803683370190505b50905060005b6007548110156110b157600060078281548110610fe057610fe0613240565b60009182526020918290206040805160a081018252600290930290910180546001600160a01b0390811684526001909101549081169383019390935260ff600160a01b84048116151591830191909152600160a81b830481166060830152600160b01b90920490911615156080820181905290915061105f57506110a9565b600061106a826127e7565b90508060000361107b5750506110a9565b8084868151811061108e5761108e613240565b6020908102919091010152846110a38161330e565b95505050505b600101610fc1565b50816000036110d357604051630f5ac0cb60e01b815260040160405180910390fd5b60005b828110156111b85760006110eb826001613327565b90505b838110156111af5782818151811061110857611108613240565b602002602001015183838151811061112257611122613240565b602002602001015111156111a757600083838151811061114457611144613240565b6020026020010151905083828151811061116057611160613240565b602002602001015184848151811061117a5761117a613240565b6020026020010181815250508084838151811061119957611199613240565b602002602001018181525050505b6001016110ee565b506001016110d6565b506111c460028361333a565b6001036111f657806111d76002846132b8565b815181106111e7576111e7613240565b60200260200101519250505090565b60028161120382856132b8565b8151811061121357611213613240565b602002602001015182600160028661122b91906132b8565b61123591906132cc565b8151811061124557611245613240565b60200260200101516112579190613327565b61126191906132b8565b9250505090565b606060068054806020026020016040519081016040528092919081815260200182805480156112c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112a2575b5050505050905090565b336000908152602081905260409020546001146112f9576040516282b42960e81b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611339573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061135d9190613256565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561139f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c39190613256565b905082801561140457507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316826001600160a01b031614155b8061144a57508215801561144a57507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316816001600160a01b031614155b1561146857604051630793df6360e21b815260040160405180910390fd5b816001600160a01b0316856001600160a01b03161415801561149c5750806001600160a01b0316856001600160a01b031614155b156114ba57604051630793df6360e21b815260040160405180910390fd5b6000856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151e919061334e565b905060128160ff16111561156a5760405162461bcd60e51b81526020600482015260136024820152720a6e8c2c4d8ca40c8cac6d2dac2d8e6407c627606b1b604482015260640161067a565b6040805160a0810182526001600160a01b0380891682528781166020830190815287151593830193845260ff80861660608501908152600160808601818152600780549283018155600052955160029091027fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688810180549287166001600160a01b03199093169290921790915592517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68990930180549651915195511515600160b01b0260ff60b01b1996909316600160a81b029590951661ffff60a81b19911515600160a01b026001600160a81b0319909716939094169290921794909417161791909117905561167a85611f6f565b611759576001600160a01b03851660009081526003602052604081205460ff16900361170d576000806116ac87611fce565b506040805160608101825242815260208082019485528183019384526001600160a01b038c16600090815260028083528482209351845595516001808501919091559451929095019190915560039052909120805460ff1916909117905550505b600480546001810182556000919091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0387161790555b60408051851515815260ff831660208201526001600160a01b0380881692908916917f5c235f9dae8874242a4334347008c0a971ff3e006b75b4444854aadda93f5fa5910160405180910390a3505050505050565b336000908152602081905260409020546001146117dd576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03818116600090815260056020908152604091829020825180840190935254928316808352600160a01b90930460ff161515908201529061183857604051633fb801a560e21b815260040160405180910390fd5b6001600160a01b038216600090815260056020526040812080546001600160a81b03191690555b60065481101561195a57826001600160a01b03166006828154811061188657611886613240565b6000918252602090912001546001600160a01b03160361195257600680546118b0906001906132cc565b815481106118c0576118c0613240565b600091825260209091200154600680546001600160a01b0390921691839081106118ec576118ec613240565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600680548061192b5761192b613371565b600082815260209020810160001990810180546001600160a01b031916905501905561195a565b60010161185f565b5080516000805b6007548110156119bb57826001600160a01b03166007828154811061198857611988613240565b60009182526020909120600160029092020101546001600160a01b0316036119b357600191506119bb565b600101611961565b5080611a0c576119ca82612944565b6001600160a01b03821660009081526002602052604081206119eb9161306d565b6001600160a01b0382166000908152600360205260409020805460ff191690555b6040516001600160a01b038516907fd4bab7746d82129d0d621d803f51fe4b9961fe75c4ddfb9537ebd8f5fa283be790600090a250505050565b60007f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316836001600160a01b031603611aad57670de0b6b3a7640000611a92610f70565b611a9c9084613387565b611aa691906132b8565b9050611bb1565b6001600160a01b03838116600090815260056020908152604091829020825180840190935254928316808352600160a01b90930460ff161515908201529015611b96576000806000611b028460000151611fce565b9250925092506000611b2e856000015186602001518760200151611b265785611b28565b865b85612a45565b90506000611b5c886040518060200160405280856001600160e01b0316815250612ee690919063ffffffff16565b805190915060701c670de0b6b3a7640000611b75610f70565b611b7f9083613387565b611b8991906132b8565b9750505050505050611baf565b604051633fb801a560e21b815260040160405180910390fd5b505b92915050565b60068181548110611bc757600080fd5b6000918252602090912001546001600160a01b0316905081565b60048181548110611bc757600080fd5b33600090815260208190526040902054600114611c20576040516282b42960e81b815260040160405180910390fd5b6007548110611c42576040516363df817160e01b815260040160405180910390fd5b600060078281548110611c5757611c57613240565b600091825260209091206001600290920201810154600780546001600160a01b03909216935091611c87916132cc565b81548110611c9757611c97613240565b906000526020600020906002020160078381548110611cb857611cb8613240565b60009182526020909120825460029092020180546001600160a01b039283166001600160a01b031991821617825560019384018054949092018054949093169084168117835581546001600160a81b031990941617600160a01b9384900460ff908116151590940217808355815460ff60a81b198216600160a81b9182900486169091029081178455915461ffff60a81b1990911660ff60b01b1990921691909117600160b01b918290049093161515029190911790556007805480611d8057611d80613371565b60008281526020812060026000199093019283020180546001600160a01b031916815560010180546001600160b81b03191690559155805b600654811015611e2457826001600160a01b03166005600060068481548110611de357611de3613240565b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541603611e1c5760019150611e24565b600101611db8565b5080611e895760005b600754811015611e8757826001600160a01b031660078281548110611e5457611e54613240565b60009182526020909120600160029092020101546001600160a01b031603611e7f5760019150611e87565b600101611e2d565b505b80611ed957611e9782612944565b6001600160a01b0382166000908152600260205260408120611eb89161306d565b6001600160a01b0382166000908152600360205260409020805460ff191690555b6040516001600160a01b0383169084907f49ff40d27a8ec667036d08fcb65529885bbe7d8acc745a4439b5eb119ad735f990600090a3505050565b60078181548110611f2457600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0391821692509081169060ff600160a01b8204811691600160a81b8104821691600160b01b9091041685565b6000805b600454811015611fc557826001600160a01b031660048281548110611f9a57611f9a613240565b6000918252602090912001546001600160a01b031603611fbd5750600192915050565b600101611f73565b50600092915050565b60008080429050836001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120379190613273565b9250836001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa158015612077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209b9190613273565b91506000806000866001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156120e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210491906133b5565b925092509250838163ffffffff161461216f57600061212963ffffffff8316866132cc565b90508063ffffffff1661213c8486612f22565b516001600160e01b031602969096019563ffffffff811661215d8585612f22565b516001600160e01b0316029590950194505b5050509193909250565b60015460009060ff1661218e57506000919050565b60006008548361219e91906132cc565b90506103848110156121b35750600092915050565b60006121c1610384836132cc565b905060006121d36103846105466132cc565b905060008183116121f6576121ef83663157def08c0e38613387565b9050612262565b600061220283856132cc565b9050600061221160e1836132b8565b905060006122276706f05b59d3b2000083612fd2565b9050600061223c86663157def08c0e38613387565b9050670de0b6b3a76400006122518383613387565b61225b91906132b8565b9450505050505b6000670de0b6b3a7640000905060007f0000000000000000000000008588dbbce840390435fcbd8e72c087ed1799a5406001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f39190613273565b905069d3c21bcecceda10000008111156123495769d3c21bcecceda10000008161231d8183613327565b612328836002613387565b61233a90670de0b6b3a7640000613387565b61234491906132b8565b935050505b670de0b6b3a764000061235c8385613387565b61236691906132b8565b98975050505050505050565b8051606090429067ffffffffffffffff811115612391576123916132df565b6040519080825280602002602001820160405280156123d657816020015b60408051808201909152600080825260208201528152602001906001900390816123af5790505b50915060005b83518110156125e45760008482815181106123f9576123f9613240565b602002602001015190506000816001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612443573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124679190613273565b90506000826001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124cd9190613273565b90506000806000856001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612512573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253691906133b5565b925092509250878163ffffffff16146125a157600061255b63ffffffff83168a6132cc565b90508063ffffffff1661256e8486612f22565b516001600160e01b031602959095019463ffffffff811661258f8585612f22565b516001600160e01b0316029490940193505b6040518060400160405280868152602001858152508988815181106125c8576125c8613240565b60200260200101819052508660010196505050505050506123dc565b50915091565b6001600160a01b03831660008181526003602090815260408083205481516060810183528681528751818501528784015181840152948452600290925290912060ff9091169190826005811061264257612642613240565b6003020160008201518160000155602082015181600101556040820151816002015590505060058160016126769190613405565b612680919061341e565b6001600160a01b0385166000818152600360209081526040808320805460ff191660ff969096169590951790945586518782015185519182529181019190915292830185905290917f9a3f414f907ddb77231900d221b663199d0a42096ca010e25f0bb7292c409b4e9060600160405180910390a350505050565b60015460ff1661271e5760405163072e9ae360e31b815260040160405180910390fd5b8060000361272a575050565b6040516340c10f1960e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000008588dbbce840390435fcbd8e72c087ed1799a54016906340c10f1990604401600060405180830381600087803b15801561279457600080fd5b505af11580156127a8573d6000803e3d6000fd5b50505050816001600160a01b03167f619caafabdd75649b302ba8419e48cccf64f37f1983ac4727cfb38b57703ffc9826040516106f391815260200190565b600080600083602001516001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561282e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285291906133b5565b50915091506000846040015161287157816001600160701b031661287c565b826001600160701b03165b90508060000361289157506000949350505050565b60008060006128a38860200151611fce565b92509250925060008860400151905060006128d08a6020015183846128c857866128ca565b875b86612a45565b905060008a6060015160126128e591906132f5565b6128f090600a613527565b61290290670de0b6b3a7640000613387565b90506000612930826040518060200160405280866001600160e01b0316815250612ee690919063ffffffff16565b5160701c9c9b505050505050505050505050565b60005b600454811015612a4157816001600160a01b03166004828154811061296e5761296e613240565b6000918252602090912001546001600160a01b031603612a395760048054612998906001906132cc565b815481106129a8576129a8613240565b600091825260209091200154600480546001600160a01b0390921691839081106129d4576129d4613240565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004805480612a1357612a13613371565b600082815260209020810160001990810180546001600160a01b03191690550190555050565b600101612947565b5050565b6000612a4f61307f565b60005b6005811015612ad0576001600160a01b03871660009081526002602052604090208160058110612a8457612a84613240565b600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050828260058110612ac357612ac3613240565b6020020152600101612a52565b5060015b6005811015612b9c576000828260058110612af157612af1613240565b60200201519050815b600081118015612b2b5750815184612b136001846132cc565b60058110612b2357612b23613240565b602002015151105b15612b7a5783612b3c6001836132cc565b60058110612b4c57612b4c613240565b6020020151848260058110612b6357612b63613240565b602002015280612b7281613536565b915050612afa565b81848260058110612b8d57612b8d613240565b60200201525050600101612ad4565b5060408051600580825260c082019092526000916020820160a08036833701905050905060008585825b6005811015612cfd57858160058110612be157612be1613240565b60200201515115612cf5576000868260058110612c0057612c00613240565b602002015151612c1090846132cc565b9050610384811080612c235750611c2081115b15612c2e5750612cf5565b60008b612c5557878360058110612c4757612c47613240565b602002015160400151612c71565b878360058110612c6757612c67613240565b6020020151602001515b9050600082612c8083886132cc565b612c8a91906132b8565b905080888881518110612c9f57612c9f613240565b6001600160e01b039092166020928302919091019091015286612cc18161330e565b975050819550888460058110612cd957612cd9613240565b602002015151945060038710612cf157505050612cfd565b5050505b600101612bc6565b506003831015612d205760405163aad0df1d60e01b815260040160405180910390fd5b60015b83811015612e2d576000858281518110612d3f57612d3f613240565b6020026020010151905060008290505b600081118015612d9357506001600160e01b03821687612d706001846132cc565b81518110612d8057612d80613240565b60200260200101516001600160e01b0316115b15612df85786612da46001836132cc565b81518110612db457612db4613240565b6020026020010151878281518110612dce57612dce613240565b6001600160e01b039092166020928302919091019091015280612df081613536565b915050612d4f565b81878281518110612e0b57612e0b613240565b6001600160e01b03909216602092830291909101909101525050600101612d23565b50612e3960028461333a565b600103612e6b5783612e4c6002856132b8565b81518110612e5c57612e5c613240565b60200260200101519550612ed9565b600284612e7882866132b8565b81518110612e8857612e88613240565b6020026020010151856001600287612ea091906132b8565b612eaa91906132cc565b81518110612eba57612eba613240565b6020026020010151612ecc919061354d565b612ed6919061356c565b95505b5050505050949350505050565b60408051602081019091526000815260405180602001604052808385600001516001600160e01b0316612f199190613387565b90529392505050565b604080516020810190915260008152816001600160701b0316600003612f8a5760405162461bcd60e51b815260206004820152601760248201527f4669786564506f696e743a204449565f42595f5a45524f000000000000000000604482015260640161067a565b604080516020810190915280612fc06001600160701b0385166dffffffffffffffffffffffffffff60701b607088901b1661356c565b6001600160e01b031690529392505050565b6000612fdf60028361333a565b600003612ff457670de0b6b3a7640000612ff6565b825b90506130036002836132b8565b91505b8115611bb157670de0b6b3a764000061301f8480613387565b61302991906132b8565b925061303660028361333a565b1561305b57670de0b6b3a764000061304e8483613387565b61305891906132b8565b90505b6130666002836132b8565b9150613006565b5061307c90600f8101906130c8565b50565b6040518060a001604052806005905b6130b260405180606001604052806000815260200160008152602001600081525090565b81526020019060019003908161308e5790505090565b5b808211156130ea5760008082556001820181905560028201556003016130c9565b5090565b6001600160a01b038116811461307c57600080fd5b6000806040838503121561311657600080fd5b8235613121816130ee565b946020939093013593505050565b60006020828403121561314157600080fd5b813561314c816130ee565b9392505050565b8035801515811461316357600080fd5b919050565b6000806040838503121561317b57600080fd5b8235915061318b60208401613153565b90509250929050565b6000806000606084860312156131a957600080fd5b83356131b4816130ee565b925060208401356131c4816130ee565b91506131d260408501613153565b90509250925092565b602080825282518282018190526000918401906040840190835b8181101561321c5783516001600160a01b03168352602093840193909201916001016131f5565b509095945050505050565b60006020828403121561323957600080fd5b5035919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561326857600080fd5b815161314c816130ee565b60006020828403121561328557600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000826132c7576132c761328c565b500490565b81810381811115611bb157611bb16132a2565b634e487b7160e01b600052604160045260246000fd5b60ff8281168282160390811115611bb157611bb16132a2565b600060018201613320576133206132a2565b5060010190565b80820180821115611bb157611bb16132a2565b6000826133495761334961328c565b500690565b60006020828403121561336057600080fd5b815160ff8116811461314c57600080fd5b634e487b7160e01b600052603160045260246000fd5b8082028115828204841417611bb157611bb16132a2565b80516001600160701b038116811461316357600080fd5b6000806000606084860312156133ca57600080fd5b6133d38461339e565b92506133e16020850161339e565b9150604084015163ffffffff811681146133fa57600080fd5b809150509250925092565b60ff8181168382160190811115611bb157611bb16132a2565b600060ff8316806134315761343161328c565b8060ff84160691505092915050565b6001815b600184111561347b5780850481111561345f5761345f6132a2565b600184161561346d57908102905b60019390931c928002613444565b935093915050565b60008261349257506001611bb1565b8161349f57506000611bb1565b81600181146134b557600281146134bf576134db565b6001915050611bb1565b60ff8411156134d0576134d06132a2565b50506001821b611bb1565b5060208310610133831016604e8410600b84101617156134fe575081810a611bb1565b61350b6000198484613440565b806000190482111561351f5761351f6132a2565b029392505050565b600061314c60ff841683613483565b600081613545576135456132a2565b506000190190565b6001600160e01b038181168382160190811115611bb157611bb16132a2565b60006001600160e01b038316806135855761358561328c565b6001600160e01b0392909216919091049291505056fea2646970667358221220270af78b4c0c0fdeb8105ffe02398205e126724695125b5d4a918ef5866376d964736f6c634300081c0033