Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- TWAPOracle
- Optimization enabled
- true
- Compiler version
- v0.8.28+commit.7893614a
- Optimization runs
- 200
- EVM Version
- paris
- Verified at
- 2026-02-15T10:12:41.375573Z
Constructor Arguments
0x000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27
Arg [0] (address) : 0xa1077a294dde1b09bb078844df40758a5d0f9a27
contracts/dss/twap.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
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);
}
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);
}
// Optimized RPower for reward calculation (Logarithmic time complexity)
// Calculates x^n with 1e18 precision to match contract constants
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; }
}
}
}
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;
}
error UnknownPair();
error PairAlreadyAdded();
error InvalidPair();
error InvalidTWAPWindow();
error Unauthorized();
error PeriodNotElapsed();
error RewardsNotEnabled();
error InsufficientBalanceForReward();
error AlreadyLaunched();
error NoValidReferences();
error StalePrice();
address public immutable wpls;
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;
uint public constant PERIOD_SIZE = 3600;
uint public constant MIN_WINDOW = 3600;
uint public constant MAX_WINDOW = 18000;
uint public constant REWARD_WINDOW = 5400; // Peak at 1.5hr total (0.5hr effective)
uint public constant UPDATE_THRESHOLD = 7200;
uint public constant DECAY_RATE = 500000000000000000; // 0.5
uint public constant DECAY_PERIOD = 900;
string public constant name = "TWAP";
string public constant symbol = "TWAP";
uint8 public constant decimals = 18;
uint public totalSupply;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
uint public constant BASE_REWARD_RATE = 13888888888888888;
uint public constant INITIAL_SUPPLY = 1_000_000 * 10 ** 18;
uint public constant MIN_HOLDING_DIVISOR = 555;
// OPTIMIZED: Circular Buffer Data
mapping(address => Observation[5]) public observations; // pair => observations
mapping(address => uint8) public observationHeads; // pair => next write index (0-4)
// OPTIMIZED: Unified List for Updates
address[] public livePairs;
mapping(address => PairInfo) public tokenToPairInfo;
address[] public pricedTokens;
// REMOVED: mapping(address => uint) public lastUpdateTimestamp; (Redundant, use observation timestamp)
ReferenceStable[] public referenceStables;
event PriceUpdated(address indexed token, address indexed pair, uint price0Cumulative, uint price1Cumulative, uint timestamp);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
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 DirectPairAdded(address indexed token, address indexed pair, bool isToken0);
event DirectPairRemoved(address indexed token);
event SuperUpdate(uint timestamp, uint updatedPairs);
uint public lastSuperUpdateTimestamp;
constructor(address _wpls) {
wpls = _wpls;
wards[msg.sender] = 1;
emit Rely(msg.sender);
totalSupply = INITIAL_SUPPLY;
balanceOf[msg.sender] = INITIAL_SUPPLY;
emit Transfer(address(0), msg.sender, INITIAL_SUPPLY);
}
function getMinHoldingForReward() public view returns (uint) { return totalSupply / MIN_HOLDING_DIVISOR; }
function launch() external auth {
if (rewardsEnabled) revert AlreadyLaunched();
rewardsEnabled = true;
emit RewardsLaunched();
}
// === REFERENCE STABLES ===
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();
uint8 stableDecimals = IERC20Decimals(stable).decimals();
if (stableDecimals > 18) revert("Stable decimals >18");
referenceStables.push(ReferenceStable(stable, pair, isWplsToken0, stableDecimals, true));
// Initialize Observation
(uint price0Cumulative, uint price1Cumulative, ) = UniswapV2OracleLibrary.currentCumulativePrices(pair);
observations[pair][0] = Observation(block.timestamp, price0Cumulative, price1Cumulative);
observationHeads[pair] = 1; // Next write goes to index 1
// OPTIMIZATION: Add to unified list
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);
}
// === DIRECT PAIRS ===
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);
// Initialize Observation
(uint price0Cumulative, uint price1Cumulative, ) = UniswapV2OracleLibrary.currentCumulativePrices(pair);
observations[pair][0] = Observation(block.timestamp, price0Cumulative, price1Cumulative);
observationHeads[pair] = 1;
// OPTIMIZATION: Add to unified list
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];
// OPTIMIZATION: Remove from livePairs
_removeLivePair(info.pair);
// Clean up storage for gas refund
delete observations[info.pair];
delete observationHeads[info.pair];
// Remove from pricedTokens
for (uint i = 0; i < pricedTokens.length; i++) {
if (pricedTokens[i] == token) {
pricedTokens[i] = pricedTokens[pricedTokens.length - 1];
pricedTokens.pop();
break;
}
}
emit DirectPairRemoved(token);
}
// Helper to remove from livePairs array
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;
}
}
}
// === OPTIMIZED: superUpdate ===
function superUpdate() public {
uint currentTimestamp = block.timestamp;
if (currentTimestamp - lastSuperUpdateTimestamp < MIN_WINDOW) {
revert PeriodNotElapsed();
}
// OPTIMIZATION: Single Pass Collection
// We allocate max memory size to avoid resizing costs.
// Since we have < 100 pairs, this is acceptable gas wise vs dynamic pushing.
uint totalPairs = livePairs.length;
address[] memory pairsToUpdate = new address[](totalPairs);
uint updateCount = 0;
for (uint i = 0; i < totalPairs; ) {
address pair = livePairs[i];
// Get the index of the most recently written observation
uint8 head = observationHeads[pair];
uint8 lastIdx = (head == 0) ? 4 : head - 1;
// Check timestamp of the latest observation instead of a separate mapping
if (currentTimestamp - observations[pair][lastIdx].timestamp >= PERIOD_SIZE) {
pairsToUpdate[updateCount] = pair;
unchecked { ++updateCount; }
}
unchecked { ++i; }
}
if (updateCount > 0) {
// Create a properly sized array for the batch call
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 && balanceOf[msg.sender] >= getMinHoldingForReward()) {
uint reward = calculateReward(currentTimestamp);
if (reward > 0) _mintReward(msg.sender, reward);
}
}
lastSuperUpdateTimestamp = currentTimestamp;
emit SuperUpdate(currentTimestamp, updateCount);
}
// === OPTIMIZED: Circular Buffer Update ===
function _applyUpdate(address pair, UniswapV2OracleLibrary.PriceData memory price, uint blockTimestamp) private {
uint8 head = observationHeads[pair];
// Overwrite the oldest observation
observations[pair][head] = Observation(
block.timestamp,
price.price0Cumulative,
price.price1Cumulative
);
// Move head forward (0 -> 1 -> 2 -> 3 -> 4 -> 0)
observationHeads[pair] = (head + 1) % 5;
emit PriceUpdated(address(0), pair, price.price0Cumulative, price.price1Cumulative, blockTimestamp);
}
// === OPTIMIZED: Read & Sort ===
function getMedianPrice(address pair, bool needPrice0, uint currentCumulative, uint currentTimestamp) internal view returns (uint224 medianPrice) {
// 1. Load all 5 observations into memory
Observation[5] memory obsArray;
for(uint i=0; i<5; i++) {
obsArray[i] = observations[pair][i];
}
// 2. Sort by timestamp (Descending: Newest first)
// Using insertion sort for efficiency on small arrays
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; }
}
// 3. Calculate Segment TWAPs
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 == 0) revert InvalidTWAPWindow();
// Sort Segment Prices
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);
FixedPoint.uq144x112 memory fullPrice = FixedPoint.uq112x112(medianPrice).mul(1e18);
uint priceNative = FixedPoint.decode144(fullPrice);
uint decimalAdjustment = 10 ** (18 - ref.stableDecimals);
priceNormalized = priceNative * decimalAdjustment;
}
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();
// Sort Prices
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 = FixedPoint.decode144(temp);
amountOutUsd = (amountInWpls * getWplsPriceInUsd()) / 1e18;
} else {
revert UnknownPair();
}
}
function _mintReward(address updater, uint reward) private {
if (!rewardsEnabled) revert RewardsNotEnabled();
uint holding = balanceOf[updater];
uint minHolding = getMinHoldingForReward();
if (holding < minHolding) revert InsufficientBalanceForReward();
if (reward == 0) return;
totalSupply += reward;
balanceOf[updater] += reward;
emit Reward(updater, reward);
}
// === OPTIMIZED REWARD MATH ===
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;
// OPTIMIZATION: Use Logarithmic Power function instead of loop
uint decayIntervals = cappedExtra / DECAY_PERIOD;
// rpow calculates (DECAY_RATE ^ decayIntervals)
// DECAY_RATE is 5e17 (0.5), rpow expects 1e18 precision
uint decayFactor = FixedPoint.rpow(DECAY_RATE, decayIntervals);
uint peakReward = BASE_REWARD_RATE * peakEffectiveTime;
timeBasedReward = (peakReward * decayFactor) / 1e18;
}
uint supplyFactor = 1e18;
if (totalSupply > INITIAL_SUPPLY) {
uint a = INITIAL_SUPPLY;
uint b = totalSupply;
supplyFactor = (2 * a * 1e18) / (a + b);
}
return (timeBasedReward * supplyFactor) / 1e18;
}
// === ERC20 IMPLEMENTATION ===
function transfer(address to, uint256 value) external returns (bool) {
require(to != address(0), "ERC20: transfer to the zero address");
require(balanceOf[msg.sender] >= value, "ERC20: transfer amount exceeds balance");
balanceOf[msg.sender] -= value;
balanceOf[to] += value;
emit Transfer(msg.sender, to, value);
return true;
}
function transferFrom(address from, address to, uint256 value) external returns (bool) {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(balanceOf[from] >= value, "ERC20: transfer amount exceeds balance");
require(allowance[from][msg.sender] >= value, "ERC20: insufficient allowance");
balanceOf[from] -= value;
balanceOf[to] += value;
allowance[from][msg.sender] -= value;
emit Transfer(from, to, value);
return true;
}
function approve(address spender, uint256 value) external returns (bool) {
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
// === VIEW HELPERS ===
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
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_wpls","internalType":"address"}]},{"type":"error","name":"AlreadyLaunched","inputs":[]},{"type":"error","name":"InsufficientBalanceForReward","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":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"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":"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":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","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":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"UPDATE_THRESHOLD","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":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"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":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"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":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"rewardsEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"superUpdate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","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":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"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
0x60a060405234801561001057600080fd5b506040516136a83803806136a883398101604081905261002f916100d3565b6001600160a01b0381166080523360008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a269d3c21bcecceda1000000600281905533600081815260036020908152604080832085905551938452919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610103565b6000602082840312156100e557600080fd5b81516001600160a01b03811681146100fc57600080fd5b9392505050565b60805161357561013360003960008181610446015281816116f40152818161173a0152611c7701526135756000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80638aec854211610151578063b5fcf194116100c3578063d2fd9f6c11610087578063d2fd9f6c14610591578063d525ed09146105a4578063dd62ed3e146105b7578063deb96634146105e2578063e837d9a9146105eb578063fc9654ab146103ce57600080fd5b8063b5fcf194146104ef578063bf353dbb14610502578063bf608cce14610522578063cdd00f6914610576578063d0578a011461057e57600080fd5b80639c52a7f1116101155780639c52a7f1146104915780639e5702be146104a4578063a4ef1357146104ac578063a9059cbb146104b4578063aa6ca808146104c7578063b1d06528146104dc57600080fd5b80638aec854214610439578063927ef7fa146104415780639586a5421461048057806395d89b41146102b657806399f91f4f1461048857600080fd5b806323b872dd116101ea57806352b65c4b116101ae57806352b65c4b146103ce57806362e2c848146103d757806365fae35e146103ea5780636b598bbe146103fd57806370a0823114610410578063802fe35d1461043057600080fd5b806323b872dd146103915780632cefe72c146103a45780632ff2e9dc146103ad578063313ce567146103be5780634ae7ee1d146103c657600080fd5b80630e8e81271161023c5780630e8e81271461032557806318160ddd1461032e5780631c0541bd146103375780631dafe16b1461036c5780631de40e49146103795780631e9d49041461038857600080fd5b806301339c2114610279578063024599661461028357806306fdde03146102b6578063095ea7b3146102e65780630e40fe9f14610309575b600080fd5b61028161063b565b005b610296610291366004612f56565b6106c5565b604080519384526020840192909252908201526060015b60405180910390f35b6102d9604051806040016040528060048152602001630545741560e41b81525081565b6040516102ad9190612f82565b6102f96102f4366004612f56565b6106fb565b60405190151581526020016102ad565b610317663157def08c0e3881565b6040519081526020016102ad565b61031761151881565b61031760025481565b61035a610345366004612fd0565b60066020526000908152604090205460ff1681565b60405160ff90911681526020016102ad565b6001546102f99060ff1681565b6103176706f05b59d3b2000081565b61031761038481565b6102f961039f366004612ff4565b610768565b61031761022b81565b61031769d3c21bcecceda100000081565b61035a601281565b600954610317565b610317610e1081565b6102816103e536600461304a565b61098f565b6102816103f8366004612fd0565b610a7b565b61028161040b366004613076565b610aef565b61031761041e366004612fd0565b60036020526000908152604090205481565b610317600b5481565b610317610e08565b6104687f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102ad565b610317610e18565b610317611c2081565b61028161049f366004612fd0565b610e2a565b610281610e9d565b6103176111b0565b6102f96104c2366004612f56565b6114a8565b6104cf61158d565b6040516102ad91906130bd565b6102816104ea366004613076565b6115ef565b6102816104fd366004612fd0565b611a40565b610317610510366004612fd0565b60006020819052908152604090205481565b610557610530366004612fd0565b6008602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b0390931683529015156020830152016102ad565b600a54610317565b61031761058c366004612f56565b611c73565b61046861059f366004613109565b611df5565b6104686105b2366004613109565b611e1f565b6103176105c5366004613122565b600460209081526000928352604080842090915290825290205481565b61031761465081565b6105fe6105f9366004613109565b611e2f565b604080516001600160a01b0396871681529590941660208601529115159284019290925260ff90911660608301521515608082015260a0016102ad565b3360009081526020819052604090205460011461066a576040516282b42960e81b815260040160405180910390fd5b60015460ff161561068e576040516319f4db0f60e31b815260040160405180910390fd5b6001805460ff1916811790556040517fa4d24b6714a5db779b2a933bdca578dbf6e9380ae4de745e84d4a6dd457204d590600090a1565b600560205281600052604060002081600581106106e157600080fd5b600302018054600182015460029092015490935090915083565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906107569086815260200190565b60405180910390a35060015b92915050565b60006001600160a01b0384166107d35760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084015b60405180910390fd5b6001600160a01b0383166107f95760405162461bcd60e51b81526004016107ca9061315b565b6001600160a01b0384166000908152600360205260409020548211156108315760405162461bcd60e51b81526004016107ca9061319e565b6001600160a01b03841660009081526004602090815260408083203384529091529020548211156108a45760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016107ca565b6001600160a01b038416600090815260036020526040812080548492906108cc9084906131fa565b90915550506001600160a01b038316600090815260036020526040812080548492906108f990849061320d565b90915550506001600160a01b0384166000908152600460209081526040808320338452909152812080548492906109319084906131fa565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161097d91815260200190565b60405180910390a35060019392505050565b336000908152602081905260409020546001146109be576040516282b42960e81b815260040160405180910390fd5b600a5482106109ff5760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064016107ca565b80600a8381548110610a1357610a13613220565b906000526020600020906002020160010160166101000a81548160ff021916908315150217905550817f1023261e84bada852098da9e423248e8fc3184408932bed6e2050195c13cfad982604051610a6f911515815260200190565b60405180910390a25050565b33600090815260208190526040902054600114610aaa576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b33600090815260208190526040902054600114610b1e576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038381166000908152600860205260409020541615610b575760405163a5d832e360e01b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190613236565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c219190613236565b9050828015610c425750846001600160a01b0316826001600160a01b031614155b80610c68575082158015610c685750846001600160a01b0316816001600160a01b031614155b15610c8657604051630793df6360e21b815260040160405180910390fd5b6040805180820182526001600160a01b0380871682528515156020808401918252898316600081815260089092529481209351845492511515600160a01b026001600160a81b031990931693169290921717909155600980546001810182559082527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b03191690921790915580610d2686611e8a565b506040805160608101825242815260208082018581528284018581526001600160a01b038d8116600081815260058652878120965187559351600180880191909155925160029096019590955560068452858320805460ff1916831790556007805492830181559092527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b0319168417905592518a1515815294965092945092908a16917f5b99e368449b8061a5e6c9aa2ba8d3557d64befc230df2b329603e412e721abb910160405180910390a350505050505050565b6000610e1342612035565b905090565b600061022b600254610e139190613269565b33600090815260208190526040902054600114610e59576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b600b544290610e1090610eb090836131fa565b1015610ecf5760405163f0aaee6560e01b815260040160405180910390fd5b60075460008167ffffffffffffffff811115610eed57610eed61327d565b604051908082528060200260200182016040528015610f16578160200160208202803683370190505b5090506000805b8381101561101857600060078281548110610f3a57610f3a613220565b60009182526020808320909101546001600160a01b03168083526006909152604082205490925060ff16908115610f7b57610f76600183613293565b610f7e565b60045b9050610e1060056000856001600160a01b03166001600160a01b031681526020019081526020016000208260ff1660058110610fbc57610fbc613220565b6003020154610fcb908a6131fa565b1061100a5782868681518110610fe357610fe3613220565b60200260200101906001600160a01b031690816001600160a01b0316815250508460010194505b836001019350505050610f1d565b50801561116c5760008167ffffffffffffffff81111561103a5761103a61327d565b604051908082528060200260200182016040528015611063578160200160208202803683370190505b50905060005b828110156110bd5783818151811061108357611083613220565b602002602001015182828151811061109d5761109d613220565b6001600160a01b0390921660209283029190910190910152600101611069565b5060006110c9826121aa565b50905060005b8381101561111c576111148382815181106110ec576110ec613220565b602002602001015183838151811061110657611106613220565b602002602001015189612422565b6001016110cf565b5060015460ff1680156111455750611132610e18565b3360009081526003602052604090205410155b1561116957600061115587612035565b90508015611167576111673382612533565b505b50505b600b84905560408051858152602081018390527f3a00c122e9fd49a4a88111ff00ae627346ec777223f410d9c595b32348ca4958910160405180910390a150505050565b600a546000908190819067ffffffffffffffff8111156111d2576111d261327d565b6040519080825280602002602001820160405280156111fb578160200160208202803683370190505b50905060005b600a548110156112f1576000600a828154811061122057611220613220565b60009182526020918290206040805160a081018252600290930290910180546001600160a01b0390811684526001909101549081169383019390935260ff600160a01b84048116151591830191909152600160a81b830481166060830152600160b01b90920490911615156080820181905290915061129f57506112e9565b60006112aa82612631565b9050806000036112bb5750506112e9565b808486815181106112ce576112ce613220565b6020908102919091010152846112e3816132ac565b95505050505b600101611201565b508160000361131357604051630f5ac0cb60e01b815260040160405180910390fd5b60005b828110156113f857600061132b82600161320d565b90505b838110156113ef5782818151811061134857611348613220565b602002602001015183838151811061136257611362613220565b602002602001015111156113e757600083838151811061138457611384613220565b602002602001015190508382815181106113a0576113a0613220565b60200260200101518484815181106113ba576113ba613220565b602002602001018181525050808483815181106113d9576113d9613220565b602002602001018181525050505b60010161132e565b50600101611316565b506114046002836132c5565b6001036114365780611417600284613269565b8151811061142757611427613220565b60200260200101519250505090565b6002816114438285613269565b8151811061145357611453613220565b602002602001015182600160028661146b9190613269565b61147591906131fa565b8151811061148557611485613220565b6020026020010151611497919061320d565b6114a19190613269565b9250505090565b60006001600160a01b0383166114d05760405162461bcd60e51b81526004016107ca9061315b565b336000908152600360205260409020548211156114ff5760405162461bcd60e51b81526004016107ca9061319e565b336000908152600360205260408120805484929061151e9084906131fa565b90915550506001600160a01b0383166000908152600360205260408120805484929061154b90849061320d565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610756565b606060098054806020026020016040519081016040528092919081815260200182805480156115e557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116115c7575b5050505050905090565b3360009081526020819052604090205460011461161e576040516282b42960e81b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561165e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116829190613236565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e89190613236565b905082801561172957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b8061176f57508215801561176f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614155b1561178d57604051630793df6360e21b815260040160405180910390fd5b6000856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f191906132d9565b905060128160ff16111561183d5760405162461bcd60e51b81526020600482015260136024820152720a6e8c2c4d8ca40c8cac6d2dac2d8e6407c627606b1b60448201526064016107ca565b6040805160a0810182526001600160a01b0388811682528781166020830190815287151593830193845260ff85811660608501908152600160808601818152600a80549283018155600090815296517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8600290930292830180546001600160a01b03191691881691909117905593517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a99091018054975192519451919095166001600160a81b031990971696909617600160a01b911515919091021761ffff60a81b1916600160a81b929091169190910260ff60b01b191617600160b01b93151593909302929092179091558061195387611e8a565b506040805160608101825242815260208082018581528284018581526001600160a01b038e8116600081815260058652878120965187559351600180880191909155925160029096019590955560068452858320805460ff1916831790556007805492830181559092527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b0319168417905583518c1515815260ff8a1692810192909252949650929450928b16917f5c235f9dae8874242a4334347008c0a971ff3e006b75b4444854aadda93f5fa5910160405180910390a35050505050505050565b33600090815260208190526040902054600114611a6f576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03818116600090815260086020908152604091829020825180840190935254928316808352600160a01b90930460ff1615159082015290611aca57604051633fb801a560e21b815260040160405180910390fd5b6001600160a01b038216600090815260086020526040902080546001600160a81b03191690558051611afb906127a5565b80516001600160a01b03166000908152600560205260408120611b1d91612ec0565b80516001600160a01b03166000908152600660205260408120805460ff191690555b600954811015611c3a57826001600160a01b031660098281548110611b6657611b66613220565b6000918252602090912001546001600160a01b031603611c325760098054611b90906001906131fa565b81548110611ba057611ba0613220565b600091825260209091200154600980546001600160a01b039092169183908110611bcc57611bcc613220565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506009805480611c0b57611c0b6132fc565b600082815260209020810160001990810180546001600160a01b0319169055019055611c3a565b600101611b3f565b506040516001600160a01b038316907fd4bab7746d82129d0d621d803f51fe4b9961fe75c4ddfb9537ebd8f5fa283be790600090a25050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611cda57670de0b6b3a7640000611cbf6111b0565b611cc99084613312565b611cd39190613269565b9050610762565b6001600160a01b03838116600090815260086020908152604091829020825180840190935254928316808352600160a01b90930460ff161515908201529015611dd5576000806000611d2f8460000151611e8a565b9250925092506000611d5b856000015186602001518760200151611d535785611d55565b865b856128a6565b90506000611d89886040518060200160405280856001600160e01b0316815250612d3990919063ffffffff16565b90506000611d98825160701c90565b6001600160901b03169050670de0b6b3a7640000611db46111b0565b611dbe9083613312565b611dc89190613269565b9750505050505050611dee565b604051633fb801a560e21b815260040160405180910390fd5b5092915050565b60098181548110611e0557600080fd5b6000918252602090912001546001600160a01b0316905081565b60078181548110611e0557600080fd5b600a8181548110611e3f57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0391821692509081169060ff600160a01b8204811691600160a81b8104821691600160b01b9091041685565b60008080429050836001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef39190613329565b9250836001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f579190613329565b91506000806000866001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611f9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc09190613359565b925092509250838163ffffffff161461202b576000611fe563ffffffff8316866131fa565b90508063ffffffff16611ff88486612d75565b516001600160e01b031602969096019563ffffffff81166120198585612d75565b516001600160e01b0316029590950194505b5050509193909250565b60015460009060ff1661204a57506000919050565b6000600b548361205a91906131fa565b9050610e1081101561206f5750600092915050565b600061207d610e10836131fa565b9050600061208f610e106115186131fa565b905060008183116120b2576120ab83663157def08c0e38613312565b905061211f565b60006120be83856131fa565b905060006120ce61038483613269565b905060006120e46706f05b59d3b2000083612e25565b905060006120f986663157def08c0e38613312565b9050670de0b6b3a764000061210e8383613312565b6121189190613269565b9450505050505b600254670de0b6b3a76400009069d3c21bcecceda100000010156121825760025469d3c21bcecceda100000090612156818361320d565b612161836002613312565b61217390670de0b6b3a7640000613312565b61217d9190613269565b925050505b670de0b6b3a76400006121958284613312565b61219f9190613269565b979650505050505050565b8051606090429067ffffffffffffffff8111156121c9576121c961327d565b60405190808252806020026020018201604052801561220e57816020015b60408051808201909152600080825260208201528152602001906001900390816121e75790505b50915060005b835181101561241c57600084828151811061223157612231613220565b602002602001015190506000816001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561227b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229f9190613329565b90506000826001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123059190613329565b90506000806000856001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561234a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236e9190613359565b925092509250878163ffffffff16146123d957600061239363ffffffff83168a6131fa565b90508063ffffffff166123a68486612d75565b516001600160e01b031602959095019463ffffffff81166123c78585612d75565b516001600160e01b0316029490940193505b60405180604001604052808681526020018581525089888151811061240057612400613220565b6020026020010181905250866001019650505050505050612214565b50915091565b6001600160a01b03831660008181526006602090815260408083205481516060810183524281528751818501528784015181840152948452600592839052922060ff9092169291908390811061247a5761247a613220565b6003020160008201518160000155602082015181600101556040820151816002015590505060058160016124ae91906133a9565b6124b891906133c2565b6001600160a01b0385166000818152600660209081526040808320805460ff191660ff969096169590951790945586518782015185519182529181019190915292830185905290917f9a3f414f907ddb77231900d221b663199d0a42096ca010e25f0bb7292c409b4e9060600160405180910390a350505050565b60015460ff166125565760405163072e9ae360e31b815260040160405180910390fd5b6001600160a01b03821660009081526003602052604081205490612578610e18565b90508082101561259b5760405163a82c3c3960e01b815260040160405180910390fd5b826000036125a95750505050565b82600260008282546125bb919061320d565b90915550506001600160a01b038416600090815260036020526040812080548592906125e890849061320d565b90915550506040518381526001600160a01b038516907f619caafabdd75649b302ba8419e48cccf64f37f1983ac4727cfb38b57703ffc99060200160405180910390a250505050565b600080600083602001516001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612678573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269c9190613359565b5091509150600084604001516126bb57816001600160701b03166126c6565b826001600160701b03165b9050806000036126db57506000949350505050565b60008060006126ed8860200151611e8a565b925092509250600088604001519050600061271a8a6020015183846127125786612714565b875b866128a6565b90506000612750670de0b6b3a76400006040518060200160405280856001600160e01b0316815250612d3990919063ffffffff16565b9050600061275f825160701c90565b6001600160901b0316905060008c60600151601261277d9190613293565b61278890600a6134cb565b90506127948183613312565b9d9c50505050505050505050505050565b60005b6007548110156128a257816001600160a01b0316600782815481106127cf576127cf613220565b6000918252602090912001546001600160a01b03160361289a57600780546127f9906001906131fa565b8154811061280957612809613220565b600091825260209091200154600780546001600160a01b03909216918390811061283557612835613220565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506007805480612874576128746132fc565b600082815260209020810160001990810180546001600160a01b03191690550190555050565b6001016127a8565b5050565b60006128b0612ed2565b60005b6005811015612934576001600160a01b038716600090815260056020819052604090912090829081106128e8576128e8613220565b60030201604051806060016040529081600082015481526020016001820154815260200160028201548152505082826005811061292757612927613220565b60200201526001016128b3565b5060015b6005811015612a0057600082826005811061295557612955613220565b60200201519050815b60008111801561298f57508151846129776001846131fa565b6005811061298757612987613220565b602002015151105b156129de57836129a06001836131fa565b600581106129b0576129b0613220565b60200201518482600581106129c7576129c7613220565b6020020152806129d6816134da565b91505061295e565b818482600581106129f1576129f1613220565b60200201525050600101612938565b5060408051600580825260c082019092526000916020820160a08036833701905050905060008585825b6005811015612b5157858160058110612a4557612a45613220565b60200201515115612b49576000868260058110612a6457612a64613220565b602002015151612a7490846131fa565b9050610e10811080612a87575061465081115b15612a925750612b49565b60008b612ab957878360058110612aab57612aab613220565b602002015160400151612ad5565b878360058110612acb57612acb613220565b6020020151602001515b9050600082612ae483886131fa565b612aee9190613269565b905080888881518110612b0357612b03613220565b6001600160e01b039092166020928302919091019091015286612b25816132ac565b975050819550888460058110612b3d57612b3d613220565b60200201515194505050505b600101612a2a565b5082600003612b7357604051633711a2a160e01b815260040160405180910390fd5b60015b83811015612c80576000858281518110612b9257612b92613220565b6020026020010151905060008290505b600081118015612be657506001600160e01b03821687612bc36001846131fa565b81518110612bd357612bd3613220565b60200260200101516001600160e01b0316115b15612c4b5786612bf76001836131fa565b81518110612c0757612c07613220565b6020026020010151878281518110612c2157612c21613220565b6001600160e01b039092166020928302919091019091015280612c43816134da565b915050612ba2565b81878281518110612c5e57612c5e613220565b6001600160e01b03909216602092830291909101909101525050600101612b76565b50612c8c6002846132c5565b600103612cbe5783612c9f600285613269565b81518110612caf57612caf613220565b60200260200101519550612d2c565b600284612ccb8286613269565b81518110612cdb57612cdb613220565b6020026020010151856001600287612cf39190613269565b612cfd91906131fa565b81518110612d0d57612d0d613220565b6020026020010151612d1f91906134f1565b612d299190613510565b95505b5050505050949350505050565b60408051602081019091526000815260405180602001604052808385600001516001600160e01b0316612d6c9190613312565b90529392505050565b604080516020810190915260008152816001600160701b0316600003612ddd5760405162461bcd60e51b815260206004820152601760248201527f4669786564506f696e743a204449565f42595f5a45524f00000000000000000060448201526064016107ca565b604080516020810190915280612e136001600160701b0385166dffffffffffffffffffffffffffff60701b607088901b16613510565b6001600160e01b031690529392505050565b6000612e326002836132c5565b600003612e4757670de0b6b3a7640000612e49565b825b9050612e56600283613269565b91505b811561076257670de0b6b3a7640000612e728480613312565b612e7c9190613269565b9250612e896002836132c5565b15612eae57670de0b6b3a7640000612ea18483613312565b612eab9190613269565b90505b612eb9600283613269565b9150612e59565b50612ecf90600f810190612f1b565b50565b6040518060a001604052806005905b612f0560405180606001604052806000815260200160008152602001600081525090565b815260200190600190039081612ee15790505090565b5b80821115612f3d576000808255600182018190556002820155600301612f1c565b5090565b6001600160a01b0381168114612ecf57600080fd5b60008060408385031215612f6957600080fd5b8235612f7481612f41565b946020939093013593505050565b602081526000825180602084015260005b81811015612fb05760208186018101516040868401015201612f93565b506000604082850101526040601f19601f83011684010191505092915050565b600060208284031215612fe257600080fd5b8135612fed81612f41565b9392505050565b60008060006060848603121561300957600080fd5b833561301481612f41565b9250602084013561302481612f41565b929592945050506040919091013590565b8035801515811461304557600080fd5b919050565b6000806040838503121561305d57600080fd5b8235915061306d60208401613035565b90509250929050565b60008060006060848603121561308b57600080fd5b833561309681612f41565b925060208401356130a681612f41565b91506130b460408501613035565b90509250925092565b602080825282518282018190526000918401906040840190835b818110156130fe5783516001600160a01b03168352602093840193909201916001016130d7565b509095945050505050565b60006020828403121561311b57600080fd5b5035919050565b6000806040838503121561313557600080fd5b823561314081612f41565b9150602083013561315081612f41565b809150509250929050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526026908201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604082015265616c616e636560d01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610762576107626131e4565b80820180821115610762576107626131e4565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561324857600080fd5b8151612fed81612f41565b634e487b7160e01b600052601260045260246000fd5b60008261327857613278613253565b500490565b634e487b7160e01b600052604160045260246000fd5b60ff8281168282160390811115610762576107626131e4565b6000600182016132be576132be6131e4565b5060010190565b6000826132d4576132d4613253565b500690565b6000602082840312156132eb57600080fd5b815160ff81168114612fed57600080fd5b634e487b7160e01b600052603160045260246000fd5b8082028115828204841417610762576107626131e4565b60006020828403121561333b57600080fd5b5051919050565b80516001600160701b038116811461304557600080fd5b60008060006060848603121561336e57600080fd5b61337784613342565b925061338560208501613342565b9150604084015163ffffffff8116811461339e57600080fd5b809150509250925092565b60ff8181168382160190811115610762576107626131e4565b600060ff8316806133d5576133d5613253565b8060ff84160691505092915050565b6001815b600184111561341f57808504811115613403576134036131e4565b600184161561341157908102905b60019390931c9280026133e8565b935093915050565b60008261343657506001610762565b8161344357506000610762565b816001811461345957600281146134635761347f565b6001915050610762565b60ff841115613474576134746131e4565b50506001821b610762565b5060208310610133831016604e8410600b84101617156134a2575081810a610762565b6134af60001984846133e4565b80600019048211156134c3576134c36131e4565b029392505050565b6000612fed60ff841683613427565b6000816134e9576134e96131e4565b506000190190565b6001600160e01b038181168382160190811115610762576107626131e4565b60006001600160e01b0383168061352957613529613253565b6001600160e01b0392909216919091049291505056fea2646970667358221220973a70be6b8260c2aa755c38e02c9606a239ca7b60762d2d35b51fe64c49ae5564736f6c634300081c0033000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102745760003560e01c80638aec854211610151578063b5fcf194116100c3578063d2fd9f6c11610087578063d2fd9f6c14610591578063d525ed09146105a4578063dd62ed3e146105b7578063deb96634146105e2578063e837d9a9146105eb578063fc9654ab146103ce57600080fd5b8063b5fcf194146104ef578063bf353dbb14610502578063bf608cce14610522578063cdd00f6914610576578063d0578a011461057e57600080fd5b80639c52a7f1116101155780639c52a7f1146104915780639e5702be146104a4578063a4ef1357146104ac578063a9059cbb146104b4578063aa6ca808146104c7578063b1d06528146104dc57600080fd5b80638aec854214610439578063927ef7fa146104415780639586a5421461048057806395d89b41146102b657806399f91f4f1461048857600080fd5b806323b872dd116101ea57806352b65c4b116101ae57806352b65c4b146103ce57806362e2c848146103d757806365fae35e146103ea5780636b598bbe146103fd57806370a0823114610410578063802fe35d1461043057600080fd5b806323b872dd146103915780632cefe72c146103a45780632ff2e9dc146103ad578063313ce567146103be5780634ae7ee1d146103c657600080fd5b80630e8e81271161023c5780630e8e81271461032557806318160ddd1461032e5780631c0541bd146103375780631dafe16b1461036c5780631de40e49146103795780631e9d49041461038857600080fd5b806301339c2114610279578063024599661461028357806306fdde03146102b6578063095ea7b3146102e65780630e40fe9f14610309575b600080fd5b61028161063b565b005b610296610291366004612f56565b6106c5565b604080519384526020840192909252908201526060015b60405180910390f35b6102d9604051806040016040528060048152602001630545741560e41b81525081565b6040516102ad9190612f82565b6102f96102f4366004612f56565b6106fb565b60405190151581526020016102ad565b610317663157def08c0e3881565b6040519081526020016102ad565b61031761151881565b61031760025481565b61035a610345366004612fd0565b60066020526000908152604090205460ff1681565b60405160ff90911681526020016102ad565b6001546102f99060ff1681565b6103176706f05b59d3b2000081565b61031761038481565b6102f961039f366004612ff4565b610768565b61031761022b81565b61031769d3c21bcecceda100000081565b61035a601281565b600954610317565b610317610e1081565b6102816103e536600461304a565b61098f565b6102816103f8366004612fd0565b610a7b565b61028161040b366004613076565b610aef565b61031761041e366004612fd0565b60036020526000908152604090205481565b610317600b5481565b610317610e08565b6104687f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2781565b6040516001600160a01b0390911681526020016102ad565b610317610e18565b610317611c2081565b61028161049f366004612fd0565b610e2a565b610281610e9d565b6103176111b0565b6102f96104c2366004612f56565b6114a8565b6104cf61158d565b6040516102ad91906130bd565b6102816104ea366004613076565b6115ef565b6102816104fd366004612fd0565b611a40565b610317610510366004612fd0565b60006020819052908152604090205481565b610557610530366004612fd0565b6008602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b0390931683529015156020830152016102ad565b600a54610317565b61031761058c366004612f56565b611c73565b61046861059f366004613109565b611df5565b6104686105b2366004613109565b611e1f565b6103176105c5366004613122565b600460209081526000928352604080842090915290825290205481565b61031761465081565b6105fe6105f9366004613109565b611e2f565b604080516001600160a01b0396871681529590941660208601529115159284019290925260ff90911660608301521515608082015260a0016102ad565b3360009081526020819052604090205460011461066a576040516282b42960e81b815260040160405180910390fd5b60015460ff161561068e576040516319f4db0f60e31b815260040160405180910390fd5b6001805460ff1916811790556040517fa4d24b6714a5db779b2a933bdca578dbf6e9380ae4de745e84d4a6dd457204d590600090a1565b600560205281600052604060002081600581106106e157600080fd5b600302018054600182015460029092015490935090915083565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906107569086815260200190565b60405180910390a35060015b92915050565b60006001600160a01b0384166107d35760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084015b60405180910390fd5b6001600160a01b0383166107f95760405162461bcd60e51b81526004016107ca9061315b565b6001600160a01b0384166000908152600360205260409020548211156108315760405162461bcd60e51b81526004016107ca9061319e565b6001600160a01b03841660009081526004602090815260408083203384529091529020548211156108a45760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016107ca565b6001600160a01b038416600090815260036020526040812080548492906108cc9084906131fa565b90915550506001600160a01b038316600090815260036020526040812080548492906108f990849061320d565b90915550506001600160a01b0384166000908152600460209081526040808320338452909152812080548492906109319084906131fa565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161097d91815260200190565b60405180910390a35060019392505050565b336000908152602081905260409020546001146109be576040516282b42960e81b815260040160405180910390fd5b600a5482106109ff5760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064016107ca565b80600a8381548110610a1357610a13613220565b906000526020600020906002020160010160166101000a81548160ff021916908315150217905550817f1023261e84bada852098da9e423248e8fc3184408932bed6e2050195c13cfad982604051610a6f911515815260200190565b60405180910390a25050565b33600090815260208190526040902054600114610aaa576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b33600090815260208190526040902054600114610b1e576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038381166000908152600860205260409020541615610b575760405163a5d832e360e01b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190613236565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c219190613236565b9050828015610c425750846001600160a01b0316826001600160a01b031614155b80610c68575082158015610c685750846001600160a01b0316816001600160a01b031614155b15610c8657604051630793df6360e21b815260040160405180910390fd5b6040805180820182526001600160a01b0380871682528515156020808401918252898316600081815260089092529481209351845492511515600160a01b026001600160a81b031990931693169290921717909155600980546001810182559082527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b03191690921790915580610d2686611e8a565b506040805160608101825242815260208082018581528284018581526001600160a01b038d8116600081815260058652878120965187559351600180880191909155925160029096019590955560068452858320805460ff1916831790556007805492830181559092527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b0319168417905592518a1515815294965092945092908a16917f5b99e368449b8061a5e6c9aa2ba8d3557d64befc230df2b329603e412e721abb910160405180910390a350505050505050565b6000610e1342612035565b905090565b600061022b600254610e139190613269565b33600090815260208190526040902054600114610e59576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b600b544290610e1090610eb090836131fa565b1015610ecf5760405163f0aaee6560e01b815260040160405180910390fd5b60075460008167ffffffffffffffff811115610eed57610eed61327d565b604051908082528060200260200182016040528015610f16578160200160208202803683370190505b5090506000805b8381101561101857600060078281548110610f3a57610f3a613220565b60009182526020808320909101546001600160a01b03168083526006909152604082205490925060ff16908115610f7b57610f76600183613293565b610f7e565b60045b9050610e1060056000856001600160a01b03166001600160a01b031681526020019081526020016000208260ff1660058110610fbc57610fbc613220565b6003020154610fcb908a6131fa565b1061100a5782868681518110610fe357610fe3613220565b60200260200101906001600160a01b031690816001600160a01b0316815250508460010194505b836001019350505050610f1d565b50801561116c5760008167ffffffffffffffff81111561103a5761103a61327d565b604051908082528060200260200182016040528015611063578160200160208202803683370190505b50905060005b828110156110bd5783818151811061108357611083613220565b602002602001015182828151811061109d5761109d613220565b6001600160a01b0390921660209283029190910190910152600101611069565b5060006110c9826121aa565b50905060005b8381101561111c576111148382815181106110ec576110ec613220565b602002602001015183838151811061110657611106613220565b602002602001015189612422565b6001016110cf565b5060015460ff1680156111455750611132610e18565b3360009081526003602052604090205410155b1561116957600061115587612035565b90508015611167576111673382612533565b505b50505b600b84905560408051858152602081018390527f3a00c122e9fd49a4a88111ff00ae627346ec777223f410d9c595b32348ca4958910160405180910390a150505050565b600a546000908190819067ffffffffffffffff8111156111d2576111d261327d565b6040519080825280602002602001820160405280156111fb578160200160208202803683370190505b50905060005b600a548110156112f1576000600a828154811061122057611220613220565b60009182526020918290206040805160a081018252600290930290910180546001600160a01b0390811684526001909101549081169383019390935260ff600160a01b84048116151591830191909152600160a81b830481166060830152600160b01b90920490911615156080820181905290915061129f57506112e9565b60006112aa82612631565b9050806000036112bb5750506112e9565b808486815181106112ce576112ce613220565b6020908102919091010152846112e3816132ac565b95505050505b600101611201565b508160000361131357604051630f5ac0cb60e01b815260040160405180910390fd5b60005b828110156113f857600061132b82600161320d565b90505b838110156113ef5782818151811061134857611348613220565b602002602001015183838151811061136257611362613220565b602002602001015111156113e757600083838151811061138457611384613220565b602002602001015190508382815181106113a0576113a0613220565b60200260200101518484815181106113ba576113ba613220565b602002602001018181525050808483815181106113d9576113d9613220565b602002602001018181525050505b60010161132e565b50600101611316565b506114046002836132c5565b6001036114365780611417600284613269565b8151811061142757611427613220565b60200260200101519250505090565b6002816114438285613269565b8151811061145357611453613220565b602002602001015182600160028661146b9190613269565b61147591906131fa565b8151811061148557611485613220565b6020026020010151611497919061320d565b6114a19190613269565b9250505090565b60006001600160a01b0383166114d05760405162461bcd60e51b81526004016107ca9061315b565b336000908152600360205260409020548211156114ff5760405162461bcd60e51b81526004016107ca9061319e565b336000908152600360205260408120805484929061151e9084906131fa565b90915550506001600160a01b0383166000908152600360205260408120805484929061154b90849061320d565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610756565b606060098054806020026020016040519081016040528092919081815260200182805480156115e557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116115c7575b5050505050905090565b3360009081526020819052604090205460011461161e576040516282b42960e81b815260040160405180910390fd5b6000826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561165e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116829190613236565b90506000836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e89190613236565b905082801561172957507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316826001600160a01b031614155b8061176f57508215801561176f57507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316816001600160a01b031614155b1561178d57604051630793df6360e21b815260040160405180910390fd5b6000856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f191906132d9565b905060128160ff16111561183d5760405162461bcd60e51b81526020600482015260136024820152720a6e8c2c4d8ca40c8cac6d2dac2d8e6407c627606b1b60448201526064016107ca565b6040805160a0810182526001600160a01b0388811682528781166020830190815287151593830193845260ff85811660608501908152600160808601818152600a80549283018155600090815296517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8600290930292830180546001600160a01b03191691881691909117905593517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a99091018054975192519451919095166001600160a81b031990971696909617600160a01b911515919091021761ffff60a81b1916600160a81b929091169190910260ff60b01b191617600160b01b93151593909302929092179091558061195387611e8a565b506040805160608101825242815260208082018581528284018581526001600160a01b038e8116600081815260058652878120965187559351600180880191909155925160029096019590955560068452858320805460ff1916831790556007805492830181559092527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b0319168417905583518c1515815260ff8a1692810192909252949650929450928b16917f5c235f9dae8874242a4334347008c0a971ff3e006b75b4444854aadda93f5fa5910160405180910390a35050505050505050565b33600090815260208190526040902054600114611a6f576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03818116600090815260086020908152604091829020825180840190935254928316808352600160a01b90930460ff1615159082015290611aca57604051633fb801a560e21b815260040160405180910390fd5b6001600160a01b038216600090815260086020526040902080546001600160a81b03191690558051611afb906127a5565b80516001600160a01b03166000908152600560205260408120611b1d91612ec0565b80516001600160a01b03166000908152600660205260408120805460ff191690555b600954811015611c3a57826001600160a01b031660098281548110611b6657611b66613220565b6000918252602090912001546001600160a01b031603611c325760098054611b90906001906131fa565b81548110611ba057611ba0613220565b600091825260209091200154600980546001600160a01b039092169183908110611bcc57611bcc613220565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506009805480611c0b57611c0b6132fc565b600082815260209020810160001990810180546001600160a01b0319169055019055611c3a565b600101611b3f565b506040516001600160a01b038316907fd4bab7746d82129d0d621d803f51fe4b9961fe75c4ddfb9537ebd8f5fa283be790600090a25050565b60007f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316836001600160a01b031603611cda57670de0b6b3a7640000611cbf6111b0565b611cc99084613312565b611cd39190613269565b9050610762565b6001600160a01b03838116600090815260086020908152604091829020825180840190935254928316808352600160a01b90930460ff161515908201529015611dd5576000806000611d2f8460000151611e8a565b9250925092506000611d5b856000015186602001518760200151611d535785611d55565b865b856128a6565b90506000611d89886040518060200160405280856001600160e01b0316815250612d3990919063ffffffff16565b90506000611d98825160701c90565b6001600160901b03169050670de0b6b3a7640000611db46111b0565b611dbe9083613312565b611dc89190613269565b9750505050505050611dee565b604051633fb801a560e21b815260040160405180910390fd5b5092915050565b60098181548110611e0557600080fd5b6000918252602090912001546001600160a01b0316905081565b60078181548110611e0557600080fd5b600a8181548110611e3f57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0391821692509081169060ff600160a01b8204811691600160a81b8104821691600160b01b9091041685565b60008080429050836001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef39190613329565b9250836001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f579190613329565b91506000806000866001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611f9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc09190613359565b925092509250838163ffffffff161461202b576000611fe563ffffffff8316866131fa565b90508063ffffffff16611ff88486612d75565b516001600160e01b031602969096019563ffffffff81166120198585612d75565b516001600160e01b0316029590950194505b5050509193909250565b60015460009060ff1661204a57506000919050565b6000600b548361205a91906131fa565b9050610e1081101561206f5750600092915050565b600061207d610e10836131fa565b9050600061208f610e106115186131fa565b905060008183116120b2576120ab83663157def08c0e38613312565b905061211f565b60006120be83856131fa565b905060006120ce61038483613269565b905060006120e46706f05b59d3b2000083612e25565b905060006120f986663157def08c0e38613312565b9050670de0b6b3a764000061210e8383613312565b6121189190613269565b9450505050505b600254670de0b6b3a76400009069d3c21bcecceda100000010156121825760025469d3c21bcecceda100000090612156818361320d565b612161836002613312565b61217390670de0b6b3a7640000613312565b61217d9190613269565b925050505b670de0b6b3a76400006121958284613312565b61219f9190613269565b979650505050505050565b8051606090429067ffffffffffffffff8111156121c9576121c961327d565b60405190808252806020026020018201604052801561220e57816020015b60408051808201909152600080825260208201528152602001906001900390816121e75790505b50915060005b835181101561241c57600084828151811061223157612231613220565b602002602001015190506000816001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561227b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229f9190613329565b90506000826001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123059190613329565b90506000806000856001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561234a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236e9190613359565b925092509250878163ffffffff16146123d957600061239363ffffffff83168a6131fa565b90508063ffffffff166123a68486612d75565b516001600160e01b031602959095019463ffffffff81166123c78585612d75565b516001600160e01b0316029490940193505b60405180604001604052808681526020018581525089888151811061240057612400613220565b6020026020010181905250866001019650505050505050612214565b50915091565b6001600160a01b03831660008181526006602090815260408083205481516060810183524281528751818501528784015181840152948452600592839052922060ff9092169291908390811061247a5761247a613220565b6003020160008201518160000155602082015181600101556040820151816002015590505060058160016124ae91906133a9565b6124b891906133c2565b6001600160a01b0385166000818152600660209081526040808320805460ff191660ff969096169590951790945586518782015185519182529181019190915292830185905290917f9a3f414f907ddb77231900d221b663199d0a42096ca010e25f0bb7292c409b4e9060600160405180910390a350505050565b60015460ff166125565760405163072e9ae360e31b815260040160405180910390fd5b6001600160a01b03821660009081526003602052604081205490612578610e18565b90508082101561259b5760405163a82c3c3960e01b815260040160405180910390fd5b826000036125a95750505050565b82600260008282546125bb919061320d565b90915550506001600160a01b038416600090815260036020526040812080548592906125e890849061320d565b90915550506040518381526001600160a01b038516907f619caafabdd75649b302ba8419e48cccf64f37f1983ac4727cfb38b57703ffc99060200160405180910390a250505050565b600080600083602001516001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612678573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269c9190613359565b5091509150600084604001516126bb57816001600160701b03166126c6565b826001600160701b03165b9050806000036126db57506000949350505050565b60008060006126ed8860200151611e8a565b925092509250600088604001519050600061271a8a6020015183846127125786612714565b875b866128a6565b90506000612750670de0b6b3a76400006040518060200160405280856001600160e01b0316815250612d3990919063ffffffff16565b9050600061275f825160701c90565b6001600160901b0316905060008c60600151601261277d9190613293565b61278890600a6134cb565b90506127948183613312565b9d9c50505050505050505050505050565b60005b6007548110156128a257816001600160a01b0316600782815481106127cf576127cf613220565b6000918252602090912001546001600160a01b03160361289a57600780546127f9906001906131fa565b8154811061280957612809613220565b600091825260209091200154600780546001600160a01b03909216918390811061283557612835613220565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506007805480612874576128746132fc565b600082815260209020810160001990810180546001600160a01b03191690550190555050565b6001016127a8565b5050565b60006128b0612ed2565b60005b6005811015612934576001600160a01b038716600090815260056020819052604090912090829081106128e8576128e8613220565b60030201604051806060016040529081600082015481526020016001820154815260200160028201548152505082826005811061292757612927613220565b60200201526001016128b3565b5060015b6005811015612a0057600082826005811061295557612955613220565b60200201519050815b60008111801561298f57508151846129776001846131fa565b6005811061298757612987613220565b602002015151105b156129de57836129a06001836131fa565b600581106129b0576129b0613220565b60200201518482600581106129c7576129c7613220565b6020020152806129d6816134da565b91505061295e565b818482600581106129f1576129f1613220565b60200201525050600101612938565b5060408051600580825260c082019092526000916020820160a08036833701905050905060008585825b6005811015612b5157858160058110612a4557612a45613220565b60200201515115612b49576000868260058110612a6457612a64613220565b602002015151612a7490846131fa565b9050610e10811080612a87575061465081115b15612a925750612b49565b60008b612ab957878360058110612aab57612aab613220565b602002015160400151612ad5565b878360058110612acb57612acb613220565b6020020151602001515b9050600082612ae483886131fa565b612aee9190613269565b905080888881518110612b0357612b03613220565b6001600160e01b039092166020928302919091019091015286612b25816132ac565b975050819550888460058110612b3d57612b3d613220565b60200201515194505050505b600101612a2a565b5082600003612b7357604051633711a2a160e01b815260040160405180910390fd5b60015b83811015612c80576000858281518110612b9257612b92613220565b6020026020010151905060008290505b600081118015612be657506001600160e01b03821687612bc36001846131fa565b81518110612bd357612bd3613220565b60200260200101516001600160e01b0316115b15612c4b5786612bf76001836131fa565b81518110612c0757612c07613220565b6020026020010151878281518110612c2157612c21613220565b6001600160e01b039092166020928302919091019091015280612c43816134da565b915050612ba2565b81878281518110612c5e57612c5e613220565b6001600160e01b03909216602092830291909101909101525050600101612b76565b50612c8c6002846132c5565b600103612cbe5783612c9f600285613269565b81518110612caf57612caf613220565b60200260200101519550612d2c565b600284612ccb8286613269565b81518110612cdb57612cdb613220565b6020026020010151856001600287612cf39190613269565b612cfd91906131fa565b81518110612d0d57612d0d613220565b6020026020010151612d1f91906134f1565b612d299190613510565b95505b5050505050949350505050565b60408051602081019091526000815260405180602001604052808385600001516001600160e01b0316612d6c9190613312565b90529392505050565b604080516020810190915260008152816001600160701b0316600003612ddd5760405162461bcd60e51b815260206004820152601760248201527f4669786564506f696e743a204449565f42595f5a45524f00000000000000000060448201526064016107ca565b604080516020810190915280612e136001600160701b0385166dffffffffffffffffffffffffffff60701b607088901b16613510565b6001600160e01b031690529392505050565b6000612e326002836132c5565b600003612e4757670de0b6b3a7640000612e49565b825b9050612e56600283613269565b91505b811561076257670de0b6b3a7640000612e728480613312565b612e7c9190613269565b9250612e896002836132c5565b15612eae57670de0b6b3a7640000612ea18483613312565b612eab9190613269565b90505b612eb9600283613269565b9150612e59565b50612ecf90600f810190612f1b565b50565b6040518060a001604052806005905b612f0560405180606001604052806000815260200160008152602001600081525090565b815260200190600190039081612ee15790505090565b5b80821115612f3d576000808255600182018190556002820155600301612f1c565b5090565b6001600160a01b0381168114612ecf57600080fd5b60008060408385031215612f6957600080fd5b8235612f7481612f41565b946020939093013593505050565b602081526000825180602084015260005b81811015612fb05760208186018101516040868401015201612f93565b506000604082850101526040601f19601f83011684010191505092915050565b600060208284031215612fe257600080fd5b8135612fed81612f41565b9392505050565b60008060006060848603121561300957600080fd5b833561301481612f41565b9250602084013561302481612f41565b929592945050506040919091013590565b8035801515811461304557600080fd5b919050565b6000806040838503121561305d57600080fd5b8235915061306d60208401613035565b90509250929050565b60008060006060848603121561308b57600080fd5b833561309681612f41565b925060208401356130a681612f41565b91506130b460408501613035565b90509250925092565b602080825282518282018190526000918401906040840190835b818110156130fe5783516001600160a01b03168352602093840193909201916001016130d7565b509095945050505050565b60006020828403121561311b57600080fd5b5035919050565b6000806040838503121561313557600080fd5b823561314081612f41565b9150602083013561315081612f41565b809150509250929050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526026908201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604082015265616c616e636560d01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610762576107626131e4565b80820180821115610762576107626131e4565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561324857600080fd5b8151612fed81612f41565b634e487b7160e01b600052601260045260246000fd5b60008261327857613278613253565b500490565b634e487b7160e01b600052604160045260246000fd5b60ff8281168282160390811115610762576107626131e4565b6000600182016132be576132be6131e4565b5060010190565b6000826132d4576132d4613253565b500690565b6000602082840312156132eb57600080fd5b815160ff81168114612fed57600080fd5b634e487b7160e01b600052603160045260246000fd5b8082028115828204841417610762576107626131e4565b60006020828403121561333b57600080fd5b5051919050565b80516001600160701b038116811461304557600080fd5b60008060006060848603121561336e57600080fd5b61337784613342565b925061338560208501613342565b9150604084015163ffffffff8116811461339e57600080fd5b809150509250925092565b60ff8181168382160190811115610762576107626131e4565b600060ff8316806133d5576133d5613253565b8060ff84160691505092915050565b6001815b600184111561341f57808504811115613403576134036131e4565b600184161561341157908102905b60019390931c9280026133e8565b935093915050565b60008261343657506001610762565b8161344357506000610762565b816001811461345957600281146134635761347f565b6001915050610762565b60ff841115613474576134746131e4565b50506001821b610762565b5060208310610133831016604e8410600b84101617156134a2575081810a610762565b6134af60001984846133e4565b80600019048211156134c3576134c36131e4565b029392505050565b6000612fed60ff841683613427565b6000816134e9576134e96131e4565b506000190190565b6001600160e01b038181168382160190811115610762576107626131e4565b60006001600160e01b0383168061352957613529613253565b6001600160e01b0392909216919091049291505056fea2646970667358221220973a70be6b8260c2aa755c38e02c9606a239ca7b60762d2d35b51fe64c49ae5564736f6c634300081c0033