Overview
ETH Balance
ETH Value
$0.00Latest 10 from a total of 10 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Create Pair | 22998415 | 139 days ago | IN | 0 ETH | 0.00018074 | ||||
| Create Pair | 22998414 | 139 days ago | IN | 0 ETH | 0.00018072 | ||||
| Create Pair | 22998413 | 139 days ago | IN | 0 ETH | 0.00018029 | ||||
| Set Fee | 3545952 | 654 days ago | IN | 0 ETH | 0.00001312 | ||||
| Set Fee | 3545941 | 654 days ago | IN | 0 ETH | 0.00001312 | ||||
| Set Fee | 3514862 | 656 days ago | IN | 0 ETH | 0.00001312 | ||||
| Set Fee | 3498667 | 656 days ago | IN | 0 ETH | 0.00001312 | ||||
| Create Pair | 2207778 | 712 days ago | IN | 0 ETH | 0.01121052 | ||||
| Set Dibs | 2202428 | 713 days ago | IN | 0 ETH | 0.00015225 | ||||
| Set Referral Fee | 2202428 | 713 days ago | IN | 0 ETH | 0.00009232 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 28263781 | 5 mins ago | 0 ETH | ||||
| 28263781 | 5 mins ago | 0 ETH | ||||
| 28263320 | 21 mins ago | 0 ETH | ||||
| 28263319 | 21 mins ago | 0 ETH | ||||
| 28263319 | 21 mins ago | 0 ETH | ||||
| 28263319 | 21 mins ago | 0 ETH | ||||
| 28263319 | 21 mins ago | 0 ETH | ||||
| 28263160 | 27 mins ago | 0 ETH | ||||
| 28263160 | 27 mins ago | 0 ETH | ||||
| 28263110 | 28 mins ago | 0 ETH | ||||
| 28263110 | 28 mins ago | 0 ETH | ||||
| 28263103 | 28 mins ago | 0 ETH | ||||
| 28263103 | 28 mins ago | 0 ETH | ||||
| 28263103 | 28 mins ago | 0 ETH | ||||
| 28263103 | 28 mins ago | 0 ETH | ||||
| 28262805 | 39 mins ago | 0 ETH | ||||
| 28262805 | 39 mins ago | 0 ETH | ||||
| 28262659 | 44 mins ago | 0 ETH | ||||
| 28261867 | 1 hr ago | 0 ETH | ||||
| 28261829 | 1 hr ago | 0 ETH | ||||
| 28261829 | 1 hr ago | 0 ETH | ||||
| 28261778 | 1 hr ago | 0 ETH | ||||
| 28261778 | 1 hr ago | 0 ETH | ||||
| 28261778 | 1 hr ago | 0 ETH | ||||
| 28261778 | 1 hr ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PairFactory
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import '../interfaces/IPairFactory.sol';
import '../Pair.sol';
contract PairFactory is IPairFactory {
uint256 public stableFee;
uint256 public volatileFee;
uint256 public REFERRAL_FEE_LIMIT = 2000; // 20%
uint256 public MAX_REFERRAL_FEE = 0; // 12%
uint256 public constant MAX_FEE = 25; // 0.25%
address public feeManager;
address public pendingFeeManager;
address public dibs; // referral fee handler
mapping(address => mapping(address => mapping(bool => address))) public getPair;
address[] public allPairs;
mapping(address => bool) public isPair; // simplified check if its a pair, given that `stable` flag might not be available in peripherals
address internal _temp0;
address internal _temp1;
bool internal _temp;
event PairCreated(address indexed token0, address indexed token1, bool stable, address pair, uint);
constructor() {
feeManager = msg.sender;
stableFee = 4; // 0.04%
volatileFee = 18; // 0.18%
}
function allPairsLength() external view returns (uint) {
return allPairs.length;
}
function pairs() external view returns(address[] memory ){
return allPairs;
}
function setFeeManager(address _feeManager) external {
require(msg.sender == feeManager, 'not fee manager');
pendingFeeManager = _feeManager;
}
function acceptFeeManager() external {
require(msg.sender == pendingFeeManager, 'not pending fee manager');
feeManager = pendingFeeManager;
}
function setDibs(address _dibs) external {
require(msg.sender == feeManager, 'not fee manager');
require(_dibs != address(0), 'address zero');
dibs = _dibs;
}
function setReferralFee(uint256 _refFee) external {
require(msg.sender == feeManager, 'not fee manager');
require(_refFee <= REFERRAL_FEE_LIMIT, "Above fee limit");
MAX_REFERRAL_FEE = _refFee;
}
function setFee(bool _stable, uint256 _fee) external {
require(msg.sender == feeManager, 'not fee manager');
require(_fee <= MAX_FEE, 'fee too high');
require(_fee != 0, 'fee must be nonzero');
if (_stable) {
stableFee = _fee;
} else {
volatileFee = _fee;
}
}
function getFee(bool _stable) public view returns(uint256) {
return _stable ? stableFee : volatileFee;
}
function pairCodeHash() external pure returns (bytes32) {
return keccak256(type(Pair).creationCode);
}
function getInitializable() external view returns (address, address, bool) {
return (_temp0, _temp1, _temp);
}
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair) {
require(tokenA != tokenB, 'IA'); // Pair: IDENTICAL_ADDRESSES
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'ZA'); // Pair: ZERO_ADDRESS
require(getPair[token0][token1][stable] == address(0), 'PE'); // Pair: PAIR_EXISTS - single check is sufficient
bytes32 salt = keccak256(abi.encodePacked(token0, token1, stable)); // notice salt includes stable as well, 3 parameters
(_temp0, _temp1, _temp) = (token0, token1, stable);
pair = address(new Pair{salt:salt}());
getPair[token0][token1][stable] = pair;
getPair[token1][token0][stable] = pair; // populate mapping in the reverse direction
allPairs.push(pair);
isPair[pair] = true;
emit PairCreated(token0, token1, stable, pair, allPairs.length);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IDibs {
function reward(address user,bytes32 parentCode,
uint256 totalFees,uint256 totalVolume,
address token) external returns(uint256 referralFee);
function findTotalRewardFor(address _user, uint _totalFees) external view returns(uint256 _referralFeeAmount);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IERC20 {
function totalSupply() external view returns (uint256);
function transfer(address recipient, uint amount) external returns (bool);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function balanceOf(address) external view returns (uint);
function transferFrom(address sender, address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IPair {
function metadata() external view returns (uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1);
function claimFees() external returns (uint, uint);
function tokens() external view returns (address, address);
function token0() external view returns (address);
function token1() external view returns (address);
function transferFrom(address src, address dst, uint amount) external returns (bool);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function burn(address to) external returns (uint amount0, uint amount1);
function mint(address to) external returns (uint liquidity);
function getReserves() external view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast);
function getAmountOut(uint, address) external view returns (uint);
function name() external view returns(string memory);
function symbol() external view returns(string memory);
function totalSupply() external view returns (uint);
function decimals() external view returns (uint8);
function claimable0(address _user) external view returns (uint);
function claimable1(address _user) external view returns (uint);
function isStable() external view returns(bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IPairCallee {
function hook(address sender, uint amount0, uint amount1, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IPairFactory {
function allPairsLength() external view returns (uint);
function isPair(address pair) external view returns (bool);
function allPairs(uint index) external view returns (address);
function pairCodeHash() external pure returns (bytes32);
function getPair(address tokenA, address token, bool stable) external view returns (address);
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair);
function MAX_REFERRAL_FEE() external view returns(uint);
function dibs() external view returns(address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
library Math {
function max(uint a, uint b) internal pure returns (uint) {
return a >= b ? a : b;
}
function min(uint a, uint b) internal pure returns (uint) {
return a < b ? a : b;
}
function sqrt(uint y) internal pure returns (uint z) {
if (y > 3) {
z = y;
uint x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
function cbrt(uint256 n) internal pure returns (uint256) { unchecked {
uint256 x = 0;
for (uint256 y = 1 << 255; y > 0; y >>= 3) {
x <<= 1;
uint256 z = 3 * x * (x + 1) + 1;
if (n / y >= z) {
n -= y * z;
x += 1;
}
}
return x;
}}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, 'Math: Sub-underflow');
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import "./libraries/Math.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/IPair.sol";
import "./interfaces/IDibs.sol";
import "./interfaces/IPairCallee.sol";
import "./factories/PairFactory.sol";
import "./PairFees.sol";
// The base pair of pools, either stable or volatile
contract Pair is IPair {
string public name;
string public symbol;
uint8 public constant decimals = 18;
// Used to denote stable or volatile pair, not immutable since construction happens in the initialize method for CREATE2 deterministic addresses
bool public immutable stable;
uint public totalSupply = 0;
mapping(address => mapping (address => uint)) public allowance;
mapping(address => uint) public balanceOf;
bytes32 internal DOMAIN_SEPARATOR;
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32 internal constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
mapping(address => uint) public nonces;
uint internal constant MINIMUM_LIQUIDITY = 10**3;
address public immutable token0;
address public immutable token1;
address public immutable fees;
address immutable factory;
// Structure to capture time period obervations every 30 minutes, used for local oracles
struct Observation {
uint timestamp;
uint reserve0Cumulative;
uint reserve1Cumulative;
}
// Capture oracle reading every 30 minutes
uint constant periodSize = 1800;
Observation[] public observations;
uint internal immutable decimals0;
uint internal immutable decimals1;
uint public reserve0;
uint public reserve1;
uint public blockTimestampLast;
uint public reserve0CumulativeLast;
uint public reserve1CumulativeLast;
// index0 and index1 are used to accumulate fees, this is split out from normal trades to keep the swap "clean"
// this further allows LP holders to easily claim fees for tokens they have/staked
uint public index0 = 0;
uint public index1 = 0;
// position assigned to each LP to track their current index0 & index1 vs the global position
mapping(address => uint) public supplyIndex0;
mapping(address => uint) public supplyIndex1;
// tracks the amount of unclaimed, but claimable tokens off of fees for token0 and token1
mapping(address => uint) public claimable0;
mapping(address => uint) public claimable1;
event Fees(address indexed sender, uint amount0, uint amount1);
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint reserve0, uint reserve1);
event Claim(address indexed sender, address indexed recipient, uint amount0, uint amount1);
event Transfer(address indexed from, address indexed to, uint amount);
event Approval(address indexed owner, address indexed spender, uint amount);
constructor() {
factory = msg.sender;
(address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable();
(token0, token1, stable) = (_token0, _token1, _stable);
fees = address(new PairFees(_token0, _token1));
if (_stable) {
name = string(abi.encodePacked("StableV1 AMM - ", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol()));
symbol = string(abi.encodePacked("sAMM-", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol()));
} else {
name = string(abi.encodePacked("VolatileV1 AMM - ", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol()));
symbol = string(abi.encodePacked("vAMM-", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol()));
}
decimals0 = 10**IERC20(_token0).decimals();
decimals1 = 10**IERC20(_token1).decimals();
observations.push(Observation(block.timestamp, 0, 0));
}
// simple re-entrancy check
uint internal _unlocked = 1;
modifier lock() {
require(_unlocked == 1);
_unlocked = 2;
_;
_unlocked = 1;
}
function observationLength() external view returns (uint) {
return observations.length;
}
function lastObservation() public view returns (Observation memory) {
return observations[observations.length-1];
}
function metadata() external view returns (uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1) {
return (decimals0, decimals1, reserve0, reserve1, stable, token0, token1);
}
function tokens() external view returns (address, address) {
return (token0, token1);
}
function isStable() external view returns(bool) {
return stable;
}
// claim accumulated but unclaimed fees (viewable via claimable0 and claimable1)
function claimFees() external returns (uint claimed0, uint claimed1) {
_updateFor(msg.sender);
claimed0 = claimable0[msg.sender];
claimed1 = claimable1[msg.sender];
if (claimed0 > 0 || claimed1 > 0) {
claimable0[msg.sender] = 0;
claimable1[msg.sender] = 0;
PairFees(fees).claimFeesFor(msg.sender, claimed0, claimed1);
emit Claim(msg.sender, msg.sender, claimed0, claimed1);
}
}
// Accrue fees on token0
function _update0(uint amount) internal {
_safeTransfer(token0, fees, amount); // transfer the fees out to PairFees
uint256 _ratio = amount * 1e18 / totalSupply; // 1e18 adjustment is removed during claim
if (_ratio > 0) {
index0 += _ratio;
}
emit Fees(msg.sender, amount, 0);
}
// Accrue fees on token1
function _update1(uint amount) internal {
_safeTransfer(token1, fees, amount); // transfer the fees out to PairFees
uint256 _ratio = amount * 1e18 / totalSupply;
if (_ratio > 0) {
index1 += _ratio;
}
emit Fees(msg.sender, 0, amount);
}
// this function MUST be called on any balance changes, otherwise can be used to infinitely claim fees
// Fees are segregated from core funds, so fees can never put liquidity at risk
function _updateFor(address recipient) internal {
uint _supplied = balanceOf[recipient]; // get LP balance of `recipient`
if (_supplied > 0) {
uint _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient
uint _supplyIndex1 = supplyIndex1[recipient];
uint _index0 = index0; // get global index0 for accumulated fees
uint _index1 = index1;
supplyIndex0[recipient] = _index0; // update user current position to global position
supplyIndex1[recipient] = _index1;
uint _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued
uint _delta1 = _index1 - _supplyIndex1;
if (_delta0 > 0) {
uint _share = _supplied * _delta0 / 1e18; // add accrued difference for each supplied token
claimable0[recipient] += _share;
}
if (_delta1 > 0) {
uint _share = _supplied * _delta1 / 1e18;
claimable1[recipient] += _share;
}
} else {
supplyIndex0[recipient] = index0; // new users are set to the default global state
supplyIndex1[recipient] = index1;
}
}
function getReserves() public view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast) {
_reserve0 = reserve0;
_reserve1 = reserve1;
_blockTimestampLast = blockTimestampLast;
}
// update reserves and, on the first call per block, price accumulators
function _update(uint balance0, uint balance1, uint _reserve0, uint _reserve1) internal {
uint blockTimestamp = block.timestamp;
uint timeElapsed;
unchecked {
timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
reserve0CumulativeLast += _reserve0 * timeElapsed;
reserve1CumulativeLast += _reserve1 * timeElapsed;
}
}
Observation memory _point = lastObservation();
timeElapsed = blockTimestamp - _point.timestamp; // compare the last observation with current timestamp, if greater than 30 minutes, record a new event
if (timeElapsed > periodSize) {
observations.push(Observation(blockTimestamp, reserve0CumulativeLast, reserve1CumulativeLast));
}
reserve0 = balance0;
reserve1 = balance1;
blockTimestampLast = blockTimestamp;
emit Sync(reserve0, reserve1);
}
// produces the cumulative price using counterfactuals to save gas and avoid a call to sync.
function currentCumulativePrices() public view returns (uint reserve0Cumulative, uint reserve1Cumulative, uint blockTimestamp) {
blockTimestamp = block.timestamp;
reserve0Cumulative = reserve0CumulativeLast;
reserve1Cumulative = reserve1CumulativeLast;
// if time has elapsed since the last update on the pair, mock the accumulated price values
(uint _reserve0, uint _reserve1, uint _blockTimestampLast) = getReserves();
if (_blockTimestampLast != blockTimestamp) {
unchecked {
// subtraction overflow is desired
uint timeElapsed = blockTimestamp - _blockTimestampLast;
reserve0Cumulative += _reserve0 * timeElapsed;
reserve1Cumulative += _reserve1 * timeElapsed;
}
}
}
// gives the current twap price measured from amountIn * tokenIn gives amountOut
function current(address tokenIn, uint amountIn) external view returns (uint amountOut) {
Observation memory _observation = lastObservation();
(uint reserve0Cumulative, uint reserve1Cumulative,) = currentCumulativePrices();
if (block.timestamp == _observation.timestamp) {
_observation = observations[observations.length-2];
}
uint timeElapsed = block.timestamp - _observation.timestamp;
uint _reserve0 = (reserve0Cumulative - _observation.reserve0Cumulative) / timeElapsed;
uint _reserve1 = (reserve1Cumulative - _observation.reserve1Cumulative) / timeElapsed;
amountOut = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);
}
// as per `current`, however allows user configured granularity, up to the full window size
function quote(address tokenIn, uint amountIn, uint granularity) external view returns (uint amountOut) {
uint [] memory _prices = sample(tokenIn, amountIn, granularity, 1);
uint priceAverageCumulative;
for (uint i = 0; i < _prices.length; i++) {
priceAverageCumulative += _prices[i];
}
return priceAverageCumulative / granularity;
}
// returns a memory set of twap prices
function prices(address tokenIn, uint amountIn, uint points) external view returns (uint[] memory) {
return sample(tokenIn, amountIn, points, 1);
}
function sample(address tokenIn, uint amountIn, uint points, uint window) public view returns (uint[] memory) {
uint[] memory _prices = new uint[](points);
uint length = observations.length-1;
uint i = length - (points * window);
uint nextIndex = 0;
uint index = 0;
for (; i < length; i+=window) {
nextIndex = i + window;
uint timeElapsed = observations[nextIndex].timestamp - observations[i].timestamp;
uint _reserve0 = (observations[nextIndex].reserve0Cumulative - observations[i].reserve0Cumulative) / timeElapsed;
uint _reserve1 = (observations[nextIndex].reserve1Cumulative - observations[i].reserve1Cumulative) / timeElapsed;
_prices[index] = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);
// index < length; length cannot overflow
unchecked {
index = index + 1;
}
}
return _prices;
}
// this low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks
// standard uniswap v2 implementation
function mint(address to) external lock returns (uint liquidity) {
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
uint _balance0 = IERC20(token0).balanceOf(address(this));
uint _balance1 = IERC20(token1).balanceOf(address(this));
uint _amount0 = _balance0 - _reserve0;
uint _amount1 = _balance1 - _reserve1;
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
if (_totalSupply == 0) {
liquidity = Math.sqrt(_amount0 * _amount1) - MINIMUM_LIQUIDITY;
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
liquidity = Math.min(_amount0 * _totalSupply / _reserve0, _amount1 * _totalSupply / _reserve1);
}
require(liquidity > 0, 'ILM'); // Pair: INSUFFICIENT_LIQUIDITY_MINTED
_mint(to, liquidity);
_update(_balance0, _balance1, _reserve0, _reserve1);
emit Mint(msg.sender, _amount0, _amount1);
}
// this low-level function should be called from a contract which performs important safety checks
// standard uniswap v2 implementation
function burn(address to) external lock returns (uint amount0, uint amount1) {
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
(address _token0, address _token1) = (token0, token1);
uint _balance0 = IERC20(_token0).balanceOf(address(this));
uint _balance1 = IERC20(_token1).balanceOf(address(this));
uint _liquidity = balanceOf[address(this)];
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
amount0 = _liquidity * _balance0 / _totalSupply; // using balances ensures pro-rata distribution
amount1 = _liquidity * _balance1 / _totalSupply; // using balances ensures pro-rata distribution
require(amount0 > 0 && amount1 > 0, 'ILB'); // Pair: INSUFFICIENT_LIQUIDITY_BURNED
_burn(address(this), _liquidity);
_safeTransfer(_token0, to, amount0);
_safeTransfer(_token1, to, amount1);
_balance0 = IERC20(_token0).balanceOf(address(this));
_balance1 = IERC20(_token1).balanceOf(address(this));
_update(_balance0, _balance1, _reserve0, _reserve1);
emit Burn(msg.sender, amount0, amount1, to);
}
// this low-level function should be called from a contract which performs important safety checks
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
require(amount0Out > 0 || amount1Out > 0, 'IOA'); // Pair: INSUFFICIENT_OUTPUT_AMOUNT
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
require(amount0Out < _reserve0 && amount1Out < _reserve1, 'IL'); // Pair: INSUFFICIENT_LIQUIDITY
uint _balance0;
uint _balance1;
{ // scope for _token{0,1}, avoids stack too deep errors
(address _token0, address _token1) = (token0, token1);
require(to != _token0 && to != _token1, 'IT'); // Pair: INVALID_TO
if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
if (data.length > 0) IPairCallee(to).hook(msg.sender, amount0Out, amount1Out, data); // callback, used for flash loans
_balance0 = IERC20(_token0).balanceOf(address(this));
_balance1 = IERC20(_token1).balanceOf(address(this));
}
uint amount0In = _balance0 > _reserve0 - amount0Out ? _balance0 - (_reserve0 - amount0Out) : 0;
uint amount1In = _balance1 > _reserve1 - amount1Out ? _balance1 - (_reserve1 - amount1Out) : 0;
require(amount0In > 0 || amount1In > 0, 'IIA'); // Pair: INSUFFICIENT_INPUT_AMOUNT
{ // scope for reserve{0,1}Adjusted, avoids stack too deep errors
(address _token0, address _token1) = (token0, token1);
if (amount0In > 0) _update0(amount0In * PairFactory(factory).getFee(stable) / 10000); // accrue fees for token0 and move them out of pool
if (amount1In > 0) _update1(amount1In * PairFactory(factory).getFee(stable) / 10000); // accrue fees for token1 and move them out of pool
_balance0 = IERC20(_token0).balanceOf(address(this)); // since we removed tokens, we need to reconfirm balances, can also simply use previous balance - amountIn/ 10000, but doing balanceOf again as safety check
_balance1 = IERC20(_token1).balanceOf(address(this));
// The curve, either x3y+y3x for stable pools, or x*y for volatile pools
require(_k(_balance0, _balance1) >= _k(_reserve0, _reserve1), 'K'); // Pair: K
}
_update(_balance0, _balance1, _reserve0, _reserve1);
emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
}
// force balances to match reserves
function skim(address to) external lock {
(address _token0, address _token1) = (token0, token1);
_safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)) - (reserve0));
_safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)) - (reserve1));
}
// force reserves to match balances
function sync() external lock {
_update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
}
function _f(uint x0, uint y) internal pure returns (uint) {
return x0*(y*y/1e18*y/1e18)/1e18+(x0*x0/1e18*x0/1e18)*y/1e18;
}
function _d(uint x0, uint y) internal pure returns (uint) {
return 3*x0*(y*y/1e18)/1e18+(x0*x0/1e18*x0/1e18);
}
function _get_y(uint x0, uint xy, uint y) internal pure returns (uint) {
// Iterate to find the value of y that satisfies the equation _f(x0, y) = xy
for (uint i = 0; i < 255; i++) {
uint y_prev = y;
uint k = _f(x0, y);
if (k < xy) {
// Calculate the change in y based on the difference between k and xy
uint dy = ((xy - k) * 1e18) / _d(x0, y);
y = y + dy;
} else {
// Calculate the change in y based on the difference between k and xy
uint dy = ((k - xy) * 1e18) / _d(x0, y);
y = y - dy;
}
// Check if the change in y is within a tolerance of 1
if (y > y_prev) {
if (y - y_prev <= 1) {
return y;
}
} else {
if (y_prev - y <= 1) {
return y;
}
}
}
return y;
}
function getAmountOut(uint amountIn, address tokenIn) external view returns (uint) {
(uint _reserve0, uint _reserve1) = (reserve0, reserve1);
amountIn -= amountIn * PairFactory(factory).getFee(stable) / 10000; // remove fee from amount received
return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1);
}
function _getAmountOut(uint amountIn, address tokenIn, uint _reserve0, uint _reserve1) internal view returns (uint) {
if (stable) {
// Calculate the product of reserves
uint xy = _k(_reserve0, _reserve1);
// Adjust the reserves based on decimals
_reserve0 = (_reserve0 * 1e18) / decimals0;
_reserve1 = (_reserve1 * 1e18) / decimals1;
// Determine the order of reserves based on the token being swapped
(uint reserveA, uint reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);
// Adjust the input amount based on decimals
amountIn = tokenIn == token0 ? (amountIn * 1e18) / decimals0 : (amountIn * 1e18) / decimals1;
// Calculate the output amount using the formula y = reserveB - _get_y(amountIn+reserveA, xy, reserveB)
uint y = reserveB - _get_y(amountIn + reserveA, xy, reserveB);
// Adjust the output amount based on decimals and return it
return (y * (tokenIn == token0 ? decimals1 : decimals0)) / 1e18;
} else {
// Determine the order of reserves based on the token being swapped
(uint reserveA, uint reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0);
// Calculate the output amount using the formula amountIn * reserveB / (reserveA + amountIn)
return (amountIn * reserveB) / (reserveA + amountIn);
}
}
function _k(uint x, uint y) internal view returns (uint) {
// Check if the pool is stable or volatile
if (stable) {
// Adjust the reserves based on decimals
uint _x = (x * 1e18) / decimals0;
uint _y = (y * 1e18) / decimals1;
// Calculate the product of adjusted reserves
uint _a = (_x * _y) / 1e18;
// Calculate the sum of squares of adjusted reserves
uint _b = ((_x * _x) / 1e18 + (_y * _y) / 1e18);
// Calculate the product of adjusted reserves and sum of squares of adjusted reserves
return (_a * _b) / 1e18; // x3y+y3x >= k
} else {
// Calculate the product of reserves
return x * y; // xy >= k
}
}
function _mint(address dst, uint amount) internal {
_updateFor(dst); // balances must be updated on mint/burn/transfer
totalSupply += amount;
balanceOf[dst] += amount;
emit Transfer(address(0), dst, amount);
}
function _burn(address dst, uint amount) internal {
_updateFor(dst);
totalSupply -= amount;
balanceOf[dst] -= amount;
emit Transfer(dst, address(0), amount);
}
function approve(address spender, uint amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
require(deadline >= block.timestamp, 'Pair: EXPIRED');
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
keccak256(bytes(name)),
keccak256(bytes('1')),
block.chainid,
address(this)
)
);
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, 'Pair: INVALID_SIGNATURE');
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function transfer(address dst, uint amount) external returns (bool) {
_transferTokens(msg.sender, dst, amount);
return true;
}
function transferFrom(address src, address dst, uint amount) external returns (bool) {
address spender = msg.sender;
uint spenderAllowance = allowance[src][spender];
if (spender != src && spenderAllowance != type(uint).max) {
uint newAllowance = spenderAllowance - amount;
allowance[src][spender] = newAllowance;
emit Approval(src, spender, newAllowance);
}
_transferTokens(src, dst, amount);
return true;
}
function _transferTokens(address src, address dst, uint amount) internal {
_updateFor(src); // update fee position for src
_updateFor(dst); // update fee position for dst
balanceOf[src] -= amount;
balanceOf[dst] += amount;
emit Transfer(src, dst, amount);
}
function _safeTransfer(address token,address to,uint256 value) internal {
require(token.code.length > 0);
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))));
}
function _safeApprove(address token,address spender,uint256 value) internal {
require(token.code.length > 0);
require((value == 0) || (IERC20(token).allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, spender, value));
require(success && (data.length == 0 || abi.decode(data, (bool))));
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import './interfaces/IERC20.sol';
// Pair Fees contract is used as a 1:1 pair relationship to split out fees, this ensures that the curve does not need to be modified for LP shares
contract PairFees {
address internal immutable pair; // The pair it is bonded to
address internal immutable token0; // token0 of pair, saved localy and statically for gas optimization
address internal immutable token1; // Token1 of pair, saved localy and statically for gas optimization
uint256 public toStake0;
uint256 public toStake1;
constructor(address _token0, address _token1) {
pair = msg.sender;
token0 = _token0;
token1 = _token1;
}
function _safeTransfer(address token,address to,uint256 value) internal {
require(token.code.length > 0);
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))));
}
// Allow the pair to transfer fees to users
function claimFeesFor(address recipient, uint amount0, uint amount1) external {
require(msg.sender == pair);
if (amount0 > 0) _safeTransfer(token0, recipient, amount0);
if (amount1 > 0) _safeTransfer(token1, recipient, amount1);
}
}{
"optimizer": {
"enabled": true,
"runs": 1000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REFERRAL_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REFERRAL_FEE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dibs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitializable","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pairs","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingFeeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dibs","type":"address"}],"name":"setDibs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_refFee","type":"uint256"}],"name":"setReferralFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"volatileFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040526107d0600255600060035534801561001b57600080fd5b50600480546001600160a01b03191633178155600055601260015561557e806100456000396000f3fe60806040523480156200001157600080fd5b5060043610620001a15760003560e01c80637be1623e11620000e9578063d0fb02031162000097578063eb13c4cf116200006e578063eb13c4cf1462000369578063f94c53c714620003a2578063ffb0a4a014620003ac57600080fd5b8063d0fb02031462000307578063e1f76b44146200031b578063e5e31b13146200033257600080fd5b80638a4fa0d211620000cc5780638a4fa0d214620002e05780639aab924814620002f4578063bc063e1a14620002fe57600080fd5b80637be1623e14620002b557806382dfdce414620002c957600080fd5b80635084ed03116200015357806363257389116200012a5780636325738914620002575780636801cc301462000261578063713494d7146200029e57600080fd5b80635084ed03146200022d578063512b45ea1462000237578063574f2ba3146200024e57600080fd5b80631e61079c11620001885780631e61079c14620001f357806340bbd775146200020c578063472d35b9146200021657600080fd5b80630c74db1214620001a65780631e3dd18b14620001bf575b600080fd5b620001bd620001b736600462000b8b565b620003c5565b005b620001d6620001d036600462000bb0565b62000491565b6040516001600160a01b0390911681526020015b60405180910390f35b620001fd60035481565b604051908152602001620001ea565b620001fd60005481565b620001bd6200022736600462000b8b565b620004bc565b620001fd60015481565b620001fd6200024836600462000bdb565b6200052c565b600854620001fd565b620001fd60025481565b620001d66200027236600462000bf9565b60076020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b620001bd620002af36600462000bb0565b62000547565b600654620001d6906001600160a01b031681565b620001d6620002da36600462000bf9565b620005ee565b600554620001d6906001600160a01b031681565b620001fd62000942565b620001fd601981565b600454620001d6906001600160a01b031681565b620001bd6200032c36600462000c43565b62000976565b620003586200034336600462000b8b565b60096020526000908152604090205460ff1681565b6040519015158152602001620001ea565b600a54600b54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff16151590820152606001620001ea565b620001bd62000a7c565b620003b662000afc565b604051620001ea919062000c70565b6004546001600160a01b03163314620004175760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064015b60405180910390fd5b6001600160a01b0381166200046f5760405162461bcd60e51b815260206004820152600c60248201527f61646472657373207a65726f000000000000000000000000000000000000000060448201526064016200040e565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b60088181548110620004a257600080fd5b6000918252602090912001546001600160a01b0316905081565b6004546001600160a01b031633146200050a5760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200040e565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000816200053d5760015462000541565b6000545b92915050565b6004546001600160a01b03163314620005955760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200040e565b600254811115620005e95760405162461bcd60e51b815260206004820152600f60248201527f41626f766520666565206c696d6974000000000000000000000000000000000060448201526064016200040e565b600355565b6000826001600160a01b0316846001600160a01b031603620006535760405162461bcd60e51b815260206004820152600260248201527f494100000000000000000000000000000000000000000000000000000000000060448201526064016200040e565b600080846001600160a01b0316866001600160a01b031610620006785784866200067b565b85855b90925090506001600160a01b038216620006d85760405162461bcd60e51b815260206004820152600260248201527f5a4100000000000000000000000000000000000000000000000000000000000060448201526064016200040e565b6001600160a01b0382811660009081526007602090815260408083208585168452825280832088151584529091529020541615620007595760405162461bcd60e51b815260206004820152600260248201527f504500000000000000000000000000000000000000000000000000000000000060448201526064016200040e565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600b80546001600160a01b038087166001600160a01b03198b1515600160a01b0281167fffffffffffffffffffffff0000000000000000000000000000000000000000009094169390931717909255600a80549288169290911691909117905591508190620008189062000b60565b8190604051809103906000f590508015801562000839573d6000803e3d6000fd5b506001600160a01b0384811660008181526007602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560088054600181810183557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee39091018054909a1687179099558587526009855295839020805460ff1916909817909755935481519687529186019290925290840152929650907fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a35050509392505050565b600060405180602001620009569062000b60565b6020820181038252601f19601f8201166040525080519060200120905090565b6004546001600160a01b03163314620009c45760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200040e565b601981111562000a175760405162461bcd60e51b815260206004820152600c60248201527f66656520746f6f2068696768000000000000000000000000000000000000000060448201526064016200040e565b8060000362000a695760405162461bcd60e51b815260206004820152601360248201527f666565206d757374206265206e6f6e7a65726f0000000000000000000000000060448201526064016200040e565b811562000a765760005550565b60015550565b6005546001600160a01b0316331462000ad85760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e6167657200000000000000000060448201526064016200040e565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b6060600880548060200260200160405190810160405280929190818152602001828054801562000b5657602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000b37575b5050505050905090565b6148898062000cc083390190565b80356001600160a01b038116811462000b8657600080fd5b919050565b60006020828403121562000b9e57600080fd5b62000ba98262000b6e565b9392505050565b60006020828403121562000bc357600080fd5b5035919050565b8035801515811462000b8657600080fd5b60006020828403121562000bee57600080fd5b62000ba98262000bca565b60008060006060848603121562000c0f57600080fd5b62000c1a8462000b6e565b925062000c2a6020850162000b6e565b915062000c3a6040850162000bca565b90509250925092565b6000806040838503121562000c5757600080fd5b62000c628362000bca565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101562000cb35783516001600160a01b03168352928401929184019160010162000c8c565b5090969550505050505056fe61016060405260006002556000600d556000600e5560016013553480156200002657600080fd5b50336001600160a01b0316610100816001600160a01b0316815250506000806000336001600160a01b031663eb13c4cf6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000086573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ac9190620007c8565b8015156080526001600160a01b0380831660c052831660a052604051929550909350915083908390620000df90620006f7565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562000113573d6000803e3d6000fd5b506001600160a01b031660e05280156200034557826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000166573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000190919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001f9919081019062000863565b6040516020016200020c9291906200091b565b604051602081830303815290604052600090805190602001906200023292919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000272573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200029c919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620002db573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000305919081019062000863565b6040516020016200031892919062000976565b604051602081830303815290604052600190805190602001906200033e92919062000705565b506200055e565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000384573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620003ae919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620003ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000417919081019062000863565b6040516020016200042a929190620009c7565b604051602081830303815290604052600090805190602001906200045092919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000490573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620004ba919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620004f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000523919081019062000863565b6040516020016200053692919062000a24565b604051602081830303815290604052600190805190602001906200055c92919062000705565b505b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200059d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005c3919062000a46565b620005d090600a62000b87565b6101208181525050816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000617573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200063d919062000a46565b6200064a90600a62000b87565b6101405250506040805160608101825242815260006020820181815292820181815260078054600181018255925291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039092029182015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555062000bd4565b61040c806200447d83390190565b828054620007139062000b98565b90600052602060002090601f01602090048101928262000737576000855562000782565b82601f106200075257805160ff191683800117855562000782565b8280016001018555821562000782579182015b828111156200078257825182559160200191906001019062000765565b506200079092915062000794565b5090565b5b8082111562000790576000815560010162000795565b80516001600160a01b0381168114620007c357600080fd5b919050565b600080600060608486031215620007de57600080fd5b620007e984620007ab565b9250620007f960208501620007ab565b9150604084015180151581146200080f57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200084d57818101518382015260200162000833565b838111156200085d576000848401525b50505050565b6000602082840312156200087657600080fd5b81516001600160401b03808211156200088e57600080fd5b818401915084601f830112620008a357600080fd5b815181811115620008b857620008b86200081a565b604051601f8201601f19908116603f01168101908382118183101715620008e357620008e36200081a565b81604052828152876020848701011115620008fd57600080fd5b6200091083602083016020880162000830565b979650505050505050565b6e029ba30b13632ab189020a6a690169608d1b8152600083516200094781600f85016020880162000830565b602f60f81b600f9184019182015283516200096a81601084016020880162000830565b01601001949350505050565b6473414d4d2d60d81b8152600083516200099881600585016020880162000830565b602f60f81b6005918401918201528351620009bb81600684016020880162000830565b01600601949350505050565b7002b37b630ba34b632ab189020a6a690169607d1b815260008351620009f581601185016020880162000830565b602f60f81b601191840191820152835162000a1881601284016020880162000830565b01601201949350505050565b6476414d4d2d60d81b8152600083516200099881600585016020880162000830565b60006020828403121562000a5957600080fd5b815160ff8116811462000a6b57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000ac957816000190482111562000aad5762000aad62000a72565b8085161562000abb57918102915b93841c939080029062000a8d565b509250929050565b60008262000ae25750600162000b81565b8162000af15750600062000b81565b816001811462000b0a576002811462000b155762000b35565b600191505062000b81565b60ff84111562000b295762000b2962000a72565b50506001821b62000b81565b5060208310610133831016604e8410600b841016171562000b5a575081810a62000b81565b62000b66838362000a88565b806000190482111562000b7d5762000b7d62000a72565b0290505b92915050565b600062000a6b60ff84168362000ad1565b600181811c9082168062000bad57607f821691505b60208210810362000bce57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161372862000d55600039600081816104de0152818161268c0152818161293d015281816129ff0152612b0a0152600081816104bb0152818161264b015281816128fe01528181612a410152612ae4015260008181610ca701528181610d78015261218d01526000818161069f01528181611d5a015281816124b2015261257f015260008181610568015281816106f4015281816107c10152818161094501528181610c3b015281816115a2015281816117a701528181611be8015281816122ea015261255e0152600081816103a601528181610540015281816106cf0152818161092401528181610c1a0152818161150c0152818161178501528181611bc601528181612262015281816124910152818161297f015281816129c601528181612aab0152612b4e01526000818161035e015281816104440152818161051001528181610c6f01528181610d400152818161215c0152818161262301526128ca01526137286000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806370a082311161019c578063bc25cf77116100ee578063d294f09311610097578063ebeb31db11610071578063ebeb31db14610829578063f140a35a14610831578063fff6cae91461084457600080fd5b8063d294f093146107e3578063d505accf146107eb578063dd62ed3e146107fe57600080fd5b8063c245febc116100c8578063c245febc146107aa578063c5700a02146107b3578063d21220a7146107bc57600080fd5b8063bc25cf7714610785578063bda39cad14610798578063bf944dbc146107a157600080fd5b80639af1d35a116101505780639f767c881161012a5780639f767c8814610732578063a1ac4d1314610752578063a9059cbb1461077257600080fd5b80639af1d35a1461069a5780639d63848a146106c15780639e8cc04b1461071f57600080fd5b806389afcb441161018157806389afcb44146106405780638a7b8cf21461066857806395d89b411461069257600080fd5b806370a08231146106005780637ecebe001461062057600080fd5b806323b872dd11610255578063443cb4bc116102095780635881c475116101e35780635881c475146105d15780635a76f25e146105e45780636a627842146105ed57600080fd5b8063443cb4bc146105955780634d5a9f8a1461059e578063517b3f82146105be57600080fd5b8063313ce5671161023a578063313ce5671461048c57806332c0defd146104a6578063392f37e9146104af57600080fd5b806323b872dd14610466578063252c09d71461047957600080fd5b80630dfe1681116102b75780631df8c717116102915780631df8c71714610417578063205aabf11461041f57806322be3de11461043f57600080fd5b80630dfe1681146103a157806313345fe1146103e057806318160ddd1461040057600080fd5b80630902f1ac116102e85780630902f1ac1461033757806309047bdd1461035c578063095ea7b31461038e57600080fd5b8063022c0d9f1461030457806306fdde0314610319575b600080fd5b6103176103123660046131aa565b61084c565b005b610321610fa8565b60405161032e919061326e565b60405180910390f35b600854600954600a545b6040805193845260208401929092529082015260600161032e565b7f00000000000000000000000000000000000000000000000000000000000000005b604051901515815260200161032e565b61037e61039c3660046132a1565b611036565b6103c87f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161032e565b6103f36103ee3660046132cb565b6110a3565b60405161032e9190613304565b61040960025481565b60405190815260200161032e565b61034161129f565b61040961042d366004613348565b60106020526000908152604090205481565b61037e7f000000000000000000000000000000000000000000000000000000000000000081565b61037e610474366004613363565b6112e5565b61034161048736600461339f565b6113ae565b610494601281565b60405160ff909116815260200161032e565b610409600d5481565b600854600954604080517f000000000000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060208201529081019290925260608201527f0000000000000000000000000000000000000000000000000000000000000000151560808201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660a08301527f00000000000000000000000000000000000000000000000000000000000000001660c082015260e00161032e565b61040960085481565b6104096105ac366004613348565b60116020526000908152604090205481565b6104096105cc3660046132a1565b6113e1565b6103f36105df3660046133b8565b6114c9565b61040960095481565b6104096105fb366004613348565b6114d8565b61040961060e366004613348565b60046020526000908152604090205481565b61040961062e366004613348565b60066020526000908152604090205481565b61065361064e366004613348565b611753565b6040805192835260208301919091520161032e565b610670611a8a565b604080518251815260208084015190820152918101519082015260600161032e565b610321611b0a565b6103c87f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f00000000000000000000000000000000000000000000000000000000000000001660208201520161032e565b61040961072d3660046133b8565b611b17565b610409610740366004613348565b600f6020526000908152604090205481565b610409610760366004613348565b60126020526000908152604090205481565b61037e6107803660046132a1565b611b84565b610317610793366004613348565b611b9a565b610409600e5481565b610409600b5481565b610409600c5481565b610409600a5481565b6103c87f000000000000000000000000000000000000000000000000000000000000000081565b610653611cb8565b6103176107f93660046133eb565b611df8565b61040961080c36600461345e565b600360209081526000928352604080842090915290825290205481565b600754610409565b61040961083f366004613491565b612147565b610317612235565b60135460011461085b57600080fd5b60026013558415158061086e5750600084115b6108bf5760405162461bcd60e51b815260206004820152600360248201527f494f41000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60085460095481871080156108d357508086105b61091f5760405162461bcd60e51b815260206004820152600260248201527f494c00000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148015906109925750806001600160a01b0316896001600160a01b031614155b6109de5760405162461bcd60e51b815260206004820152600260248201527f495400000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b8a156109ef576109ef828a8d61236f565b8915610a0057610a00818a8c61236f565b8615610a86576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610a539033908f908f908e908e906004016134b4565b600060405180830381600087803b158015610a6d57600080fd5b505af1158015610a81573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613501565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b599190613501565b9250505060008985610b6b9190613530565b8311610b78576000610b8c565b610b828a86613530565b610b8c9084613530565b90506000610b9a8a86613530565b8311610ba7576000610bbb565b610bb18a86613530565b610bbb9084613530565b90506000821180610bcc5750600081115b610c185760405162461bcd60e51b815260206004820152600360248201527f494941000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008315610d2b57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610d2b90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610cee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d129190613501565b610d1c9087613547565b610d269190613566565b61248c565b8215610dfc57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610dfc90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610dbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de39190613501565b610ded9086613547565b610df79190613566565b612559565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e649190613501565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa158015610eab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecf9190613501565b9450610edb888861261f565b610ee5878761261f565b1015610f335760405162461bcd60e51b815260206004820152600160248201527f4b0000000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b5050610f418484888861276b565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601355505050505050505050565b60008054610fb590613588565b80601f0160208091040260200160405190810160405280929190818152602001828054610fe190613588565b801561102e5780601f106110035761010080835404028352916020019161102e565b820191906000526020600020905b81548152906001019060200180831161101157829003601f168201915b505050505081565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906110919086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff8111156110c0576110c06135bc565b6040519080825280602002602001820160405280156110e9578160200160208202803683370190505b506007549091506000906110ff90600190613530565b9050600061110d8587613547565b6111179083613530565b90506000805b8383101561128f5761112f87846135d2565b9150600060078481548110611146576111466135ea565b9060005260206000209060030201600001546007848154811061116b5761116b6135ea565b9060005260206000209060030201600001546111879190613530565b90506000816007868154811061119f5761119f6135ea565b906000526020600020906003020160010154600786815481106111c4576111c46135ea565b9060005260206000209060030201600101546111e09190613530565b6111ea9190613566565b905060008260078781548110611202576112026135ea565b90600052602060002090600302016002015460078781548110611227576112276135ea565b9060005260206000209060030201600201546112439190613530565b61124d9190613566565b905061125b8c8e84846128c6565b88858151811061126d5761126d6135ea565b602090810291909101015250505060010161128887846135d2565b925061111d565b509293505050505b949350505050565b600b54600c5442600080806112bd600854600954600a549192909190565b9250925092508381146112dd578084038381029690960195820294909401935b505050909192565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061131f57506000198114155b156113955760006113308583613530565b6001600160a01b038881166000818152600360209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6113a0868686612bbb565b6001925050505b9392505050565b600781815481106113be57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000806113ec611a8a565b90506000806113f961129f565b50845191935091504203611461576007805461141790600290613530565b81548110611427576114276135ea565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906114709042613530565b90506000818560200151856114859190613530565b61148f9190613566565b90506000828660400151856114a49190613530565b6114ae9190613566565b90506114bc888a84846128c6565b9998505050505050505050565b606061129784848460016110a3565b60006013546001146114e957600080fd5b60026013556008546009546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561155b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157f9190613501565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190613501565b9050600061161b8584613530565b905060006116298584613530565b600254909150600081900361166b576103e861164d6116488486613547565b612c7b565b6116579190613530565b975061166660006103e8612ceb565b6116a0565b61169d876116798386613547565b6116839190613566565b8761168e8486613547565b6116989190613566565b612d7e565b97505b600088116116f05760405162461bcd60e51b815260206004820152600360248201527f494c4d000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b6116fa8989612ceb565b6117068585898961276b565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601355509395945050505050565b60008060135460011461176557600080fd5b60026013556008546009546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156117fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181f9190613501565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188d9190613501565b3060009081526004602052604090205460025491925090806118af8584613547565b6118b99190613566565b9950806118c68484613547565b6118d09190613566565b985060008a1180156118e25750600089115b61192e5760405162461bcd60e51b815260206004820152600360248201527f494c42000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b6119383083612d94565b611943868c8c61236f565b61194e858c8b61236f565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b69190613501565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa1580156119fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a219190613501565b9250611a2f84848a8a61276b565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601381905550915091565b611aae60405180606001604052806000815260200160008152602001600081525090565b60078054611abe90600190613530565b81548110611ace57611ace6135ea565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60018054610fb590613588565b600080611b2785858560016110a3565b90506000805b8251811015611b6f57828181518110611b4857611b486135ea565b602002602001015182611b5b91906135d2565b915080611b6781613600565b915050611b2d565b50611b7a8482613566565b9695505050505050565b6000611b91338484612bbb565b50600192915050565b601354600114611ba957600080fd5b60026013556008546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091611c769184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa158015611c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c679190613501565b611c719190613530565b61236f565b6009546040516370a0823160e01b8152306004820152611cae9183918691906001600160a01b038416906370a0823190602401611c26565b5050600160135550565b600080611cc433612e1f565b50503360009081526011602090815260408083205460129092529091205481151580611cf05750600081115b15611df457336000818152601160209081526040808320839055601290915280822091909155517f533cf5ce000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018290526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063533cf5ce90606401600060405180830381600087803b158015611d9e57600080fd5b505af1158015611db2573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b42841015611e485760405162461bcd60e51b815260206004820152600d60248201527f506169723a20455850495245440000000000000000000000000000000000000060448201526064016108b6565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611e789190613619565b604080519182900382208282018252600183527f31000000000000000000000000000000000000000000000000000000000000006020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060058190556001600160a01b038a166000908152600690935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b919087611f5f83613600565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001611ff39291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa15801561205e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906120945750886001600160a01b0316816001600160a01b0316145b6120e05760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e415455524500000000000000000060448201526064016108b6565b6001600160a01b038981166000818152600360209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600854600954604051632895a2f560e11b81527f0000000000000000000000000000000000000000000000000000000000000000151560048201526000929190612710907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063512b45ea90602401602060405180830381865afa1580156121dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122009190613501565b61220a9087613547565b6122149190613566565b61221e9086613530565b945061222c858584846128c6565b95945050505050565b60135460011461224457600080fd5b60026013556040516370a0823160e01b8152306004820152612368907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156122b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d59190613501565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612339573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235d9190613501565b60085460095461276b565b6001601355565b6000836001600160a01b03163b1161238657600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161241091906136b4565b6000604051808303816000865af19150503d806000811461244d576040519150601f19603f3d011682016040523d82523d6000602084013e612452565b606091505b509150915081801561247c57508051158061247c57508080602001905181019061247c91906136d0565b61248557600080fd5b5050505050565b6124d77f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008361236f565b6002546000906124ef83670de0b6b3a7640000613547565b6124f99190613566565b905080156125195780600d600082825461251391906135d2565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b6125a47f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008361236f565b6002546000906125bc83670de0b6b3a7640000613547565b6125c69190613566565b905080156125e65780600e60008282546125e091906135d2565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602910161254d565b60007f00000000000000000000000000000000000000000000000000000000000000001561275a5760007f000000000000000000000000000000000000000000000000000000000000000061267c85670de0b6b3a7640000613547565b6126869190613566565b905060007f00000000000000000000000000000000000000000000000000000000000000006126bd85670de0b6b3a7640000613547565b6126c79190613566565b90506000670de0b6b3a76400006126de8385613547565b6126e89190613566565b90506000670de0b6b3a76400006126ff8480613547565b6127099190613566565b670de0b6b3a764000061271c8680613547565b6127269190613566565b61273091906135d2565b9050670de0b6b3a76400006127458284613547565b61274f9190613566565b94505050505061109d565b6127648284613547565b905061109d565b600a54429080820390821480159061278257508315155b801561278d57508215155b156127a757600b8054858302019055600c80548483020190555b60006127b1611a8a565b80519091506127c09084613530565b91506107088211156128755760408051606081018252848152600b5460208201908152600c549282019283526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600390930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68982015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555b60088790556009869055600a83905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015612b495760006128fa848461261f565b90507f000000000000000000000000000000000000000000000000000000000000000061292f85670de0b6b3a7640000613547565b6129399190613566565b93507f000000000000000000000000000000000000000000000000000000000000000061296e84670de0b6b3a7640000613547565b6129789190613566565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b0316146129bd5784866129c0565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614612a3f577f0000000000000000000000000000000000000000000000000000000000000000612a3089670de0b6b3a7640000613547565b612a3a9190613566565b612a7c565b7f0000000000000000000000000000000000000000000000000000000000000000612a7289670de0b6b3a7640000613547565b612a7c9190613566565b97506000612a94612a8d848b6135d2565b8584612f7f565b612a9e9083613530565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b031614612b08577f0000000000000000000000000000000000000000000000000000000000000000612b2a565b7f00000000000000000000000000000000000000000000000000000000000000005b612b349083613547565b612b3e9190613566565b945050505050611297565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614612b8c578385612b8f565b84845b9092509050612b9e87836135d2565b612ba88289613547565b612bb29190613566565b92505050611297565b612bc483612e1f565b612bcd82612e1f565b6001600160a01b03831660009081526004602052604081208054839290612bf5908490613530565b90915550506001600160a01b03821660009081526004602052604081208054839290612c229084906135d2565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612c6e91815260200190565b60405180910390a3505050565b60006003821115612cdc5750806000612c95600283613566565b612ca09060016135d2565b90505b81811015612cd657905080600281612cbb8186613566565b612cc591906135d2565b612ccf9190613566565b9050612ca3565b50919050565b8115612ce6575060015b919050565b612cf482612e1f565b8060026000828254612d0691906135d2565b90915550506001600160a01b03821660009081526004602052604081208054839290612d339084906135d2565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310612d8d57816113a7565b5090919050565b612d9d82612e1f565b8060026000828254612daf9190613530565b90915550506001600160a01b03821660009081526004602052604081208054839290612ddc908490613530565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612d72565b6001600160a01b0381166000908152600460205260409020548015612f4d576001600160a01b0382166000908152600f60209081526040808320805460108085529285208054600d54600e54948190559490955282905593612e818584613530565b90506000612e8f8584613530565b90508115612eea576000670de0b6b3a7640000612eac848a613547565b612eb69190613566565b6001600160a01b038a16600090815260116020526040812080549293508392909190612ee39084906135d2565b9091555050505b8015612f43576000670de0b6b3a7640000612f05838a613547565b612f0f9190613566565b6001600160a01b038a16600090815260126020526040812080549293508392909190612f3c9084906135d2565b9091555050505b5050505050505050565b600d546001600160a01b0383166000908152600f6020908152604080832093909355600e546010909152919020555050565b6000805b60ff81101561308557826000612f99878361308e565b905085811015612fe9576000612faf888761312b565b612fb98389613530565b612fcb90670de0b6b3a7640000613547565b612fd59190613566565b9050612fe181876135d2565b95505061302b565b6000612ff5888761312b565b612fff8884613530565b61301190670de0b6b3a7640000613547565b61301b9190613566565b90506130278187613530565b9550505b8185111561305457600161303f8387613530565b1161304f578493505050506113a7565b613070565b60016130608684613530565b11613070578493505050506113a7565b5050808061307d90613600565b915050612f83565b50909392505050565b6000670de0b6b3a7640000828185816130a78280613547565b6130b19190613566565b6130bb9190613547565b6130c59190613566565b6130cf9190613547565b6130d99190613566565b670de0b6b3a76400008084816130ef8280613547565b6130f99190613566565b6131039190613547565b61310d9190613566565b6131179086613547565b6131219190613566565b6113a791906135d2565b6000670de0b6b3a764000083816131428280613547565b61314c9190613566565b6131569190613547565b6131609190613566565b670de0b6b3a7640000806131748580613547565b61317e9190613566565b613189866003613547565b6131179190613547565b80356001600160a01b0381168114612ce657600080fd5b6000806000806000608086880312156131c257600080fd5b85359450602086013593506131d960408701613193565b9250606086013567ffffffffffffffff808211156131f657600080fd5b818801915088601f83011261320a57600080fd5b81358181111561321957600080fd5b89602082850101111561322b57600080fd5b9699959850939650602001949392505050565b60005b83811015613259578181015183820152602001613241565b83811115613268576000848401525b50505050565b602081526000825180602084015261328d81604085016020870161323e565b601f01601f19169190910160400192915050565b600080604083850312156132b457600080fd5b6132bd83613193565b946020939093013593505050565b600080600080608085870312156132e157600080fd5b6132ea85613193565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561333c57835183529284019291840191600101613320565b50909695505050505050565b60006020828403121561335a57600080fd5b6113a782613193565b60008060006060848603121561337857600080fd5b61338184613193565b925061338f60208501613193565b9150604084013590509250925092565b6000602082840312156133b157600080fd5b5035919050565b6000806000606084860312156133cd57600080fd5b6133d684613193565b95602085013595506040909401359392505050565b600080600080600080600060e0888a03121561340657600080fd5b61340f88613193565b965061341d60208901613193565b95506040880135945060608801359350608088013560ff8116811461344157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561347157600080fd5b61347a83613193565b915061348860208401613193565b90509250929050565b600080604083850312156134a457600080fd5b8235915061348860208401613193565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60006020828403121561351357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156135425761354261351a565b500390565b60008160001904831182151516156135615761356161351a565b500290565b60008261358357634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061359c57607f821691505b602082108103612cd657634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082198211156135e5576135e561351a565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600182016136125761361261351a565b5060010190565b600080835481600182811c91508083168061363557607f831692505b6020808410820361365457634e487b7160e01b86526022600452602486fd5b8180156136685760018114613679576136a6565b60ff198616895284890196506136a6565b60008a81526020902060005b8681101561369e5781548b820152908501908301613685565b505084890196505b509498975050505050505050565b600082516136c681846020870161323e565b9190910192915050565b6000602082840312156136e257600080fd5b815180151581146113a757600080fdfea2646970667358221220a77c6462e49311cf8535f961ef70e841932f13cda16ebaf5f4dbe718f476ec8e64736f6c634300080d003360e060405234801561001057600080fd5b5060405161040c38038061040c83398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c0516103476100c5600039600060fd0152600060cc01526000609701526103476000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063533cf5ce146100465780635b3c92481461005b578063651d83f914610076575b600080fd5b61005961005436600461025f565b61007f565b005b61006460015481565b60405190815260200160405180910390f35b61006460005481565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100c157600080fd5b81156100f2576100f27f00000000000000000000000000000000000000000000000000000000000000008484610128565b8015610123576101237f00000000000000000000000000000000000000000000000000000000000000008483610128565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1161014c57600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916101e391906102ad565b6000604051808303816000865af19150503d8060008114610220576040519150601f19603f3d011682016040523d82523d6000602084013e610225565b606091505b509150915081801561024f57508051158061024f57508080602001905181019061024f91906102e8565b61025857600080fd5b5050505050565b60008060006060848603121561027457600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461029857600080fd5b95602085013595506040909401359392505050565b6000825160005b818110156102ce57602081860181015185830152016102b4565b818111156102dd576000828501525b509190910192915050565b6000602082840312156102fa57600080fd5b8151801515811461030a57600080fd5b939250505056fea26469706673582212206bfeedd1f2b9802e31fed7ffc3a001478f67c16055c890931b1cce8e25481d9664736f6c634300080d0033a2646970667358221220fa2702d04060292df45ac51e485f13120d1f69c60983623cfeaa6ad2b97cec7b64736f6c634300080d0033
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620001a15760003560e01c80637be1623e11620000e9578063d0fb02031162000097578063eb13c4cf116200006e578063eb13c4cf1462000369578063f94c53c714620003a2578063ffb0a4a014620003ac57600080fd5b8063d0fb02031462000307578063e1f76b44146200031b578063e5e31b13146200033257600080fd5b80638a4fa0d211620000cc5780638a4fa0d214620002e05780639aab924814620002f4578063bc063e1a14620002fe57600080fd5b80637be1623e14620002b557806382dfdce414620002c957600080fd5b80635084ed03116200015357806363257389116200012a5780636325738914620002575780636801cc301462000261578063713494d7146200029e57600080fd5b80635084ed03146200022d578063512b45ea1462000237578063574f2ba3146200024e57600080fd5b80631e61079c11620001885780631e61079c14620001f357806340bbd775146200020c578063472d35b9146200021657600080fd5b80630c74db1214620001a65780631e3dd18b14620001bf575b600080fd5b620001bd620001b736600462000b8b565b620003c5565b005b620001d6620001d036600462000bb0565b62000491565b6040516001600160a01b0390911681526020015b60405180910390f35b620001fd60035481565b604051908152602001620001ea565b620001fd60005481565b620001bd6200022736600462000b8b565b620004bc565b620001fd60015481565b620001fd6200024836600462000bdb565b6200052c565b600854620001fd565b620001fd60025481565b620001d66200027236600462000bf9565b60076020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b620001bd620002af36600462000bb0565b62000547565b600654620001d6906001600160a01b031681565b620001d6620002da36600462000bf9565b620005ee565b600554620001d6906001600160a01b031681565b620001fd62000942565b620001fd601981565b600454620001d6906001600160a01b031681565b620001bd6200032c36600462000c43565b62000976565b620003586200034336600462000b8b565b60096020526000908152604090205460ff1681565b6040519015158152602001620001ea565b600a54600b54604080516001600160a01b0393841681529282166020840152600160a01b90910460ff16151590820152606001620001ea565b620001bd62000a7c565b620003b662000afc565b604051620001ea919062000c70565b6004546001600160a01b03163314620004175760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064015b60405180910390fd5b6001600160a01b0381166200046f5760405162461bcd60e51b815260206004820152600c60248201527f61646472657373207a65726f000000000000000000000000000000000000000060448201526064016200040e565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b60088181548110620004a257600080fd5b6000918252602090912001546001600160a01b0316905081565b6004546001600160a01b031633146200050a5760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200040e565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000816200053d5760015462000541565b6000545b92915050565b6004546001600160a01b03163314620005955760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200040e565b600254811115620005e95760405162461bcd60e51b815260206004820152600f60248201527f41626f766520666565206c696d6974000000000000000000000000000000000060448201526064016200040e565b600355565b6000826001600160a01b0316846001600160a01b031603620006535760405162461bcd60e51b815260206004820152600260248201527f494100000000000000000000000000000000000000000000000000000000000060448201526064016200040e565b600080846001600160a01b0316866001600160a01b031610620006785784866200067b565b85855b90925090506001600160a01b038216620006d85760405162461bcd60e51b815260206004820152600260248201527f5a4100000000000000000000000000000000000000000000000000000000000060448201526064016200040e565b6001600160a01b0382811660009081526007602090815260408083208585168452825280832088151584529091529020541615620007595760405162461bcd60e51b815260206004820152600260248201527f504500000000000000000000000000000000000000000000000000000000000060448201526064016200040e565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015284151560f81b604882015260009060490160408051601f19818403018152908290528051602090910120600b80546001600160a01b038087166001600160a01b03198b1515600160a01b0281167fffffffffffffffffffffff0000000000000000000000000000000000000000009094169390931717909255600a80549288169290911691909117905591508190620008189062000b60565b8190604051809103906000f590508015801562000839573d6000803e3d6000fd5b506001600160a01b0384811660008181526007602081815260408084208987168086529083528185208d15158087529084528286208054988a166001600160a01b0319998a16811790915582875294845282862087875284528286208187528452828620805489168617905560088054600181810183557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee39091018054909a1687179099558587526009855295839020805460ff1916909817909755935481519687529186019290925290840152929650907fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc99060600160405180910390a35050509392505050565b600060405180602001620009569062000b60565b6020820181038252601f19601f8201166040525080519060200120905090565b6004546001600160a01b03163314620009c45760405162461bcd60e51b815260206004820152600f60248201526e3737ba103332b29036b0b730b3b2b960891b60448201526064016200040e565b601981111562000a175760405162461bcd60e51b815260206004820152600c60248201527f66656520746f6f2068696768000000000000000000000000000000000000000060448201526064016200040e565b8060000362000a695760405162461bcd60e51b815260206004820152601360248201527f666565206d757374206265206e6f6e7a65726f0000000000000000000000000060448201526064016200040e565b811562000a765760005550565b60015550565b6005546001600160a01b0316331462000ad85760405162461bcd60e51b815260206004820152601760248201527f6e6f742070656e64696e6720666565206d616e6167657200000000000000000060448201526064016200040e565b600554600480546001600160a01b0319166001600160a01b03909216919091179055565b6060600880548060200260200160405190810160405280929190818152602001828054801562000b5657602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000b37575b5050505050905090565b6148898062000cc083390190565b80356001600160a01b038116811462000b8657600080fd5b919050565b60006020828403121562000b9e57600080fd5b62000ba98262000b6e565b9392505050565b60006020828403121562000bc357600080fd5b5035919050565b8035801515811462000b8657600080fd5b60006020828403121562000bee57600080fd5b62000ba98262000bca565b60008060006060848603121562000c0f57600080fd5b62000c1a8462000b6e565b925062000c2a6020850162000b6e565b915062000c3a6040850162000bca565b90509250925092565b6000806040838503121562000c5757600080fd5b62000c628362000bca565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101562000cb35783516001600160a01b03168352928401929184019160010162000c8c565b5090969550505050505056fe61016060405260006002556000600d556000600e5560016013553480156200002657600080fd5b50336001600160a01b0316610100816001600160a01b0316815250506000806000336001600160a01b031663eb13c4cf6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000086573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ac9190620007c8565b8015156080526001600160a01b0380831660c052831660a052604051929550909350915083908390620000df90620006f7565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562000113573d6000803e3d6000fd5b506001600160a01b031660e05280156200034557826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000166573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000190919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001cf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001f9919081019062000863565b6040516020016200020c9291906200091b565b604051602081830303815290604052600090805190602001906200023292919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000272573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200029c919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620002db573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000305919081019062000863565b6040516020016200031892919062000976565b604051602081830303815290604052600190805190602001906200033e92919062000705565b506200055e565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000384573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620003ae919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620003ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000417919081019062000863565b6040516020016200042a929190620009c7565b604051602081830303815290604052600090805190602001906200045092919062000705565b50826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000490573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620004ba919081019062000863565b826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620004f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000523919081019062000863565b6040516020016200053692919062000a24565b604051602081830303815290604052600190805190602001906200055c92919062000705565b505b826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200059d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005c3919062000a46565b620005d090600a62000b87565b6101208181525050816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000617573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200063d919062000a46565b6200064a90600a62000b87565b6101405250506040805160608101825242815260006020820181815292820181815260078054600181018255925291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039092029182015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555062000bd4565b61040c806200447d83390190565b828054620007139062000b98565b90600052602060002090601f01602090048101928262000737576000855562000782565b82601f106200075257805160ff191683800117855562000782565b8280016001018555821562000782579182015b828111156200078257825182559160200191906001019062000765565b506200079092915062000794565b5090565b5b8082111562000790576000815560010162000795565b80516001600160a01b0381168114620007c357600080fd5b919050565b600080600060608486031215620007de57600080fd5b620007e984620007ab565b9250620007f960208501620007ab565b9150604084015180151581146200080f57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200084d57818101518382015260200162000833565b838111156200085d576000848401525b50505050565b6000602082840312156200087657600080fd5b81516001600160401b03808211156200088e57600080fd5b818401915084601f830112620008a357600080fd5b815181811115620008b857620008b86200081a565b604051601f8201601f19908116603f01168101908382118183101715620008e357620008e36200081a565b81604052828152876020848701011115620008fd57600080fd5b6200091083602083016020880162000830565b979650505050505050565b6e029ba30b13632ab189020a6a690169608d1b8152600083516200094781600f85016020880162000830565b602f60f81b600f9184019182015283516200096a81601084016020880162000830565b01601001949350505050565b6473414d4d2d60d81b8152600083516200099881600585016020880162000830565b602f60f81b6005918401918201528351620009bb81600684016020880162000830565b01600601949350505050565b7002b37b630ba34b632ab189020a6a690169607d1b815260008351620009f581601185016020880162000830565b602f60f81b601191840191820152835162000a1881601284016020880162000830565b01601201949350505050565b6476414d4d2d60d81b8152600083516200099881600585016020880162000830565b60006020828403121562000a5957600080fd5b815160ff8116811462000a6b57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000ac957816000190482111562000aad5762000aad62000a72565b8085161562000abb57918102915b93841c939080029062000a8d565b509250929050565b60008262000ae25750600162000b81565b8162000af15750600062000b81565b816001811462000b0a576002811462000b155762000b35565b600191505062000b81565b60ff84111562000b295762000b2962000a72565b50506001821b62000b81565b5060208310610133831016604e8410600b841016171562000b5a575081810a62000b81565b62000b66838362000a88565b806000190482111562000b7d5762000b7d62000a72565b0290505b92915050565b600062000a6b60ff84168362000ad1565b600181811c9082168062000bad57607f821691505b60208210810362000bce57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161372862000d55600039600081816104de0152818161268c0152818161293d015281816129ff0152612b0a0152600081816104bb0152818161264b015281816128fe01528181612a410152612ae4015260008181610ca701528181610d78015261218d01526000818161069f01528181611d5a015281816124b2015261257f015260008181610568015281816106f4015281816107c10152818161094501528181610c3b015281816115a2015281816117a701528181611be8015281816122ea015261255e0152600081816103a601528181610540015281816106cf0152818161092401528181610c1a0152818161150c0152818161178501528181611bc601528181612262015281816124910152818161297f015281816129c601528181612aab0152612b4e01526000818161035e015281816104440152818161051001528181610c6f01528181610d400152818161215c0152818161262301526128ca01526137286000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806370a082311161019c578063bc25cf77116100ee578063d294f09311610097578063ebeb31db11610071578063ebeb31db14610829578063f140a35a14610831578063fff6cae91461084457600080fd5b8063d294f093146107e3578063d505accf146107eb578063dd62ed3e146107fe57600080fd5b8063c245febc116100c8578063c245febc146107aa578063c5700a02146107b3578063d21220a7146107bc57600080fd5b8063bc25cf7714610785578063bda39cad14610798578063bf944dbc146107a157600080fd5b80639af1d35a116101505780639f767c881161012a5780639f767c8814610732578063a1ac4d1314610752578063a9059cbb1461077257600080fd5b80639af1d35a1461069a5780639d63848a146106c15780639e8cc04b1461071f57600080fd5b806389afcb441161018157806389afcb44146106405780638a7b8cf21461066857806395d89b411461069257600080fd5b806370a08231146106005780637ecebe001461062057600080fd5b806323b872dd11610255578063443cb4bc116102095780635881c475116101e35780635881c475146105d15780635a76f25e146105e45780636a627842146105ed57600080fd5b8063443cb4bc146105955780634d5a9f8a1461059e578063517b3f82146105be57600080fd5b8063313ce5671161023a578063313ce5671461048c57806332c0defd146104a6578063392f37e9146104af57600080fd5b806323b872dd14610466578063252c09d71461047957600080fd5b80630dfe1681116102b75780631df8c717116102915780631df8c71714610417578063205aabf11461041f57806322be3de11461043f57600080fd5b80630dfe1681146103a157806313345fe1146103e057806318160ddd1461040057600080fd5b80630902f1ac116102e85780630902f1ac1461033757806309047bdd1461035c578063095ea7b31461038e57600080fd5b8063022c0d9f1461030457806306fdde0314610319575b600080fd5b6103176103123660046131aa565b61084c565b005b610321610fa8565b60405161032e919061326e565b60405180910390f35b600854600954600a545b6040805193845260208401929092529082015260600161032e565b7f00000000000000000000000000000000000000000000000000000000000000005b604051901515815260200161032e565b61037e61039c3660046132a1565b611036565b6103c87f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161032e565b6103f36103ee3660046132cb565b6110a3565b60405161032e9190613304565b61040960025481565b60405190815260200161032e565b61034161129f565b61040961042d366004613348565b60106020526000908152604090205481565b61037e7f000000000000000000000000000000000000000000000000000000000000000081565b61037e610474366004613363565b6112e5565b61034161048736600461339f565b6113ae565b610494601281565b60405160ff909116815260200161032e565b610409600d5481565b600854600954604080517f000000000000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060208201529081019290925260608201527f0000000000000000000000000000000000000000000000000000000000000000151560808201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660a08301527f00000000000000000000000000000000000000000000000000000000000000001660c082015260e00161032e565b61040960085481565b6104096105ac366004613348565b60116020526000908152604090205481565b6104096105cc3660046132a1565b6113e1565b6103f36105df3660046133b8565b6114c9565b61040960095481565b6104096105fb366004613348565b6114d8565b61040961060e366004613348565b60046020526000908152604090205481565b61040961062e366004613348565b60066020526000908152604090205481565b61065361064e366004613348565b611753565b6040805192835260208301919091520161032e565b610670611a8a565b604080518251815260208084015190820152918101519082015260600161032e565b610321611b0a565b6103c87f000000000000000000000000000000000000000000000000000000000000000081565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f00000000000000000000000000000000000000000000000000000000000000001660208201520161032e565b61040961072d3660046133b8565b611b17565b610409610740366004613348565b600f6020526000908152604090205481565b610409610760366004613348565b60126020526000908152604090205481565b61037e6107803660046132a1565b611b84565b610317610793366004613348565b611b9a565b610409600e5481565b610409600b5481565b610409600c5481565b610409600a5481565b6103c87f000000000000000000000000000000000000000000000000000000000000000081565b610653611cb8565b6103176107f93660046133eb565b611df8565b61040961080c36600461345e565b600360209081526000928352604080842090915290825290205481565b600754610409565b61040961083f366004613491565b612147565b610317612235565b60135460011461085b57600080fd5b60026013558415158061086e5750600084115b6108bf5760405162461bcd60e51b815260206004820152600360248201527f494f41000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60085460095481871080156108d357508086105b61091f5760405162461bcd60e51b815260206004820152600260248201527f494c00000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b6000807f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03898116908316148015906109925750806001600160a01b0316896001600160a01b031614155b6109de5760405162461bcd60e51b815260206004820152600260248201527f495400000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b8a156109ef576109ef828a8d61236f565b8915610a0057610a00818a8c61236f565b8615610a86576040517f9a7bff790000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690639a7bff7990610a539033908f908f908e908e906004016134b4565b600060405180830381600087803b158015610a6d57600080fd5b505af1158015610a81573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613501565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b599190613501565b9250505060008985610b6b9190613530565b8311610b78576000610b8c565b610b828a86613530565b610b8c9084613530565b90506000610b9a8a86613530565b8311610ba7576000610bbb565b610bb18a86613530565b610bbb9084613530565b90506000821180610bcc5750600081115b610c185760405162461bcd60e51b815260206004820152600360248201527f494941000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008315610d2b57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610d2b90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610cee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d129190613501565b610d1c9087613547565b610d269190613566565b61248c565b8215610dfc57604051632895a2f560e11b81527f000000000000000000000000000000000000000000000000000000000000000015156004820152610dfc90612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063512b45ea90602401602060405180830381865afa158015610dbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de39190613501565b610ded9086613547565b610df79190613566565b612559565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610e40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e649190613501565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa158015610eab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecf9190613501565b9450610edb888861261f565b610ee5878761261f565b1015610f335760405162461bcd60e51b815260206004820152600160248201527f4b0000000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b5050610f418484888861276b565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001601355505050505050505050565b60008054610fb590613588565b80601f0160208091040260200160405190810160405280929190818152602001828054610fe190613588565b801561102e5780601f106110035761010080835404028352916020019161102e565b820191906000526020600020905b81548152906001019060200180831161101157829003601f168201915b505050505081565b3360008181526003602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906110919086815260200190565b60405180910390a35060015b92915050565b606060008367ffffffffffffffff8111156110c0576110c06135bc565b6040519080825280602002602001820160405280156110e9578160200160208202803683370190505b506007549091506000906110ff90600190613530565b9050600061110d8587613547565b6111179083613530565b90506000805b8383101561128f5761112f87846135d2565b9150600060078481548110611146576111466135ea565b9060005260206000209060030201600001546007848154811061116b5761116b6135ea565b9060005260206000209060030201600001546111879190613530565b90506000816007868154811061119f5761119f6135ea565b906000526020600020906003020160010154600786815481106111c4576111c46135ea565b9060005260206000209060030201600101546111e09190613530565b6111ea9190613566565b905060008260078781548110611202576112026135ea565b90600052602060002090600302016002015460078781548110611227576112276135ea565b9060005260206000209060030201600201546112439190613530565b61124d9190613566565b905061125b8c8e84846128c6565b88858151811061126d5761126d6135ea565b602090810291909101015250505060010161128887846135d2565b925061111d565b509293505050505b949350505050565b600b54600c5442600080806112bd600854600954600a549192909190565b9250925092508381146112dd578084038381029690960195820294909401935b505050909192565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061131f57506000198114155b156113955760006113308583613530565b6001600160a01b038881166000818152600360209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6113a0868686612bbb565b6001925050505b9392505050565b600781815481106113be57600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b6000806113ec611a8a565b90506000806113f961129f565b50845191935091504203611461576007805461141790600290613530565b81548110611427576114276135ea565b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092505b82516000906114709042613530565b90506000818560200151856114859190613530565b61148f9190613566565b90506000828660400151856114a49190613530565b6114ae9190613566565b90506114bc888a84846128c6565b9998505050505050505050565b606061129784848460016110a3565b60006013546001146114e957600080fd5b60026013556008546009546040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561155b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157f9190613501565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156115e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160d9190613501565b9050600061161b8584613530565b905060006116298584613530565b600254909150600081900361166b576103e861164d6116488486613547565b612c7b565b6116579190613530565b975061166660006103e8612ceb565b6116a0565b61169d876116798386613547565b6116839190613566565b8761168e8486613547565b6116989190613566565b612d7e565b97505b600088116116f05760405162461bcd60e51b815260206004820152600360248201527f494c4d000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b6116fa8989612ceb565b6117068585898961276b565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001601355509395945050505050565b60008060135460011461176557600080fd5b60026013556008546009546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156117fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181f9190613501565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188d9190613501565b3060009081526004602052604090205460025491925090806118af8584613547565b6118b99190613566565b9950806118c68484613547565b6118d09190613566565b985060008a1180156118e25750600089115b61192e5760405162461bcd60e51b815260206004820152600360248201527f494c42000000000000000000000000000000000000000000000000000000000060448201526064016108b6565b6119383083612d94565b611943868c8c61236f565b61194e858c8b61236f565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015611992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b69190613501565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa1580156119fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a219190613501565b9250611a2f84848a8a61276b565b604080518b8152602081018b90526001600160a01b038d169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050505050506001601381905550915091565b611aae60405180606001604052806000815260200160008152602001600081525090565b60078054611abe90600190613530565b81548110611ace57611ace6135ea565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b60018054610fb590613588565b600080611b2785858560016110a3565b90506000805b8251811015611b6f57828181518110611b4857611b486135ea565b602002602001015182611b5b91906135d2565b915080611b6781613600565b915050611b2d565b50611b7a8482613566565b9695505050505050565b6000611b91338484612bbb565b50600192915050565b601354600114611ba957600080fd5b60026013556008546040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091611c769184918691906001600160a01b038416906370a08231906024015b602060405180830381865afa158015611c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c679190613501565b611c719190613530565b61236f565b6009546040516370a0823160e01b8152306004820152611cae9183918691906001600160a01b038416906370a0823190602401611c26565b5050600160135550565b600080611cc433612e1f565b50503360009081526011602090815260408083205460129092529091205481151580611cf05750600081115b15611df457336000818152601160209081526040808320839055601290915280822091909155517f533cf5ce000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018290526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063533cf5ce90606401600060405180830381600087803b158015611d9e57600080fd5b505af1158015611db2573d6000803e3d6000fd5b505060408051858152602081018590523393508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b9091565b42841015611e485760405162461bcd60e51b815260206004820152600d60248201527f506169723a20455850495245440000000000000000000000000000000000000060448201526064016108b6565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611e789190613619565b604080519182900382208282018252600183527f31000000000000000000000000000000000000000000000000000000000000006020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f19818403018152918152815160209283012060058190556001600160a01b038a166000908152600690935290822080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b919087611f5f83613600565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001611ff39291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa15801561205e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906120945750886001600160a01b0316816001600160a01b0316145b6120e05760405162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e415455524500000000000000000060448201526064016108b6565b6001600160a01b038981166000818152600360209081526040808320948d16808452948252918290208b905590518a81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600854600954604051632895a2f560e11b81527f0000000000000000000000000000000000000000000000000000000000000000151560048201526000929190612710907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063512b45ea90602401602060405180830381865afa1580156121dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122009190613501565b61220a9087613547565b6122149190613566565b61221e9086613530565b945061222c858584846128c6565b95945050505050565b60135460011461224457600080fd5b60026013556040516370a0823160e01b8152306004820152612368907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156122b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d59190613501565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612339573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235d9190613501565b60085460095461276b565b6001601355565b6000836001600160a01b03163b1161238657600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161241091906136b4565b6000604051808303816000865af19150503d806000811461244d576040519150601f19603f3d011682016040523d82523d6000602084013e612452565b606091505b509150915081801561247c57508051158061247c57508080602001905181019061247c91906136d0565b61248557600080fd5b5050505050565b6124d77f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008361236f565b6002546000906124ef83670de0b6b3a7640000613547565b6124f99190613566565b905080156125195780600d600082825461251391906135d2565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b6125a47f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008361236f565b6002546000906125bc83670de0b6b3a7640000613547565b6125c69190613566565b905080156125e65780600e60008282546125e091906135d2565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602910161254d565b60007f00000000000000000000000000000000000000000000000000000000000000001561275a5760007f000000000000000000000000000000000000000000000000000000000000000061267c85670de0b6b3a7640000613547565b6126869190613566565b905060007f00000000000000000000000000000000000000000000000000000000000000006126bd85670de0b6b3a7640000613547565b6126c79190613566565b90506000670de0b6b3a76400006126de8385613547565b6126e89190613566565b90506000670de0b6b3a76400006126ff8480613547565b6127099190613566565b670de0b6b3a764000061271c8680613547565b6127269190613566565b61273091906135d2565b9050670de0b6b3a76400006127458284613547565b61274f9190613566565b94505050505061109d565b6127648284613547565b905061109d565b600a54429080820390821480159061278257508315155b801561278d57508215155b156127a757600b8054858302019055600c80548483020190555b60006127b1611a8a565b80519091506127c09084613530565b91506107088211156128755760408051606081018252848152600b5460208201908152600c549282019283526007805460018101825560009190915291517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688600390930292830155517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68982015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a909101555b60088790556009869055600a83905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000015612b495760006128fa848461261f565b90507f000000000000000000000000000000000000000000000000000000000000000061292f85670de0b6b3a7640000613547565b6129399190613566565b93507f000000000000000000000000000000000000000000000000000000000000000061296e84670de0b6b3a7640000613547565b6129789190613566565b92506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b0316146129bd5784866129c0565b85855b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614612a3f577f0000000000000000000000000000000000000000000000000000000000000000612a3089670de0b6b3a7640000613547565b612a3a9190613566565b612a7c565b7f0000000000000000000000000000000000000000000000000000000000000000612a7289670de0b6b3a7640000613547565b612a7c9190613566565b97506000612a94612a8d848b6135d2565b8584612f7f565b612a9e9083613530565b9050670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b031614612b08577f0000000000000000000000000000000000000000000000000000000000000000612b2a565b7f00000000000000000000000000000000000000000000000000000000000000005b612b349083613547565b612b3e9190613566565b945050505050611297565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614612b8c578385612b8f565b84845b9092509050612b9e87836135d2565b612ba88289613547565b612bb29190613566565b92505050611297565b612bc483612e1f565b612bcd82612e1f565b6001600160a01b03831660009081526004602052604081208054839290612bf5908490613530565b90915550506001600160a01b03821660009081526004602052604081208054839290612c229084906135d2565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612c6e91815260200190565b60405180910390a3505050565b60006003821115612cdc5750806000612c95600283613566565b612ca09060016135d2565b90505b81811015612cd657905080600281612cbb8186613566565b612cc591906135d2565b612ccf9190613566565b9050612ca3565b50919050565b8115612ce6575060015b919050565b612cf482612e1f565b8060026000828254612d0691906135d2565b90915550506001600160a01b03821660009081526004602052604081208054839290612d339084906135d2565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310612d8d57816113a7565b5090919050565b612d9d82612e1f565b8060026000828254612daf9190613530565b90915550506001600160a01b03821660009081526004602052604081208054839290612ddc908490613530565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612d72565b6001600160a01b0381166000908152600460205260409020548015612f4d576001600160a01b0382166000908152600f60209081526040808320805460108085529285208054600d54600e54948190559490955282905593612e818584613530565b90506000612e8f8584613530565b90508115612eea576000670de0b6b3a7640000612eac848a613547565b612eb69190613566565b6001600160a01b038a16600090815260116020526040812080549293508392909190612ee39084906135d2565b9091555050505b8015612f43576000670de0b6b3a7640000612f05838a613547565b612f0f9190613566565b6001600160a01b038a16600090815260126020526040812080549293508392909190612f3c9084906135d2565b9091555050505b5050505050505050565b600d546001600160a01b0383166000908152600f6020908152604080832093909355600e546010909152919020555050565b6000805b60ff81101561308557826000612f99878361308e565b905085811015612fe9576000612faf888761312b565b612fb98389613530565b612fcb90670de0b6b3a7640000613547565b612fd59190613566565b9050612fe181876135d2565b95505061302b565b6000612ff5888761312b565b612fff8884613530565b61301190670de0b6b3a7640000613547565b61301b9190613566565b90506130278187613530565b9550505b8185111561305457600161303f8387613530565b1161304f578493505050506113a7565b613070565b60016130608684613530565b11613070578493505050506113a7565b5050808061307d90613600565b915050612f83565b50909392505050565b6000670de0b6b3a7640000828185816130a78280613547565b6130b19190613566565b6130bb9190613547565b6130c59190613566565b6130cf9190613547565b6130d99190613566565b670de0b6b3a76400008084816130ef8280613547565b6130f99190613566565b6131039190613547565b61310d9190613566565b6131179086613547565b6131219190613566565b6113a791906135d2565b6000670de0b6b3a764000083816131428280613547565b61314c9190613566565b6131569190613547565b6131609190613566565b670de0b6b3a7640000806131748580613547565b61317e9190613566565b613189866003613547565b6131179190613547565b80356001600160a01b0381168114612ce657600080fd5b6000806000806000608086880312156131c257600080fd5b85359450602086013593506131d960408701613193565b9250606086013567ffffffffffffffff808211156131f657600080fd5b818801915088601f83011261320a57600080fd5b81358181111561321957600080fd5b89602082850101111561322b57600080fd5b9699959850939650602001949392505050565b60005b83811015613259578181015183820152602001613241565b83811115613268576000848401525b50505050565b602081526000825180602084015261328d81604085016020870161323e565b601f01601f19169190910160400192915050565b600080604083850312156132b457600080fd5b6132bd83613193565b946020939093013593505050565b600080600080608085870312156132e157600080fd5b6132ea85613193565b966020860135965060408601359560600135945092505050565b6020808252825182820181905260009190848201906040850190845b8181101561333c57835183529284019291840191600101613320565b50909695505050505050565b60006020828403121561335a57600080fd5b6113a782613193565b60008060006060848603121561337857600080fd5b61338184613193565b925061338f60208501613193565b9150604084013590509250925092565b6000602082840312156133b157600080fd5b5035919050565b6000806000606084860312156133cd57600080fd5b6133d684613193565b95602085013595506040909401359392505050565b600080600080600080600060e0888a03121561340657600080fd5b61340f88613193565b965061341d60208901613193565b95506040880135945060608801359350608088013560ff8116811461344157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561347157600080fd5b61347a83613193565b915061348860208401613193565b90509250929050565b600080604083850312156134a457600080fd5b8235915061348860208401613193565b6001600160a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60006020828403121561351357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156135425761354261351a565b500390565b60008160001904831182151516156135615761356161351a565b500290565b60008261358357634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061359c57607f821691505b602082108103612cd657634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600082198211156135e5576135e561351a565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600182016136125761361261351a565b5060010190565b600080835481600182811c91508083168061363557607f831692505b6020808410820361365457634e487b7160e01b86526022600452602486fd5b8180156136685760018114613679576136a6565b60ff198616895284890196506136a6565b60008a81526020902060005b8681101561369e5781548b820152908501908301613685565b505084890196505b509498975050505050505050565b600082516136c681846020870161323e565b9190910192915050565b6000602082840312156136e257600080fd5b815180151581146113a757600080fdfea2646970667358221220a77c6462e49311cf8535f961ef70e841932f13cda16ebaf5f4dbe718f476ec8e64736f6c634300080d003360e060405234801561001057600080fd5b5060405161040c38038061040c83398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c0516103476100c5600039600060fd0152600060cc01526000609701526103476000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063533cf5ce146100465780635b3c92481461005b578063651d83f914610076575b600080fd5b61005961005436600461025f565b61007f565b005b61006460015481565b60405190815260200160405180910390f35b61006460005481565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100c157600080fd5b81156100f2576100f27f00000000000000000000000000000000000000000000000000000000000000008484610128565b8015610123576101237f00000000000000000000000000000000000000000000000000000000000000008483610128565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1161014c57600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916101e391906102ad565b6000604051808303816000865af19150503d8060008114610220576040519150601f19603f3d011682016040523d82523d6000602084013e610225565b606091505b509150915081801561024f57508051158061024f57508080602001905181019061024f91906102e8565b61025857600080fd5b5050505050565b60008060006060848603121561027457600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461029857600080fd5b95602085013595506040909401359392505050565b6000825160005b818110156102ce57602081860181015185830152016102b4565b818111156102dd576000828501525b509190910192915050565b6000602082840312156102fa57600080fd5b8151801515811461030a57600080fd5b939250505056fea26469706673582212206bfeedd1f2b9802e31fed7ffc3a001478f67c16055c890931b1cce8e25481d9664736f6c634300080d0033a2646970667358221220fa2702d04060292df45ac51e485f13120d1f69c60983623cfeaa6ad2b97cec7b64736f6c634300080d0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.