Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Reader
- Optimization enabled
- true
- Compiler version
- v0.6.12+commit.27d51765
- Optimization runs
- 8
- EVM Version
- default
- Verified at
- 2023-07-29T18:23:14.292586Z
contracts/peripherals/Reader.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "../libraries/token/IERC20.sol";
import "../libraries/math/SafeMath.sol";
import "../core/interfaces/IVault.sol";
import "../core/interfaces/IVaultPriceFeed.sol";
import "../tokens/interfaces/IYieldTracker.sol";
import "../tokens/interfaces/IYieldToken.sol";
import "../amm/interfaces/IPancakeFactory.sol";
import "../staking/interfaces/IVester.sol";
import "../access/Governable.sol";
contract Reader is Governable {
using SafeMath for uint256;
uint256 public constant BASIS_POINTS_DIVISOR = 10000;
uint256 public constant POSITION_PROPS_LENGTH = 9;
uint256 public constant PRICE_PRECISION = 10 ** 30;
uint256 public constant USDG_DECIMALS = 18;
bool public hasMaxGlobalShortSizes;
function setConfig(bool _hasMaxGlobalShortSizes) public onlyGov {
hasMaxGlobalShortSizes = _hasMaxGlobalShortSizes;
}
function getMaxAmountIn(IVault _vault, address _tokenIn, address _tokenOut) public view returns (uint256) {
uint256 priceIn = _vault.getMinPrice(_tokenIn);
uint256 priceOut = _vault.getMaxPrice(_tokenOut);
uint256 tokenInDecimals = _vault.tokenDecimals(_tokenIn);
uint256 tokenOutDecimals = _vault.tokenDecimals(_tokenOut);
uint256 amountIn;
{
uint256 poolAmount = _vault.poolAmounts(_tokenOut);
uint256 reservedAmount = _vault.reservedAmounts(_tokenOut);
uint256 bufferAmount = _vault.bufferAmounts(_tokenOut);
uint256 subAmount = reservedAmount > bufferAmount ? reservedAmount : bufferAmount;
if (subAmount >= poolAmount) {
return 0;
}
uint256 availableAmount = poolAmount.sub(subAmount);
amountIn = availableAmount.mul(priceOut).div(priceIn).mul(10 ** tokenInDecimals).div(10 ** tokenOutDecimals);
}
uint256 maxUsdgAmount = _vault.maxUsdgAmounts(_tokenIn);
if (maxUsdgAmount != 0) {
if (maxUsdgAmount < _vault.usdgAmounts(_tokenIn)) {
return 0;
}
uint256 maxAmountIn = maxUsdgAmount.sub(_vault.usdgAmounts(_tokenIn));
maxAmountIn = maxAmountIn.mul(10 ** tokenInDecimals).div(10 ** USDG_DECIMALS);
maxAmountIn = maxAmountIn.mul(PRICE_PRECISION).div(priceIn);
if (amountIn > maxAmountIn) {
return maxAmountIn;
}
}
return amountIn;
}
function getAmountOut(IVault _vault, address _tokenIn, address _tokenOut, uint256 _amountIn) public view returns (uint256, uint256) {
uint256 priceIn = _vault.getMinPrice(_tokenIn);
uint256 tokenInDecimals = _vault.tokenDecimals(_tokenIn);
uint256 tokenOutDecimals = _vault.tokenDecimals(_tokenOut);
uint256 feeBasisPoints;
{
uint256 usdgAmount = _amountIn.mul(priceIn).div(PRICE_PRECISION);
usdgAmount = usdgAmount.mul(10 ** USDG_DECIMALS).div(10 ** tokenInDecimals);
bool isStableSwap = _vault.stableTokens(_tokenIn) && _vault.stableTokens(_tokenOut);
uint256 baseBps = isStableSwap ? _vault.stableSwapFeeBasisPoints() : _vault.swapFeeBasisPoints();
uint256 taxBps = isStableSwap ? _vault.stableTaxBasisPoints() : _vault.taxBasisPoints();
uint256 feesBasisPoints0 = _vault.getFeeBasisPoints(_tokenIn, usdgAmount, baseBps, taxBps, true);
uint256 feesBasisPoints1 = _vault.getFeeBasisPoints(_tokenOut, usdgAmount, baseBps, taxBps, false);
// use the higher of the two fee basis points
feeBasisPoints = feesBasisPoints0 > feesBasisPoints1 ? feesBasisPoints0 : feesBasisPoints1;
}
uint256 priceOut = _vault.getMaxPrice(_tokenOut);
uint256 amountOut = _amountIn.mul(priceIn).div(priceOut);
amountOut = amountOut.mul(10 ** tokenOutDecimals).div(10 ** tokenInDecimals);
uint256 amountOutAfterFees = amountOut.mul(BASIS_POINTS_DIVISOR.sub(feeBasisPoints)).div(BASIS_POINTS_DIVISOR);
uint256 feeAmount = amountOut.sub(amountOutAfterFees);
return (amountOutAfterFees, feeAmount);
}
function getFeeBasisPoints(IVault _vault, address _tokenIn, address _tokenOut, uint256 _amountIn) public view returns (uint256, uint256, uint256) {
uint256 priceIn = _vault.getMinPrice(_tokenIn);
uint256 tokenInDecimals = _vault.tokenDecimals(_tokenIn);
uint256 usdgAmount = _amountIn.mul(priceIn).div(PRICE_PRECISION);
usdgAmount = usdgAmount.mul(10 ** USDG_DECIMALS).div(10 ** tokenInDecimals);
bool isStableSwap = _vault.stableTokens(_tokenIn) && _vault.stableTokens(_tokenOut);
uint256 baseBps = isStableSwap ? _vault.stableSwapFeeBasisPoints() : _vault.swapFeeBasisPoints();
uint256 taxBps = isStableSwap ? _vault.stableTaxBasisPoints() : _vault.taxBasisPoints();
uint256 feesBasisPoints0 = _vault.getFeeBasisPoints(_tokenIn, usdgAmount, baseBps, taxBps, true);
uint256 feesBasisPoints1 = _vault.getFeeBasisPoints(_tokenOut, usdgAmount, baseBps, taxBps, false);
// use the higher of the two fee basis points
uint256 feeBasisPoints = feesBasisPoints0 > feesBasisPoints1 ? feesBasisPoints0 : feesBasisPoints1;
return (feeBasisPoints, feesBasisPoints0, feesBasisPoints1);
}
function getFees(address _vault, address[] memory _tokens) public view returns (uint256[] memory) {
uint256[] memory amounts = new uint256[](_tokens.length);
for (uint256 i = 0; i < _tokens.length; i++) {
amounts[i] = IVault(_vault).feeReserves(_tokens[i]);
}
return amounts;
}
function getTotalStaked(address[] memory _yieldTokens) public view returns (uint256[] memory) {
uint256[] memory amounts = new uint256[](_yieldTokens.length);
for (uint256 i = 0; i < _yieldTokens.length; i++) {
IYieldToken yieldToken = IYieldToken(_yieldTokens[i]);
amounts[i] = yieldToken.totalStaked();
}
return amounts;
}
function getStakingInfo(address _account, address[] memory _yieldTrackers) public view returns (uint256[] memory) {
uint256 propsLength = 2;
uint256[] memory amounts = new uint256[](_yieldTrackers.length * propsLength);
for (uint256 i = 0; i < _yieldTrackers.length; i++) {
IYieldTracker yieldTracker = IYieldTracker(_yieldTrackers[i]);
amounts[i * propsLength] = yieldTracker.claimable(_account);
amounts[i * propsLength + 1] = yieldTracker.getTokensPerInterval();
}
return amounts;
}
function getVestingInfo(address _account, address[] memory _vesters) public view returns (uint256[] memory) {
uint256 propsLength = 7;
uint256[] memory amounts = new uint256[](_vesters.length * propsLength);
for (uint256 i = 0; i < _vesters.length; i++) {
IVester vester = IVester(_vesters[i]);
amounts[i * propsLength] = vester.pairAmounts(_account);
amounts[i * propsLength + 1] = vester.getVestedAmount(_account);
amounts[i * propsLength + 2] = IERC20(_vesters[i]).balanceOf(_account);
amounts[i * propsLength + 3] = vester.claimedAmounts(_account);
amounts[i * propsLength + 4] = vester.claimable(_account);
amounts[i * propsLength + 5] = vester.getMaxVestableAmount(_account);
amounts[i * propsLength + 6] = vester.getCombinedAverageStakedAmount(_account);
}
return amounts;
}
function getPairInfo(address _factory, address[] memory _tokens) public view returns (uint256[] memory) {
uint256 inputLength = 2;
uint256 propsLength = 2;
uint256[] memory amounts = new uint256[](_tokens.length / inputLength * propsLength);
for (uint256 i = 0; i < _tokens.length / inputLength; i++) {
address token0 = _tokens[i * inputLength];
address token1 = _tokens[i * inputLength + 1];
address pair = IPancakeFactory(_factory).getPair(token0, token1);
amounts[i * propsLength] = IERC20(token0).balanceOf(pair);
amounts[i * propsLength + 1] = IERC20(token1).balanceOf(pair);
}
return amounts;
}
function getFundingRates(address _vault, address _weth, address[] memory _tokens) public view returns (uint256[] memory) {
uint256 propsLength = 2;
uint256[] memory fundingRates = new uint256[](_tokens.length * propsLength);
IVault vault = IVault(_vault);
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
if (token == address(0)) {
token = _weth;
}
uint256 fundingRateFactor = vault.stableTokens(token) ? vault.stableFundingRateFactor() : vault.fundingRateFactor();
uint256 reservedAmount = vault.reservedAmounts(token);
uint256 poolAmount = vault.poolAmounts(token);
if (poolAmount > 0) {
fundingRates[i * propsLength] = fundingRateFactor.mul(reservedAmount).div(poolAmount);
}
if (vault.cumulativeFundingRates(token) > 0) {
uint256 nextRate = vault.getNextFundingRate(token);
uint256 baseRate = vault.cumulativeFundingRates(token);
fundingRates[i * propsLength + 1] = baseRate.add(nextRate);
}
}
return fundingRates;
}
function getTokenSupply(IERC20 _token, address[] memory _excludedAccounts) public view returns (uint256) {
uint256 supply = _token.totalSupply();
for (uint256 i = 0; i < _excludedAccounts.length; i++) {
address account = _excludedAccounts[i];
uint256 balance = _token.balanceOf(account);
supply = supply.sub(balance);
}
return supply;
}
function getTotalBalance(IERC20 _token, address[] memory _accounts) public view returns (uint256) {
uint256 totalBalance = 0;
for (uint256 i = 0; i < _accounts.length; i++) {
address account = _accounts[i];
uint256 balance = _token.balanceOf(account);
totalBalance = totalBalance.add(balance);
}
return totalBalance;
}
function getTokenBalances(address _account, address[] memory _tokens) public view returns (uint256[] memory) {
uint256[] memory balances = new uint256[](_tokens.length);
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
if (token == address(0)) {
balances[i] = _account.balance;
continue;
}
balances[i] = IERC20(token).balanceOf(_account);
}
return balances;
}
function getTokenBalancesWithSupplies(address _account, address[] memory _tokens) public view returns (uint256[] memory) {
uint256 propsLength = 2;
uint256[] memory balances = new uint256[](_tokens.length * propsLength);
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
if (token == address(0)) {
balances[i * propsLength] = _account.balance;
balances[i * propsLength + 1] = 0;
continue;
}
balances[i * propsLength] = IERC20(token).balanceOf(_account);
balances[i * propsLength + 1] = IERC20(token).totalSupply();
}
return balances;
}
function getPrices(IVaultPriceFeed _priceFeed, address[] memory _tokens) public view returns (uint256[] memory) {
uint256 propsLength = 6;
uint256[] memory amounts = new uint256[](_tokens.length * propsLength);
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
amounts[i * propsLength] = _priceFeed.getPrice(token, true, true, false);
amounts[i * propsLength + 1] = _priceFeed.getPrice(token, false, true, false);
amounts[i * propsLength + 2] = _priceFeed.getPrimaryPrice(token, true);
amounts[i * propsLength + 3] = _priceFeed.getPrimaryPrice(token, false);
amounts[i * propsLength + 4] = _priceFeed.isAdjustmentAdditive(token) ? 1 : 0;
amounts[i * propsLength + 5] = _priceFeed.adjustmentBasisPoints(token);
}
return amounts;
}
function getVaultTokenInfo(address _vault, address _weth, uint256 _usdgAmount, address[] memory _tokens) public view returns (uint256[] memory) {
uint256 propsLength = 10;
IVault vault = IVault(_vault);
IVaultPriceFeed priceFeed = IVaultPriceFeed(vault.priceFeed());
uint256[] memory amounts = new uint256[](_tokens.length * propsLength);
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
if (token == address(0)) {
token = _weth;
}
amounts[i * propsLength] = vault.poolAmounts(token);
amounts[i * propsLength + 1] = vault.reservedAmounts(token);
amounts[i * propsLength + 2] = vault.usdgAmounts(token);
amounts[i * propsLength + 3] = vault.getRedemptionAmount(token, _usdgAmount);
amounts[i * propsLength + 4] = vault.tokenWeights(token);
amounts[i * propsLength + 5] = vault.getMinPrice(token);
amounts[i * propsLength + 6] = vault.getMaxPrice(token);
amounts[i * propsLength + 7] = vault.guaranteedUsd(token);
amounts[i * propsLength + 8] = priceFeed.getPrimaryPrice(token, false);
amounts[i * propsLength + 9] = priceFeed.getPrimaryPrice(token, true);
}
return amounts;
}
function getFullVaultTokenInfo(address _vault, address _weth, uint256 _usdgAmount, address[] memory _tokens) public view returns (uint256[] memory) {
uint256 propsLength = 12;
IVault vault = IVault(_vault);
IVaultPriceFeed priceFeed = IVaultPriceFeed(vault.priceFeed());
uint256[] memory amounts = new uint256[](_tokens.length * propsLength);
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
if (token == address(0)) {
token = _weth;
}
amounts[i * propsLength] = vault.poolAmounts(token);
amounts[i * propsLength + 1] = vault.reservedAmounts(token);
amounts[i * propsLength + 2] = vault.usdgAmounts(token);
amounts[i * propsLength + 3] = vault.getRedemptionAmount(token, _usdgAmount);
amounts[i * propsLength + 4] = vault.tokenWeights(token);
amounts[i * propsLength + 5] = vault.bufferAmounts(token);
amounts[i * propsLength + 6] = vault.maxUsdgAmounts(token);
amounts[i * propsLength + 7] = vault.getMinPrice(token);
amounts[i * propsLength + 8] = vault.getMaxPrice(token);
amounts[i * propsLength + 9] = vault.guaranteedUsd(token);
amounts[i * propsLength + 10] = priceFeed.getPrimaryPrice(token, false);
amounts[i * propsLength + 11] = priceFeed.getPrimaryPrice(token, true);
}
return amounts;
}
function getVaultTokenInfoV2(address _vault, address _weth, uint256 _usdgAmount, address[] memory _tokens) public view returns (uint256[] memory) {
uint256 propsLength = 14;
IVault vault = IVault(_vault);
IVaultPriceFeed priceFeed = IVaultPriceFeed(vault.priceFeed());
uint256[] memory amounts = new uint256[](_tokens.length * propsLength);
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
if (token == address(0)) {
token = _weth;
}
uint256 maxGlobalShortSize = hasMaxGlobalShortSizes ? vault.maxGlobalShortSizes(token) : 0;
amounts[i * propsLength] = vault.poolAmounts(token);
amounts[i * propsLength + 1] = vault.reservedAmounts(token);
amounts[i * propsLength + 2] = vault.usdgAmounts(token);
amounts[i * propsLength + 3] = vault.getRedemptionAmount(token, _usdgAmount);
amounts[i * propsLength + 4] = vault.tokenWeights(token);
amounts[i * propsLength + 5] = vault.bufferAmounts(token);
amounts[i * propsLength + 6] = vault.maxUsdgAmounts(token);
amounts[i * propsLength + 7] = vault.globalShortSizes(token);
amounts[i * propsLength + 8] = maxGlobalShortSize;
amounts[i * propsLength + 9] = vault.getMinPrice(token);
amounts[i * propsLength + 10] = vault.getMaxPrice(token);
amounts[i * propsLength + 11] = vault.guaranteedUsd(token);
amounts[i * propsLength + 12] = priceFeed.getPrimaryPrice(token, false);
amounts[i * propsLength + 13] = priceFeed.getPrimaryPrice(token, true);
}
return amounts;
}
function getPositions(address _vault, address _account, address[] memory _collateralTokens, address[] memory _indexTokens, bool[] memory _isLong) public view returns(uint256[] memory) {
uint256[] memory amounts = new uint256[](_collateralTokens.length * POSITION_PROPS_LENGTH);
for (uint256 i = 0; i < _collateralTokens.length; i++) {
{
(uint256 size,
uint256 collateral,
uint256 averagePrice,
uint256 entryFundingRate,
/* reserveAmount */,
uint256 realisedPnl,
bool hasRealisedProfit,
uint256 lastIncreasedTime) = IVault(_vault).getPosition(_account, _collateralTokens[i], _indexTokens[i], _isLong[i]);
amounts[i * POSITION_PROPS_LENGTH] = size;
amounts[i * POSITION_PROPS_LENGTH + 1] = collateral;
amounts[i * POSITION_PROPS_LENGTH + 2] = averagePrice;
amounts[i * POSITION_PROPS_LENGTH + 3] = entryFundingRate;
amounts[i * POSITION_PROPS_LENGTH + 4] = hasRealisedProfit ? 1 : 0;
amounts[i * POSITION_PROPS_LENGTH + 5] = realisedPnl;
amounts[i * POSITION_PROPS_LENGTH + 6] = lastIncreasedTime;
}
uint256 size = amounts[i * POSITION_PROPS_LENGTH];
uint256 averagePrice = amounts[i * POSITION_PROPS_LENGTH + 2];
uint256 lastIncreasedTime = amounts[i * POSITION_PROPS_LENGTH + 6];
if (averagePrice > 0) {
(bool hasProfit, uint256 delta) = IVault(_vault).getDelta(_indexTokens[i], size, averagePrice, _isLong[i], lastIncreasedTime);
amounts[i * POSITION_PROPS_LENGTH + 7] = hasProfit ? 1 : 0;
amounts[i * POSITION_PROPS_LENGTH + 8] = delta;
}
}
return amounts;
}
}
contracts/access/Governable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
contract Governable {
address public gov;
constructor() public {
gov = msg.sender;
}
modifier onlyGov() {
require(msg.sender == gov, "Governable: forbidden");
_;
}
function setGov(address _gov) external onlyGov {
gov = _gov;
}
}
contracts/amm/interfaces/IPancakeFactory.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IPancakeFactory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
contracts/core/interfaces/IVault.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "./IVaultUtils.sol";
interface IVault {
function isInitialized() external view returns (bool);
function isSwapEnabled() external view returns (bool);
function isLeverageEnabled() external view returns (bool);
function setVaultUtils(IVaultUtils _vaultUtils) external;
function setError(uint256 _errorCode, string calldata _error) external;
function router() external view returns (address);
function usdg() external view returns (address);
function gov() external view returns (address);
function whitelistedTokenCount() external view returns (uint256);
function maxLeverage() external view returns (uint256);
function minProfitTime() external view returns (uint256);
function hasDynamicFees() external view returns (bool);
function fundingInterval() external view returns (uint256);
function totalTokenWeights() external view returns (uint256);
function getTargetUsdgAmount(address _token) external view returns (uint256);
function inManagerMode() external view returns (bool);
function inPrivateLiquidationMode() external view returns (bool);
function maxGasPrice() external view returns (uint256);
function approvedRouters(address _account, address _router) external view returns (bool);
function isLiquidator(address _account) external view returns (bool);
function isManager(address _account) external view returns (bool);
function minProfitBasisPoints(address _token) external view returns (uint256);
function tokenBalances(address _token) external view returns (uint256);
function lastFundingTimes(address _token) external view returns (uint256);
function setMaxLeverage(uint256 _maxLeverage) external;
function setInManagerMode(bool _inManagerMode) external;
function setManager(address _manager, bool _isManager) external;
function setIsSwapEnabled(bool _isSwapEnabled) external;
function setIsLeverageEnabled(bool _isLeverageEnabled) external;
function setMaxGasPrice(uint256 _maxGasPrice) external;
function setUsdgAmount(address _token, uint256 _amount) external;
function setBufferAmount(address _token, uint256 _amount) external;
function setMaxGlobalShortSize(address _token, uint256 _amount) external;
function setInPrivateLiquidationMode(bool _inPrivateLiquidationMode) external;
function setLiquidator(address _liquidator, bool _isActive) external;
function setFundingRate(uint256 _fundingInterval, uint256 _fundingRateFactor, uint256 _stableFundingRateFactor) external;
function setFees(
uint256 _taxBasisPoints,
uint256 _stableTaxBasisPoints,
uint256 _mintBurnFeeBasisPoints,
uint256 _swapFeeBasisPoints,
uint256 _stableSwapFeeBasisPoints,
uint256 _marginFeeBasisPoints,
uint256 _liquidationFeeUsd,
uint256 _minProfitTime,
bool _hasDynamicFees
) external;
function setTokenConfig(
address _token,
uint256 _tokenDecimals,
uint256 _redemptionBps,
uint256 _minProfitBps,
uint256 _maxUsdgAmount,
bool _isStable,
bool _isShortable
) external;
function setPriceFeed(address _priceFeed) external;
function withdrawFees(address _token, address _receiver) external returns (uint256);
function directPoolDeposit(address _token) external;
function buyUSDG(address _token, address _receiver) external returns (uint256);
function sellUSDG(address _token, address _receiver) external returns (uint256);
function swap(address _tokenIn, address _tokenOut, address _receiver) external returns (uint256);
function increasePosition(address _account, address _collateralToken, address _indexToken, uint256 _sizeDelta, bool _isLong) external;
function decreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external returns (uint256);
function validateLiquidation(address _account, address _collateralToken, address _indexToken, bool _isLong, bool _raise) external view returns (uint256, uint256);
function liquidatePosition(address _account, address _collateralToken, address _indexToken, bool _isLong, address _feeReceiver) external;
function tokenToUsdMin(address _token, uint256 _tokenAmount) external view returns (uint256);
function priceFeed() external view returns (address);
function fundingRateFactor() external view returns (uint256);
function stableFundingRateFactor() external view returns (uint256);
function cumulativeFundingRates(address _token) external view returns (uint256);
function getNextFundingRate(address _token) external view returns (uint256);
function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256);
function liquidationFeeUsd() external view returns (uint256);
function taxBasisPoints() external view returns (uint256);
function stableTaxBasisPoints() external view returns (uint256);
function mintBurnFeeBasisPoints() external view returns (uint256);
function swapFeeBasisPoints() external view returns (uint256);
function stableSwapFeeBasisPoints() external view returns (uint256);
function marginFeeBasisPoints() external view returns (uint256);
function allWhitelistedTokensLength() external view returns (uint256);
function allWhitelistedTokens(uint256) external view returns (address);
function whitelistedTokens(address _token) external view returns (bool);
function stableTokens(address _token) external view returns (bool);
function shortableTokens(address _token) external view returns (bool);
function feeReserves(address _token) external view returns (uint256);
function globalShortSizes(address _token) external view returns (uint256);
function globalShortAveragePrices(address _token) external view returns (uint256);
function maxGlobalShortSizes(address _token) external view returns (uint256);
function tokenDecimals(address _token) external view returns (uint256);
function tokenWeights(address _token) external view returns (uint256);
function guaranteedUsd(address _token) external view returns (uint256);
function poolAmounts(address _token) external view returns (uint256);
function bufferAmounts(address _token) external view returns (uint256);
function reservedAmounts(address _token) external view returns (uint256);
function usdgAmounts(address _token) external view returns (uint256);
function maxUsdgAmounts(address _token) external view returns (uint256);
function getRedemptionAmount(address _token, uint256 _usdgAmount) external view returns (uint256);
function getMaxPrice(address _token) external view returns (uint256);
function getMinPrice(address _token) external view returns (uint256);
function getDelta(address _indexToken, uint256 _size, uint256 _averagePrice, bool _isLong, uint256 _lastIncreasedTime) external view returns (bool, uint256);
function getPosition(address _account, address _collateralToken, address _indexToken, bool _isLong) external view returns (uint256, uint256, uint256, uint256, uint256, uint256, bool, uint256);
}
contracts/core/interfaces/IVaultPriceFeed.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IVaultPriceFeed {
function adjustmentBasisPoints(address _token) external view returns (uint256);
function isAdjustmentAdditive(address _token) external view returns (bool);
function setAdjustment(address _token, bool _isAdditive, uint256 _adjustmentBps) external;
function setUseV2Pricing(bool _useV2Pricing) external;
function setIsAmmEnabled(bool _isEnabled) external;
function setIsSecondaryPriceEnabled(bool _isEnabled) external;
function setSpreadBasisPoints(address _token, uint256 _spreadBasisPoints) external;
function setSpreadThresholdBasisPoints(uint256 _spreadThresholdBasisPoints) external;
function setFavorPrimaryPrice(bool _favorPrimaryPrice) external;
function setPriceSampleSpace(uint256 _priceSampleSpace) external;
function setMaxStrictPriceDeviation(uint256 _maxStrictPriceDeviation) external;
function getPrice(address _token, bool _maximise, bool _includeAmmPrice, bool _useSwapPricing) external view returns (uint256);
function getAmmPrice(address _token) external view returns (uint256);
function getLatestPrimaryPrice(address _token) external view returns (uint256);
function getPrimaryPrice(address _token, bool _maximise) external view returns (uint256);
function setTokenConfig(
address _token,
address _priceFeed,
uint256 _priceDecimals,
bool _isStrictStable
) external;
}
contracts/core/interfaces/IVaultUtils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IVaultUtils {
function updateCumulativeFundingRate(address _collateralToken, address _indexToken) external returns (bool);
function validateIncreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _sizeDelta, bool _isLong) external view;
function validateDecreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external view;
function validateLiquidation(address _account, address _collateralToken, address _indexToken, bool _isLong, bool _raise) external view returns (uint256, uint256);
function getEntryFundingRate(address _collateralToken, address _indexToken, bool _isLong) external view returns (uint256);
function getPositionFee(address _account, address _collateralToken, address _indexToken, bool _isLong, uint256 _sizeDelta) external view returns (uint256);
function getFundingFee(address _account, address _collateralToken, address _indexToken, bool _isLong, uint256 _size, uint256 _entryFundingRate) external view returns (uint256);
function getBuyUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256);
function getSellUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256);
function getSwapFeeBasisPoints(address _tokenIn, address _tokenOut, uint256 _usdgAmount) external view returns (uint256);
function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256);
}
contracts/libraries/math/SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
contracts/libraries/token/IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contracts/staking/interfaces/IVester.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IVester {
function rewardTracker() external view returns (address);
function claimForAccount(address _account, address _receiver) external returns (uint256);
function claimable(address _account) external view returns (uint256);
function cumulativeClaimAmounts(address _account) external view returns (uint256);
function claimedAmounts(address _account) external view returns (uint256);
function pairAmounts(address _account) external view returns (uint256);
function getVestedAmount(address _account) external view returns (uint256);
function transferredAverageStakedAmounts(address _account) external view returns (uint256);
function transferredCumulativeRewards(address _account) external view returns (uint256);
function cumulativeRewardDeductions(address _account) external view returns (uint256);
function bonusRewards(address _account) external view returns (uint256);
function transferStakeValues(address _sender, address _receiver) external;
function setTransferredAverageStakedAmounts(address _account, uint256 _amount) external;
function setTransferredCumulativeRewards(address _account, uint256 _amount) external;
function setCumulativeRewardDeductions(address _account, uint256 _amount) external;
function setBonusRewards(address _account, uint256 _amount) external;
function getMaxVestableAmount(address _account) external view returns (uint256);
function getCombinedAverageStakedAmount(address _account) external view returns (uint256);
}
contracts/tokens/interfaces/IYieldToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IYieldToken {
function totalStaked() external view returns (uint256);
function stakedBalance(address _account) external view returns (uint256);
function removeAdmin(address _account) external;
}
contracts/tokens/interfaces/IYieldTracker.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IYieldTracker {
function claim(address _account, address _receiver) external returns (uint256);
function updateRewards(address _account) external;
function getTokensPerInterval() external view returns (uint256);
function claimable(address _account) external view returns (uint256);
}
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":8,"enabled":true},"libraries":{}}
Contract ABI
[{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"BASIS_POINTS_DIVISOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"POSITION_PROPS_LENGTH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"PRICE_PRECISION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"USDG_DECIMALS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAmountOut","inputs":[{"type":"address","name":"_vault","internalType":"contract IVault"},{"type":"address","name":"_tokenIn","internalType":"address"},{"type":"address","name":"_tokenOut","internalType":"address"},{"type":"uint256","name":"_amountIn","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getFeeBasisPoints","inputs":[{"type":"address","name":"_vault","internalType":"contract IVault"},{"type":"address","name":"_tokenIn","internalType":"address"},{"type":"address","name":"_tokenOut","internalType":"address"},{"type":"uint256","name":"_amountIn","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getFees","inputs":[{"type":"address","name":"_vault","internalType":"address"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getFullVaultTokenInfo","inputs":[{"type":"address","name":"_vault","internalType":"address"},{"type":"address","name":"_weth","internalType":"address"},{"type":"uint256","name":"_usdgAmount","internalType":"uint256"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getFundingRates","inputs":[{"type":"address","name":"_vault","internalType":"address"},{"type":"address","name":"_weth","internalType":"address"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMaxAmountIn","inputs":[{"type":"address","name":"_vault","internalType":"contract IVault"},{"type":"address","name":"_tokenIn","internalType":"address"},{"type":"address","name":"_tokenOut","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getPairInfo","inputs":[{"type":"address","name":"_factory","internalType":"address"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getPositions","inputs":[{"type":"address","name":"_vault","internalType":"address"},{"type":"address","name":"_account","internalType":"address"},{"type":"address[]","name":"_collateralTokens","internalType":"address[]"},{"type":"address[]","name":"_indexTokens","internalType":"address[]"},{"type":"bool[]","name":"_isLong","internalType":"bool[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getPrices","inputs":[{"type":"address","name":"_priceFeed","internalType":"contract IVaultPriceFeed"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getStakingInfo","inputs":[{"type":"address","name":"_account","internalType":"address"},{"type":"address[]","name":"_yieldTrackers","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getTokenBalances","inputs":[{"type":"address","name":"_account","internalType":"address"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getTokenBalancesWithSupplies","inputs":[{"type":"address","name":"_account","internalType":"address"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTokenSupply","inputs":[{"type":"address","name":"_token","internalType":"contract IERC20"},{"type":"address[]","name":"_excludedAccounts","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalBalance","inputs":[{"type":"address","name":"_token","internalType":"contract IERC20"},{"type":"address[]","name":"_accounts","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getTotalStaked","inputs":[{"type":"address[]","name":"_yieldTokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getVaultTokenInfo","inputs":[{"type":"address","name":"_vault","internalType":"address"},{"type":"address","name":"_weth","internalType":"address"},{"type":"uint256","name":"_usdgAmount","internalType":"uint256"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getVaultTokenInfoV2","inputs":[{"type":"address","name":"_vault","internalType":"address"},{"type":"address","name":"_weth","internalType":"address"},{"type":"uint256","name":"_usdgAmount","internalType":"uint256"},{"type":"address[]","name":"_tokens","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getVestingInfo","inputs":[{"type":"address","name":"_account","internalType":"address"},{"type":"address[]","name":"_vesters","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"gov","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasMaxGlobalShortSizes","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setConfig","inputs":[{"type":"bool","name":"_hasMaxGlobalShortSizes","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGov","inputs":[{"type":"address","name":"_gov","internalType":"address"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b50600080546001600160a01b031916331790556159ff80620000336000396000f3fe608060405234801561001057600080fd5b506004361061013e5760003560e01c8063126082cf1461014357806312d43a511461015d57806320542568146101815780632413c8c1146102925780632ac0184c146103335780632e3e3342146103e45780633613d52714610495578063440f018c1461054657806348211934146105a05780637b906e931461065157806386d4d0f514610712578063870d917c146107c35780638e83ca32146107cb578063937a0be81461088c57806395082d251461093d57806395a7535a146109455780639b0183c3146109ff578063a4543ead14610a20578063ad7e549714610ad1578063c6f1d67614610ad9578063cfad57a214610af5578063d7176ca914610b1b578063d802178e14610b70578063dc383cab14610c21578063f3535e6c14610ddf578063fbdb05ca14610e17575b600080fd5b61014b610ec8565b60408051918252519081900360200190f35b610165610ece565b604080516001600160a01b039092168252519081900360200190f35b6102426004803603608081101561019757600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156101d157600080fd5b8201836020820111156101e357600080fd5b803590602001918460208302840111600160201b8311171561020457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610edd945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561027e578181015183820152602001610266565b505050509050019250505060405180910390f35b610242600480360360208110156102a857600080fd5b810190602081018135600160201b8111156102c257600080fd5b8201836020820111156102d457600080fd5b803590602001918460208302840111600160201b831117156102f557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506115eb945050505050565b61014b6004803603604081101561034957600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561037357600080fd5b82018360208201111561038557600080fd5b803590602001918460208302840111600160201b831117156103a657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506116e4945050505050565b610242600480360360408110156103fa57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561042457600080fd5b82018360208201111561043657600080fd5b803590602001918460208302840111600160201b8311171561045757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061180f945050505050565b610242600480360360408110156104ab57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104d557600080fd5b8201836020820111156104e757600080fd5b803590602001918460208302840111600160201b8311171561050857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a14945050505050565b6105826004803603608081101561055c57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611e4e565b60408051938452602084019290925282820152519081900360600190f35b610242600480360360408110156105b657600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156105e057600080fd5b8201836020820111156105f257600080fd5b803590602001918460208302840111600160201b8311171561061357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506123b3945050505050565b6102426004803603608081101561066757600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156106a157600080fd5b8201836020820111156106b357600080fd5b803590602001918460208302840111600160201b831117156106d457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612867945050505050565b6102426004803603604081101561072857600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561075257600080fd5b82018360208201111561076457600080fd5b803590602001918460208302840111600160201b8311171561078557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613098945050505050565b61014b613198565b610242600480360360808110156107e157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561081b57600080fd5b82018360208201111561082d57600080fd5b803590602001918460208302840111600160201b8311171561084e57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061319d945050505050565b610242600480360360408110156108a257600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156108cc57600080fd5b8201836020820111156108de57600080fd5b803590602001918460208302840111600160201b831117156108ff57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613b1a945050505050565b61014b613caf565b6102426004803603606081101561095b57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561098e57600080fd5b8201836020820111156109a057600080fd5b803590602001918460208302840111600160201b831117156109c157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613cbf945050505050565b610a1e60048036036020811015610a1557600080fd5b5035151561418d565b005b61024260048036036040811015610a3657600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610a6057600080fd5b820183602082011115610a7257600080fd5b803590602001918460208302840111600160201b83111715610a9357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614202945050505050565b61014b61446e565b610ae1614473565b604080519115158252519081900360200190f35b610a1e60048036036020811015610b0b57600080fd5b50356001600160a01b0316614483565b610b5760048036036080811015610b3157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356144fc565b6040805192835260208301919091528051918290030190f35b61024260048036036040811015610b8657600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610bb057600080fd5b820183602082011115610bc257600080fd5b803590602001918460208302840111600160201b83111715610be357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614bb2945050505050565b610242600480360360a0811015610c3757600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610c6a57600080fd5b820183602082011115610c7c57600080fd5b803590602001918460208302840111600160201b83111715610c9d57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610cec57600080fd5b820183602082011115610cfe57600080fd5b803590602001918460208302840111600160201b83111715610d1f57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610d6e57600080fd5b820183602082011115610d8057600080fd5b803590602001918460208302840111600160201b83111715610da157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614cfe945050505050565b61014b60048036036060811015610df557600080fd5b506001600160a01b0381358116916020810135821691604090910135166150fa565b61014b60048036036040811015610e2d57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610e5757600080fd5b820183602082011115610e6957600080fd5b803590602001918460208302840111600160201b83111715610e8a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506156c1945050505050565b61271081565b6000546001600160a01b031681565b60606000600a905060008690506000816001600160a01b031663741bef1a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2557600080fd5b505afa158015610f39573d6000803e3d6000fd5b505050506040513d6020811015610f4f57600080fd5b5051855190915060609084026001600160401b0381118015610f7057600080fd5b50604051908082528060200260200182016040528015610f9a578160200160208202803683370190505b50905060005b86518110156115de576000878281518110610fb757fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415610fdf5750885b846001600160a01b03166352f55eed826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561102c57600080fd5b505afa158015611040573d6000803e3d6000fd5b505050506040513d602081101561105657600080fd5b50518351849084890290811061106857fe5b602002602001018181525050846001600160a01b031663c3c7b9e9826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156110c157600080fd5b505afa1580156110d5573d6000803e3d6000fd5b505050506040513d60208110156110eb57600080fd5b5051835184906001858a020190811061110057fe5b602002602001018181525050846001600160a01b0316631aa4ace5826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d602081101561118357600080fd5b5051835184906002858a020190811061119857fe5b602002602001018181525050846001600160a01b0316632c668ec1828b6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b1580156111f957600080fd5b505afa15801561120d573d6000803e3d6000fd5b505050506040513d602081101561122357600080fd5b5051835184906003858a020190811061123857fe5b602002602001018181525050846001600160a01b031663ab2f3ad4826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561129157600080fd5b505afa1580156112a5573d6000803e3d6000fd5b505050506040513d60208110156112bb57600080fd5b5051835184906004858a02019081106112d057fe5b602002602001018181525050846001600160a01b03166381a612d6826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561132957600080fd5b505afa15801561133d573d6000803e3d6000fd5b505050506040513d602081101561135357600080fd5b5051835184906005858a020190811061136857fe5b602002602001018181525050846001600160a01b031663e124e6d2826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156113c157600080fd5b505afa1580156113d5573d6000803e3d6000fd5b505050506040513d60208110156113eb57600080fd5b5051835184906006858a020190811061140057fe5b602002602001018181525050846001600160a01b031663f07456ce826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561145957600080fd5b505afa15801561146d573d6000803e3d6000fd5b505050506040513d602081101561148357600080fd5b5051835184906007858a020190811061149857fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600060248301529151918716926356c8c2c192604480840193829003018186803b1580156114f257600080fd5b505afa158015611506573d6000803e3d6000fd5b505050506040513d602081101561151c57600080fd5b5051835184906008858a020190811061153157fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600160248301529151918716926356c8c2c192604480840193829003018186803b15801561158b57600080fd5b505afa15801561159f573d6000803e3d6000fd5b505050506040513d60208110156115b557600080fd5b5051835184906009858a02019081106115ca57fe5b602090810291909101015250600101610fa0565b5098975050505050505050565b60608082516001600160401b038111801561160557600080fd5b5060405190808252806020026020018201604052801561162f578160200160208202803683370190505b50905060005b83518110156116dd57600084828151811061164c57fe5b60200260200101519050806001600160a01b031663817b1cd26040518163ffffffff1660e01b815260040160206040518083038186803b15801561168f57600080fd5b505afa1580156116a3573d6000803e3d6000fd5b505050506040513d60208110156116b957600080fd5b505183518490849081106116c957fe5b602090810291909101015250600101611635565b5092915050565b600080836001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561172057600080fd5b505afa158015611734573d6000803e3d6000fd5b505050506040513d602081101561174a57600080fd5b5051905060005b835181101561180557600084828151811061176857fe5b602002602001015190506000866001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156117c157600080fd5b505afa1580156117d5573d6000803e3d6000fd5b505050506040513d60208110156117eb57600080fd5b505190506117f9848261577a565b93505050600101611751565b5090505b92915050565b60606000600290506060818451026001600160401b038111801561183257600080fd5b5060405190808252806020026020018201604052801561185c578160200160208202803683370190505b50905060005b8451811015611a0b57600085828151811061187957fe5b6020026020010151905060006001600160a01b0316816001600160a01b031614156118e857866001600160a01b03163183858402815181106118b757fe5b602002602001018181525050600083858402600101815181106118d657fe5b60200260200101818152505050611a03565b806001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561193557600080fd5b505afa158015611949573d6000803e3d6000fd5b505050506040513d602081101561195f57600080fd5b50518351849084870290811061197157fe5b602002602001018181525050806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119b657600080fd5b505afa1580156119ca573d6000803e3d6000fd5b505050506040513d60208110156119e057600080fd5b5051835184906001858802019081106119f557fe5b602002602001018181525050505b600101611862565b50949350505050565b60606000600690506060818451026001600160401b0381118015611a3757600080fd5b50604051908082528060200260200182016040528015611a61578160200160208202803683370190505b50905060005b8451811015611a0b576000858281518110611a7e57fe5b602090810291909101810151604080516317e1d38560e11b81526001600160a01b0380841660048301526001602483018190526044830152600060648301529151929450908a1692632fc3a70a92608480840193829003018186803b158015611ae657600080fd5b505afa158015611afa573d6000803e3d6000fd5b505050506040513d6020811015611b1057600080fd5b505183518490848702908110611b2257fe5b602090810291909101810191909152604080516317e1d38560e11b81526001600160a01b0384811660048301526000602483018190526001604484015260648301529151918a1692632fc3a70a92608480840193829003018186803b158015611b8a57600080fd5b505afa158015611b9e573d6000803e3d6000fd5b505050506040513d6020811015611bb457600080fd5b505183518490600185880201908110611bc957fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600160248301529151918a16926356c8c2c192604480840193829003018186803b158015611c2357600080fd5b505afa158015611c37573d6000803e3d6000fd5b505050506040513d6020811015611c4d57600080fd5b505183518490600285880201908110611c6257fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600060248301529151918a16926356c8c2c192604480840193829003018186803b158015611cbc57600080fd5b505afa158015611cd0573d6000803e3d6000fd5b505050506040513d6020811015611ce657600080fd5b505183518490600385880201908110611cfb57fe5b602002602001018181525050866001600160a01b0316636ce8a44b826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611d5457600080fd5b505afa158015611d68573d6000803e3d6000fd5b505050506040513d6020811015611d7e57600080fd5b5051611d8b576000611d8e565b60015b60ff168385840260040181518110611da257fe5b602002602001018181525050866001600160a01b03166348cac277826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611dfb57600080fd5b505afa158015611e0f573d6000803e3d6000fd5b505050506040513d6020811015611e2557600080fd5b505183518490600585880201908110611e3a57fe5b602090810291909101015250600101611a67565b600080600080876001600160a01b03166381a612d6886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611ea157600080fd5b505afa158015611eb5573d6000803e3d6000fd5b505050506040513d6020811015611ecb57600080fd5b5051604080516323b95ceb60e21b81526001600160a01b038a811660048301529151929350600092918b1691638ee573ac91602480820192602092909190829003018186803b158015611f1d57600080fd5b505afa158015611f31573d6000803e3d6000fd5b505050506040513d6020811015611f4757600080fd5b505190506000611f6d68327cb2734119d3b7a9601e1b611f6789866157bc565b90615815565b9050611f89600a83900a611f6783670de0b6b3a76400006157bc565b905060008a6001600160a01b03166342b60b038b6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fda57600080fd5b505afa158015611fee573d6000803e3d6000fd5b505050506040513d602081101561200457600080fd5b5051801561208757508a6001600160a01b03166342b60b038a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561205a57600080fd5b505afa15801561206e573d6000803e3d6000fd5b505050506040513d602081101561208457600080fd5b50515b90506000816120fa578b6001600160a01b031663a22f23926040518163ffffffff1660e01b815260040160206040518083038186803b1580156120c957600080fd5b505afa1580156120dd573d6000803e3d6000fd5b505050506040513d60208110156120f357600080fd5b5051612160565b8b6001600160a01b031663df73a2676040518163ffffffff1660e01b815260040160206040518083038186803b15801561213357600080fd5b505afa158015612147573d6000803e3d6000fd5b505050506040513d602081101561215d57600080fd5b50515b90506000826121d3578c6001600160a01b0316637a210a2b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121a257600080fd5b505afa1580156121b6573d6000803e3d6000fd5b505050506040513d60208110156121cc57600080fd5b5051612239565b8c6001600160a01b03166310eb56c26040518163ffffffff1660e01b815260040160206040518083038186803b15801561220c57600080fd5b505afa158015612220573d6000803e3d6000fd5b505050506040513d602081101561223657600080fd5b50515b905060008d6001600160a01b031663c7e074c38e87868660016040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b1580156122ad57600080fd5b505afa1580156122c1573d6000803e3d6000fd5b505050506040513d60208110156122d757600080fd5b8101908080519060200190929190505050905060008e6001600160a01b031663c7e074c38e88878760006040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b15801561235c57600080fd5b505afa158015612370573d6000803e3d6000fd5b505050506040513d602081101561238657600080fd5b505190506000818311612399578161239b565b825b9b509199509750505050505050509450945094915050565b60606000600790506060818451026001600160401b03811180156123d657600080fd5b50604051908082528060200260200182016040528015612400578160200160208202803683370190505b50905060005b8451811015611a0b57600085828151811061241d57fe5b60200260200101519050806001600160a01b0316635d50e729886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561247457600080fd5b505afa158015612488573d6000803e3d6000fd5b505050506040513d602081101561249e57600080fd5b5051835184908487029081106124b057fe5b602002602001018181525050806001600160a01b031663d5a73fdd886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561250957600080fd5b505afa15801561251d573d6000803e3d6000fd5b505050506040513d602081101561253357600080fd5b50518351849060018588020190811061254857fe5b60200260200101818152505085828151811061256057fe5b60200260200101516001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156125b457600080fd5b505afa1580156125c8573d6000803e3d6000fd5b505050506040513d60208110156125de57600080fd5b5051835184906002858802019081106125f357fe5b602002602001018181525050806001600160a01b03166371417b32886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561264c57600080fd5b505afa158015612660573d6000803e3d6000fd5b505050506040513d602081101561267657600080fd5b50518351849060038588020190811061268b57fe5b602002602001018181525050806001600160a01b031663402914f5886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156126e457600080fd5b505afa1580156126f8573d6000803e3d6000fd5b505050506040513d602081101561270e57600080fd5b50518351849060048588020190811061272357fe5b602002602001018181525050806001600160a01b03166308f26c76886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561277c57600080fd5b505afa158015612790573d6000803e3d6000fd5b505050506040513d60208110156127a657600080fd5b5051835184906005858802019081106127bb57fe5b602002602001018181525050806001600160a01b03166345f01ee6886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561281457600080fd5b505afa158015612828573d6000803e3d6000fd5b505050506040513d602081101561283e57600080fd5b50518351849060068588020190811061285357fe5b602090810291909101015250600101612406565b60606000600c905060008690506000816001600160a01b031663741bef1a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156128af57600080fd5b505afa1580156128c3573d6000803e3d6000fd5b505050506040513d60208110156128d957600080fd5b5051855190915060609084026001600160401b03811180156128fa57600080fd5b50604051908082528060200260200182016040528015612924578160200160208202803683370190505b50905060005b86518110156115de57600087828151811061294157fe5b6020026020010151905060006001600160a01b0316816001600160a01b031614156129695750885b846001600160a01b03166352f55eed826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156129b657600080fd5b505afa1580156129ca573d6000803e3d6000fd5b505050506040513d60208110156129e057600080fd5b5051835184908489029081106129f257fe5b602002602001018181525050846001600160a01b031663c3c7b9e9826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612a4b57600080fd5b505afa158015612a5f573d6000803e3d6000fd5b505050506040513d6020811015612a7557600080fd5b5051835184906001858a0201908110612a8a57fe5b602002602001018181525050846001600160a01b0316631aa4ace5826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612ae357600080fd5b505afa158015612af7573d6000803e3d6000fd5b505050506040513d6020811015612b0d57600080fd5b5051835184906002858a0201908110612b2257fe5b602002602001018181525050846001600160a01b0316632c668ec1828b6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b158015612b8357600080fd5b505afa158015612b97573d6000803e3d6000fd5b505050506040513d6020811015612bad57600080fd5b5051835184906003858a0201908110612bc257fe5b602002602001018181525050846001600160a01b031663ab2f3ad4826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612c1b57600080fd5b505afa158015612c2f573d6000803e3d6000fd5b505050506040513d6020811015612c4557600080fd5b5051835184906004858a0201908110612c5a57fe5b602002602001018181525050846001600160a01b0316634a993ee9826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612cb357600080fd5b505afa158015612cc7573d6000803e3d6000fd5b505050506040513d6020811015612cdd57600080fd5b5051835184906005858a0201908110612cf257fe5b602002602001018181525050846001600160a01b031663ad1e4f8d826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612d4b57600080fd5b505afa158015612d5f573d6000803e3d6000fd5b505050506040513d6020811015612d7557600080fd5b5051835184906006858a0201908110612d8a57fe5b602002602001018181525050846001600160a01b03166381a612d6826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612de357600080fd5b505afa158015612df7573d6000803e3d6000fd5b505050506040513d6020811015612e0d57600080fd5b5051835184906007858a0201908110612e2257fe5b602002602001018181525050846001600160a01b031663e124e6d2826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612e7b57600080fd5b505afa158015612e8f573d6000803e3d6000fd5b505050506040513d6020811015612ea557600080fd5b5051835184906008858a0201908110612eba57fe5b602002602001018181525050846001600160a01b031663f07456ce826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612f1357600080fd5b505afa158015612f27573d6000803e3d6000fd5b505050506040513d6020811015612f3d57600080fd5b5051835184906009858a0201908110612f5257fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600060248301529151918716926356c8c2c192604480840193829003018186803b158015612fac57600080fd5b505afa158015612fc0573d6000803e3d6000fd5b505050506040513d6020811015612fd657600080fd5b505183518490600a858a0201908110612feb57fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600160248301529151918716926356c8c2c192604480840193829003018186803b15801561304557600080fd5b505afa158015613059573d6000803e3d6000fd5b505050506040513d602081101561306f57600080fd5b505183518490600b858a020190811061308457fe5b60209081029190910101525060010161292a565b60608082516001600160401b03811180156130b257600080fd5b506040519080825280602002602001820160405280156130dc578160200160208202803683370190505b50905060005b835181101561180557846001600160a01b0316631ce9cb8f85838151811061310657fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561314b57600080fd5b505afa15801561315f573d6000803e3d6000fd5b505050506040513d602081101561317557600080fd5b5051825183908390811061318557fe5b60209081029190910101526001016130e2565b601281565b60606000600e905060008690506000816001600160a01b031663741bef1a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156131e557600080fd5b505afa1580156131f9573d6000803e3d6000fd5b505050506040513d602081101561320f57600080fd5b5051855190915060609084026001600160401b038111801561323057600080fd5b5060405190808252806020026020018201604052801561325a578160200160208202803683370190505b50905060005b86518110156115de57600087828151811061327757fe5b6020026020010151905060006001600160a01b0316816001600160a01b0316141561329f5750885b60008054600160a01b900460ff166132b8576000613332565b856001600160a01b0316639698d25a836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561330557600080fd5b505afa158015613319573d6000803e3d6000fd5b505050506040513d602081101561332f57600080fd5b50515b9050856001600160a01b03166352f55eed836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561338157600080fd5b505afa158015613395573d6000803e3d6000fd5b505050506040513d60208110156133ab57600080fd5b505184518590858a029081106133bd57fe5b602002602001018181525050856001600160a01b031663c3c7b9e9836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561341657600080fd5b505afa15801561342a573d6000803e3d6000fd5b505050506040513d602081101561344057600080fd5b5051845185906001868b020190811061345557fe5b602002602001018181525050856001600160a01b0316631aa4ace5836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156134ae57600080fd5b505afa1580156134c2573d6000803e3d6000fd5b505050506040513d60208110156134d857600080fd5b5051845185906002868b02019081106134ed57fe5b602002602001018181525050856001600160a01b0316632c668ec1838c6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b15801561354e57600080fd5b505afa158015613562573d6000803e3d6000fd5b505050506040513d602081101561357857600080fd5b5051845185906003868b020190811061358d57fe5b602002602001018181525050856001600160a01b031663ab2f3ad4836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156135e657600080fd5b505afa1580156135fa573d6000803e3d6000fd5b505050506040513d602081101561361057600080fd5b5051845185906004868b020190811061362557fe5b602002602001018181525050856001600160a01b0316634a993ee9836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561367e57600080fd5b505afa158015613692573d6000803e3d6000fd5b505050506040513d60208110156136a857600080fd5b5051845185906005868b02019081106136bd57fe5b602002602001018181525050856001600160a01b031663ad1e4f8d836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561371657600080fd5b505afa15801561372a573d6000803e3d6000fd5b505050506040513d602081101561374057600080fd5b5051845185906006868b020190811061375557fe5b602002602001018181525050856001600160a01b0316638a78daa8836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156137ae57600080fd5b505afa1580156137c2573d6000803e3d6000fd5b505050506040513d60208110156137d857600080fd5b5051845185906007868b02019081106137ed57fe5b60200260200101818152505080848885026008018151811061380b57fe5b602002602001018181525050856001600160a01b03166381a612d6836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561386457600080fd5b505afa158015613878573d6000803e3d6000fd5b505050506040513d602081101561388e57600080fd5b5051845185906009868b02019081106138a357fe5b602002602001018181525050856001600160a01b031663e124e6d2836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156138fc57600080fd5b505afa158015613910573d6000803e3d6000fd5b505050506040513d602081101561392657600080fd5b505184518590600a868b020190811061393b57fe5b602002602001018181525050856001600160a01b031663f07456ce836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561399457600080fd5b505afa1580156139a8573d6000803e3d6000fd5b505050506040513d60208110156139be57600080fd5b505184518590600b868b02019081106139d357fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038581166004830152600060248301529151918816926356c8c2c192604480840193829003018186803b158015613a2d57600080fd5b505afa158015613a41573d6000803e3d6000fd5b505050506040513d6020811015613a5757600080fd5b505184518590600c868b0201908110613a6c57fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038581166004830152600160248301529151918816926356c8c2c192604480840193829003018186803b158015613ac657600080fd5b505afa158015613ada573d6000803e3d6000fd5b505050506040513d6020811015613af057600080fd5b505184518590600d868b0201908110613b0557fe5b60209081029190910101525050600101613260565b60606000600290506060818451026001600160401b0381118015613b3d57600080fd5b50604051908082528060200260200182016040528015613b67578160200160208202803683370190505b50905060005b8451811015611a0b576000858281518110613b8457fe5b60200260200101519050806001600160a01b031663402914f5886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613bdb57600080fd5b505afa158015613bef573d6000803e3d6000fd5b505050506040513d6020811015613c0557600080fd5b505183518490848702908110613c1757fe5b602002602001018181525050806001600160a01b0316632459f51d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c5c57600080fd5b505afa158015613c70573d6000803e3d6000fd5b505050506040513d6020811015613c8657600080fd5b505183518490600185880201908110613c9b57fe5b602090810291909101015250600101613b6d565b68327cb2734119d3b7a9601e1b81565b60606000600290506060818451026001600160401b0381118015613ce257600080fd5b50604051908082528060200260200182016040528015613d0c578160200160208202803683370190505b5090508560005b855181101561417f576000868281518110613d2a57fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415613d525750865b6000836001600160a01b03166342b60b03836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613da157600080fd5b505afa158015613db5573d6000803e3d6000fd5b505050506040513d6020811015613dcb57600080fd5b5051613e3b57836001600160a01b031663c4f718bf6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e0a57600080fd5b505afa158015613e1e573d6000803e3d6000fd5b505050506040513d6020811015613e3457600080fd5b5051613ea1565b836001600160a01b031663134ca63b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e7457600080fd5b505afa158015613e88573d6000803e3d6000fd5b505050506040513d6020811015613e9e57600080fd5b50515b90506000846001600160a01b031663c3c7b9e9846040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613ef257600080fd5b505afa158015613f06573d6000803e3d6000fd5b505050506040513d6020811015613f1c57600080fd5b5051604080516352f55eed60e01b81526001600160a01b0386811660048301529151929350600092918816916352f55eed91602480820192602092909190829003018186803b158015613f6e57600080fd5b505afa158015613f82573d6000803e3d6000fd5b505050506040513d6020811015613f9857600080fd5b505190508015613fcb57613fb081611f6785856157bc565b8789870281518110613fbe57fe5b6020026020010181815250505b6000866001600160a01b031663c65bc7b1866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561401a57600080fd5b505afa15801561402e573d6000803e3d6000fd5b505050506040513d602081101561404457600080fd5b5051111561416f576000866001600160a01b031663a93acac2866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561409b57600080fd5b505afa1580156140af573d6000803e3d6000fd5b505050506040513d60208110156140c557600080fd5b50516040805163c65bc7b160e01b81526001600160a01b0388811660048301529151929350600092918a169163c65bc7b191602480820192602092909190829003018186803b15801561411757600080fd5b505afa15801561412b573d6000803e3d6000fd5b505050506040513d602081101561414157600080fd5b5051905061414f8183615854565b898b89026001018151811061416057fe5b60200260200101818152505050505b505060019092019150613d139050565b5090925050505b9392505050565b6000546001600160a01b031633146141e4576040805162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b604482015290519081900360640190fd5b60008054911515600160a01b0260ff60a01b19909216919091179055565b80516060906002908190839082900482026001600160401b038111801561422857600080fd5b50604051908082528060200260200182016040528015614252578160200160208202803683370190505b50905060005b8386518161426257fe5b04811015614464576000868583028151811061427a57fe5b602002602001015190506000878684026001018151811061429757fe5b602002602001015190506000896001600160a01b031663e6a4390584846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561430157600080fd5b505afa158015614315573d6000803e3d6000fd5b505050506040513d602081101561432b57600080fd5b5051604080516370a0823160e01b81526001600160a01b0380841660048301529151929350908516916370a0823191602480820192602092909190829003018186803b15801561437a57600080fd5b505afa15801561438e573d6000803e3d6000fd5b505050506040513d60208110156143a457600080fd5b5051855186908689029081106143b657fe5b602002602001018181525050816001600160a01b03166370a08231826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561440f57600080fd5b505afa158015614423573d6000803e3d6000fd5b505050506040513d602081101561443957600080fd5b5051855186906001878a020190811061444e57fe5b6020908102919091010152505050600101614258565b5095945050505050565b600981565b600054600160a01b900460ff1681565b6000546001600160a01b031633146144da576040805162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000866001600160a01b03166381a612d6876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561454e57600080fd5b505afa158015614562573d6000803e3d6000fd5b505050506040513d602081101561457857600080fd5b5051604080516323b95ceb60e21b81526001600160a01b0389811660048301529151929350600092918a1691638ee573ac91602480820192602092909190829003018186803b1580156145ca57600080fd5b505afa1580156145de573d6000803e3d6000fd5b505050506040513d60208110156145f457600080fd5b5051604080516323b95ceb60e21b81526001600160a01b0389811660048301529151929350600092918b1691638ee573ac91602480820192602092909190829003018186803b15801561464657600080fd5b505afa15801561465a573d6000803e3d6000fd5b505050506040513d602081101561467057600080fd5b5051905060008061469168327cb2734119d3b7a9601e1b611f678a886157bc565b90506146ad600a85900a611f6783670de0b6b3a76400006157bc565b905060008b6001600160a01b03166342b60b038c6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156146fe57600080fd5b505afa158015614712573d6000803e3d6000fd5b505050506040513d602081101561472857600080fd5b505180156147ab57508b6001600160a01b03166342b60b038b6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561477e57600080fd5b505afa158015614792573d6000803e3d6000fd5b505050506040513d60208110156147a857600080fd5b50515b905060008161481e578c6001600160a01b031663a22f23926040518163ffffffff1660e01b815260040160206040518083038186803b1580156147ed57600080fd5b505afa158015614801573d6000803e3d6000fd5b505050506040513d602081101561481757600080fd5b5051614884565b8c6001600160a01b031663df73a2676040518163ffffffff1660e01b815260040160206040518083038186803b15801561485757600080fd5b505afa15801561486b573d6000803e3d6000fd5b505050506040513d602081101561488157600080fd5b50515b90506000826148f7578d6001600160a01b0316637a210a2b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156148c657600080fd5b505afa1580156148da573d6000803e3d6000fd5b505050506040513d60208110156148f057600080fd5b505161495d565b8d6001600160a01b03166310eb56c26040518163ffffffff1660e01b815260040160206040518083038186803b15801561493057600080fd5b505afa158015614944573d6000803e3d6000fd5b505050506040513d602081101561495a57600080fd5b50515b905060008e6001600160a01b031663c7e074c38f87868660016040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b1580156149d157600080fd5b505afa1580156149e5573d6000803e3d6000fd5b505050506040513d60208110156149fb57600080fd5b8101908080519060200190929190505050905060008f6001600160a01b031663c7e074c38f88878760006040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b158015614a8057600080fd5b505afa158015614a94573d6000803e3d6000fd5b505050506040513d6020811015614aaa57600080fd5b50519050808211614abb5780614abd565b815b965050505050505060008a6001600160a01b031663e124e6d28a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015614b1457600080fd5b505afa158015614b28573d6000803e3d6000fd5b505050506040513d6020811015614b3e57600080fd5b505190506000614b5282611f678b896157bc565b9050614b7185600a0a611f6786600a0a846157bc90919063ffffffff16565b90506000614b8f612710611f67614b88828861577a565b85906157bc565b90506000614b9d838361577a565b919e919d50909b505050505050505050505050565b60608082516001600160401b0381118015614bcc57600080fd5b50604051908082528060200260200182016040528015614bf6578160200160208202803683370190505b50905060005b8351811015611805576000848281518110614c1357fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415614c6157856001600160a01b031631838381518110614c4f57fe5b60200260200101818152505050614cf6565b806001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015614cae57600080fd5b505afa158015614cc2573d6000803e3d6000fd5b505050506040513d6020811015614cd857600080fd5b50518351849084908110614ce857fe5b602002602001018181525050505b600101614bfc565b60608060098551026001600160401b0381118015614d1b57600080fd5b50604051908082528060200260200182016040528015614d45578160200160208202803683370190505b50905060005b85518110156150ef5760008060008060008060008e6001600160a01b0316634a3f088d8f8f8b81518110614d7b57fe5b60200260200101518f8c81518110614d8f57fe5b60200260200101518f8d81518110614da357fe5b60200260200101516040518563ffffffff1660e01b815260040180856001600160a01b03168152602001846001600160a01b03168152602001836001600160a01b0316815260200182151581526020019450505050506101006040518083038186803b158015614e1257600080fd5b505afa158015614e26573d6000803e3d6000fd5b505050506040513d610100811015614e3d57600080fd5b50805160208201516040830151606084015160a085015160c086015160e0909601518f51959d50939b509199509750955091935090915087908a9060098b02908110614e8557fe5b602002602001018181525050858960098a0260010181518110614ea457fe5b602002602001018181525050848960098a0260020181518110614ec357fe5b602002602001018181525050838960098a0260030181518110614ee257fe5b60200260200101818152505081614efa576000614efd565b60015b60ff168960098a0260040181518110614f1257fe5b602002602001018181525050828960098a0260050181518110614f3157fe5b602002602001018181525050808960098a0260060181518110614f5057fe5b602002602001018181525050505050505050506000826009830281518110614f7457fe5b602002602001015190506000836009840260020181518110614f9257fe5b602002602001015190506000846009850260060181518110614fb057fe5b6020026020010151905060008211156150e4576000808c6001600160a01b0316635c07eaab8b8881518110614fe157fe5b602002602001015187878d8b81518110614ff757fe5b6020026020010151886040518663ffffffff1660e01b815260040180866001600160a01b03168152602001858152602001848152602001831515815260200182815260200195505050505050604080518083038186803b15801561505a57600080fd5b505afa15801561506e573d6000803e3d6000fd5b505050506040513d604081101561508457600080fd5b50805160209091015190925090508161509e5760006150a1565b60015b60ff168760098802600701815181106150b657fe5b602002602001018181525050808760098802600801815181106150d557fe5b60200260200101818152505050505b505050600101614d4b565b509695505050505050565b600080846001600160a01b03166381a612d6856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561514a57600080fd5b505afa15801561515e573d6000803e3d6000fd5b505050506040513d602081101561517457600080fd5b505160408051637092736960e11b81526001600160a01b03868116600483015291519293506000929188169163e124e6d291602480820192602092909190829003018186803b1580156151c657600080fd5b505afa1580156151da573d6000803e3d6000fd5b505050506040513d60208110156151f057600080fd5b5051604080516323b95ceb60e21b81526001600160a01b038881166004830152915192935060009291891691638ee573ac91602480820192602092909190829003018186803b15801561524257600080fd5b505afa158015615256573d6000803e3d6000fd5b505050506040513d602081101561526c57600080fd5b5051604080516323b95ceb60e21b81526001600160a01b0388811660048301529151929350600092918a1691638ee573ac91602480820192602092909190829003018186803b1580156152be57600080fd5b505afa1580156152d2573d6000803e3d6000fd5b505050506040513d60208110156152e857600080fd5b5051604080516352f55eed60e01b81526001600160a01b038981166004830152915192935060009283928c16916352f55eed916024808301926020929190829003018186803b15801561533a57600080fd5b505afa15801561534e573d6000803e3d6000fd5b505050506040513d602081101561536457600080fd5b50516040805163c3c7b9e960e01b81526001600160a01b038b811660048301529151929350600092918d169163c3c7b9e991602480820192602092909190829003018186803b1580156153b657600080fd5b505afa1580156153ca573d6000803e3d6000fd5b505050506040513d60208110156153e057600080fd5b505160408051634a993ee960e01b81526001600160a01b038c811660048301529151929350600092918e1691634a993ee991602480820192602092909190829003018186803b15801561543257600080fd5b505afa158015615446573d6000803e3d6000fd5b505050506040513d602081101561545c57600080fd5b50519050600081831161546f5781615471565b825b905083811061548c5760009950505050505050505050614186565b6000615498858361577a565b90506154c587600a0a611f678a600a0a6154bf8e611f678f886157bc90919063ffffffff16565b906157bc565b955050505050506000896001600160a01b031663ad1e4f8d8a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561551b57600080fd5b505afa15801561552f573d6000803e3d6000fd5b505050506040513d602081101561554557600080fd5b5051905080156115de57896001600160a01b0316631aa4ace58a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561559c57600080fd5b505afa1580156155b0573d6000803e3d6000fd5b505050506040513d60208110156155c657600080fd5b50518110156155de5760009650505050505050614186565b60006156638b6001600160a01b0316631aa4ace58c6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561563057600080fd5b505afa158015615644573d6000803e3d6000fd5b505050506040513d602081101561565a57600080fd5b5051839061577a565b905061567f670de0b6b3a7640000611f6783600a89900a6157bc565b905061569b87611f678368327cb2734119d3b7a9601e1b6157bc565b9050808311156156b357965061418695505050505050565b505098975050505050505050565b600080805b83518110156118055760008482815181106156dd57fe5b602002602001015190506000866001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561573657600080fd5b505afa15801561574a573d6000803e3d6000fd5b505050506040513d602081101561576057600080fd5b5051905061576e8482615854565b935050506001016156c6565b600061418683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506158ac565b6000826157cb57506000611809565b828202828482816157d857fe5b04146141865760405162461bcd60e51b81526004018080602001828103825260218152602001806159a96021913960400191505060405180910390fd5b600061418683836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250615943565b600082820183811015614186576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b6000818484111561593b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156159005781810151838201526020016158e8565b50505050905090810190601f16801561592d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836159925760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156159005781810151838201526020016158e8565b50600083858161599e57fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122064e40d714a9e51161afd4054a6edc0ef45f77bda91e3a3e155e706b57f4969e664736f6c634300060c0033
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061013e5760003560e01c8063126082cf1461014357806312d43a511461015d57806320542568146101815780632413c8c1146102925780632ac0184c146103335780632e3e3342146103e45780633613d52714610495578063440f018c1461054657806348211934146105a05780637b906e931461065157806386d4d0f514610712578063870d917c146107c35780638e83ca32146107cb578063937a0be81461088c57806395082d251461093d57806395a7535a146109455780639b0183c3146109ff578063a4543ead14610a20578063ad7e549714610ad1578063c6f1d67614610ad9578063cfad57a214610af5578063d7176ca914610b1b578063d802178e14610b70578063dc383cab14610c21578063f3535e6c14610ddf578063fbdb05ca14610e17575b600080fd5b61014b610ec8565b60408051918252519081900360200190f35b610165610ece565b604080516001600160a01b039092168252519081900360200190f35b6102426004803603608081101561019757600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156101d157600080fd5b8201836020820111156101e357600080fd5b803590602001918460208302840111600160201b8311171561020457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610edd945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561027e578181015183820152602001610266565b505050509050019250505060405180910390f35b610242600480360360208110156102a857600080fd5b810190602081018135600160201b8111156102c257600080fd5b8201836020820111156102d457600080fd5b803590602001918460208302840111600160201b831117156102f557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506115eb945050505050565b61014b6004803603604081101561034957600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561037357600080fd5b82018360208201111561038557600080fd5b803590602001918460208302840111600160201b831117156103a657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506116e4945050505050565b610242600480360360408110156103fa57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561042457600080fd5b82018360208201111561043657600080fd5b803590602001918460208302840111600160201b8311171561045757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061180f945050505050565b610242600480360360408110156104ab57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104d557600080fd5b8201836020820111156104e757600080fd5b803590602001918460208302840111600160201b8311171561050857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a14945050505050565b6105826004803603608081101561055c57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611e4e565b60408051938452602084019290925282820152519081900360600190f35b610242600480360360408110156105b657600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156105e057600080fd5b8201836020820111156105f257600080fd5b803590602001918460208302840111600160201b8311171561061357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506123b3945050505050565b6102426004803603608081101561066757600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156106a157600080fd5b8201836020820111156106b357600080fd5b803590602001918460208302840111600160201b831117156106d457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612867945050505050565b6102426004803603604081101561072857600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561075257600080fd5b82018360208201111561076457600080fd5b803590602001918460208302840111600160201b8311171561078557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613098945050505050565b61014b613198565b610242600480360360808110156107e157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561081b57600080fd5b82018360208201111561082d57600080fd5b803590602001918460208302840111600160201b8311171561084e57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061319d945050505050565b610242600480360360408110156108a257600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156108cc57600080fd5b8201836020820111156108de57600080fd5b803590602001918460208302840111600160201b831117156108ff57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613b1a945050505050565b61014b613caf565b6102426004803603606081101561095b57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561098e57600080fd5b8201836020820111156109a057600080fd5b803590602001918460208302840111600160201b831117156109c157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613cbf945050505050565b610a1e60048036036020811015610a1557600080fd5b5035151561418d565b005b61024260048036036040811015610a3657600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610a6057600080fd5b820183602082011115610a7257600080fd5b803590602001918460208302840111600160201b83111715610a9357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614202945050505050565b61014b61446e565b610ae1614473565b604080519115158252519081900360200190f35b610a1e60048036036020811015610b0b57600080fd5b50356001600160a01b0316614483565b610b5760048036036080811015610b3157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356144fc565b6040805192835260208301919091528051918290030190f35b61024260048036036040811015610b8657600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610bb057600080fd5b820183602082011115610bc257600080fd5b803590602001918460208302840111600160201b83111715610be357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614bb2945050505050565b610242600480360360a0811015610c3757600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610c6a57600080fd5b820183602082011115610c7c57600080fd5b803590602001918460208302840111600160201b83111715610c9d57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610cec57600080fd5b820183602082011115610cfe57600080fd5b803590602001918460208302840111600160201b83111715610d1f57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610d6e57600080fd5b820183602082011115610d8057600080fd5b803590602001918460208302840111600160201b83111715610da157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550614cfe945050505050565b61014b60048036036060811015610df557600080fd5b506001600160a01b0381358116916020810135821691604090910135166150fa565b61014b60048036036040811015610e2d57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610e5757600080fd5b820183602082011115610e6957600080fd5b803590602001918460208302840111600160201b83111715610e8a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506156c1945050505050565b61271081565b6000546001600160a01b031681565b60606000600a905060008690506000816001600160a01b031663741bef1a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f2557600080fd5b505afa158015610f39573d6000803e3d6000fd5b505050506040513d6020811015610f4f57600080fd5b5051855190915060609084026001600160401b0381118015610f7057600080fd5b50604051908082528060200260200182016040528015610f9a578160200160208202803683370190505b50905060005b86518110156115de576000878281518110610fb757fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415610fdf5750885b846001600160a01b03166352f55eed826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561102c57600080fd5b505afa158015611040573d6000803e3d6000fd5b505050506040513d602081101561105657600080fd5b50518351849084890290811061106857fe5b602002602001018181525050846001600160a01b031663c3c7b9e9826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156110c157600080fd5b505afa1580156110d5573d6000803e3d6000fd5b505050506040513d60208110156110eb57600080fd5b5051835184906001858a020190811061110057fe5b602002602001018181525050846001600160a01b0316631aa4ace5826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561115957600080fd5b505afa15801561116d573d6000803e3d6000fd5b505050506040513d602081101561118357600080fd5b5051835184906002858a020190811061119857fe5b602002602001018181525050846001600160a01b0316632c668ec1828b6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b1580156111f957600080fd5b505afa15801561120d573d6000803e3d6000fd5b505050506040513d602081101561122357600080fd5b5051835184906003858a020190811061123857fe5b602002602001018181525050846001600160a01b031663ab2f3ad4826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561129157600080fd5b505afa1580156112a5573d6000803e3d6000fd5b505050506040513d60208110156112bb57600080fd5b5051835184906004858a02019081106112d057fe5b602002602001018181525050846001600160a01b03166381a612d6826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561132957600080fd5b505afa15801561133d573d6000803e3d6000fd5b505050506040513d602081101561135357600080fd5b5051835184906005858a020190811061136857fe5b602002602001018181525050846001600160a01b031663e124e6d2826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156113c157600080fd5b505afa1580156113d5573d6000803e3d6000fd5b505050506040513d60208110156113eb57600080fd5b5051835184906006858a020190811061140057fe5b602002602001018181525050846001600160a01b031663f07456ce826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561145957600080fd5b505afa15801561146d573d6000803e3d6000fd5b505050506040513d602081101561148357600080fd5b5051835184906007858a020190811061149857fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600060248301529151918716926356c8c2c192604480840193829003018186803b1580156114f257600080fd5b505afa158015611506573d6000803e3d6000fd5b505050506040513d602081101561151c57600080fd5b5051835184906008858a020190811061153157fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600160248301529151918716926356c8c2c192604480840193829003018186803b15801561158b57600080fd5b505afa15801561159f573d6000803e3d6000fd5b505050506040513d60208110156115b557600080fd5b5051835184906009858a02019081106115ca57fe5b602090810291909101015250600101610fa0565b5098975050505050505050565b60608082516001600160401b038111801561160557600080fd5b5060405190808252806020026020018201604052801561162f578160200160208202803683370190505b50905060005b83518110156116dd57600084828151811061164c57fe5b60200260200101519050806001600160a01b031663817b1cd26040518163ffffffff1660e01b815260040160206040518083038186803b15801561168f57600080fd5b505afa1580156116a3573d6000803e3d6000fd5b505050506040513d60208110156116b957600080fd5b505183518490849081106116c957fe5b602090810291909101015250600101611635565b5092915050565b600080836001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561172057600080fd5b505afa158015611734573d6000803e3d6000fd5b505050506040513d602081101561174a57600080fd5b5051905060005b835181101561180557600084828151811061176857fe5b602002602001015190506000866001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156117c157600080fd5b505afa1580156117d5573d6000803e3d6000fd5b505050506040513d60208110156117eb57600080fd5b505190506117f9848261577a565b93505050600101611751565b5090505b92915050565b60606000600290506060818451026001600160401b038111801561183257600080fd5b5060405190808252806020026020018201604052801561185c578160200160208202803683370190505b50905060005b8451811015611a0b57600085828151811061187957fe5b6020026020010151905060006001600160a01b0316816001600160a01b031614156118e857866001600160a01b03163183858402815181106118b757fe5b602002602001018181525050600083858402600101815181106118d657fe5b60200260200101818152505050611a03565b806001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561193557600080fd5b505afa158015611949573d6000803e3d6000fd5b505050506040513d602081101561195f57600080fd5b50518351849084870290811061197157fe5b602002602001018181525050806001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119b657600080fd5b505afa1580156119ca573d6000803e3d6000fd5b505050506040513d60208110156119e057600080fd5b5051835184906001858802019081106119f557fe5b602002602001018181525050505b600101611862565b50949350505050565b60606000600690506060818451026001600160401b0381118015611a3757600080fd5b50604051908082528060200260200182016040528015611a61578160200160208202803683370190505b50905060005b8451811015611a0b576000858281518110611a7e57fe5b602090810291909101810151604080516317e1d38560e11b81526001600160a01b0380841660048301526001602483018190526044830152600060648301529151929450908a1692632fc3a70a92608480840193829003018186803b158015611ae657600080fd5b505afa158015611afa573d6000803e3d6000fd5b505050506040513d6020811015611b1057600080fd5b505183518490848702908110611b2257fe5b602090810291909101810191909152604080516317e1d38560e11b81526001600160a01b0384811660048301526000602483018190526001604484015260648301529151918a1692632fc3a70a92608480840193829003018186803b158015611b8a57600080fd5b505afa158015611b9e573d6000803e3d6000fd5b505050506040513d6020811015611bb457600080fd5b505183518490600185880201908110611bc957fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600160248301529151918a16926356c8c2c192604480840193829003018186803b158015611c2357600080fd5b505afa158015611c37573d6000803e3d6000fd5b505050506040513d6020811015611c4d57600080fd5b505183518490600285880201908110611c6257fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600060248301529151918a16926356c8c2c192604480840193829003018186803b158015611cbc57600080fd5b505afa158015611cd0573d6000803e3d6000fd5b505050506040513d6020811015611ce657600080fd5b505183518490600385880201908110611cfb57fe5b602002602001018181525050866001600160a01b0316636ce8a44b826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611d5457600080fd5b505afa158015611d68573d6000803e3d6000fd5b505050506040513d6020811015611d7e57600080fd5b5051611d8b576000611d8e565b60015b60ff168385840260040181518110611da257fe5b602002602001018181525050866001600160a01b03166348cac277826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611dfb57600080fd5b505afa158015611e0f573d6000803e3d6000fd5b505050506040513d6020811015611e2557600080fd5b505183518490600585880201908110611e3a57fe5b602090810291909101015250600101611a67565b600080600080876001600160a01b03166381a612d6886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611ea157600080fd5b505afa158015611eb5573d6000803e3d6000fd5b505050506040513d6020811015611ecb57600080fd5b5051604080516323b95ceb60e21b81526001600160a01b038a811660048301529151929350600092918b1691638ee573ac91602480820192602092909190829003018186803b158015611f1d57600080fd5b505afa158015611f31573d6000803e3d6000fd5b505050506040513d6020811015611f4757600080fd5b505190506000611f6d68327cb2734119d3b7a9601e1b611f6789866157bc565b90615815565b9050611f89600a83900a611f6783670de0b6b3a76400006157bc565b905060008a6001600160a01b03166342b60b038b6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fda57600080fd5b505afa158015611fee573d6000803e3d6000fd5b505050506040513d602081101561200457600080fd5b5051801561208757508a6001600160a01b03166342b60b038a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561205a57600080fd5b505afa15801561206e573d6000803e3d6000fd5b505050506040513d602081101561208457600080fd5b50515b90506000816120fa578b6001600160a01b031663a22f23926040518163ffffffff1660e01b815260040160206040518083038186803b1580156120c957600080fd5b505afa1580156120dd573d6000803e3d6000fd5b505050506040513d60208110156120f357600080fd5b5051612160565b8b6001600160a01b031663df73a2676040518163ffffffff1660e01b815260040160206040518083038186803b15801561213357600080fd5b505afa158015612147573d6000803e3d6000fd5b505050506040513d602081101561215d57600080fd5b50515b90506000826121d3578c6001600160a01b0316637a210a2b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121a257600080fd5b505afa1580156121b6573d6000803e3d6000fd5b505050506040513d60208110156121cc57600080fd5b5051612239565b8c6001600160a01b03166310eb56c26040518163ffffffff1660e01b815260040160206040518083038186803b15801561220c57600080fd5b505afa158015612220573d6000803e3d6000fd5b505050506040513d602081101561223657600080fd5b50515b905060008d6001600160a01b031663c7e074c38e87868660016040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b1580156122ad57600080fd5b505afa1580156122c1573d6000803e3d6000fd5b505050506040513d60208110156122d757600080fd5b8101908080519060200190929190505050905060008e6001600160a01b031663c7e074c38e88878760006040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b15801561235c57600080fd5b505afa158015612370573d6000803e3d6000fd5b505050506040513d602081101561238657600080fd5b505190506000818311612399578161239b565b825b9b509199509750505050505050509450945094915050565b60606000600790506060818451026001600160401b03811180156123d657600080fd5b50604051908082528060200260200182016040528015612400578160200160208202803683370190505b50905060005b8451811015611a0b57600085828151811061241d57fe5b60200260200101519050806001600160a01b0316635d50e729886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561247457600080fd5b505afa158015612488573d6000803e3d6000fd5b505050506040513d602081101561249e57600080fd5b5051835184908487029081106124b057fe5b602002602001018181525050806001600160a01b031663d5a73fdd886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561250957600080fd5b505afa15801561251d573d6000803e3d6000fd5b505050506040513d602081101561253357600080fd5b50518351849060018588020190811061254857fe5b60200260200101818152505085828151811061256057fe5b60200260200101516001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156125b457600080fd5b505afa1580156125c8573d6000803e3d6000fd5b505050506040513d60208110156125de57600080fd5b5051835184906002858802019081106125f357fe5b602002602001018181525050806001600160a01b03166371417b32886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561264c57600080fd5b505afa158015612660573d6000803e3d6000fd5b505050506040513d602081101561267657600080fd5b50518351849060038588020190811061268b57fe5b602002602001018181525050806001600160a01b031663402914f5886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156126e457600080fd5b505afa1580156126f8573d6000803e3d6000fd5b505050506040513d602081101561270e57600080fd5b50518351849060048588020190811061272357fe5b602002602001018181525050806001600160a01b03166308f26c76886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561277c57600080fd5b505afa158015612790573d6000803e3d6000fd5b505050506040513d60208110156127a657600080fd5b5051835184906005858802019081106127bb57fe5b602002602001018181525050806001600160a01b03166345f01ee6886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561281457600080fd5b505afa158015612828573d6000803e3d6000fd5b505050506040513d602081101561283e57600080fd5b50518351849060068588020190811061285357fe5b602090810291909101015250600101612406565b60606000600c905060008690506000816001600160a01b031663741bef1a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156128af57600080fd5b505afa1580156128c3573d6000803e3d6000fd5b505050506040513d60208110156128d957600080fd5b5051855190915060609084026001600160401b03811180156128fa57600080fd5b50604051908082528060200260200182016040528015612924578160200160208202803683370190505b50905060005b86518110156115de57600087828151811061294157fe5b6020026020010151905060006001600160a01b0316816001600160a01b031614156129695750885b846001600160a01b03166352f55eed826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156129b657600080fd5b505afa1580156129ca573d6000803e3d6000fd5b505050506040513d60208110156129e057600080fd5b5051835184908489029081106129f257fe5b602002602001018181525050846001600160a01b031663c3c7b9e9826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612a4b57600080fd5b505afa158015612a5f573d6000803e3d6000fd5b505050506040513d6020811015612a7557600080fd5b5051835184906001858a0201908110612a8a57fe5b602002602001018181525050846001600160a01b0316631aa4ace5826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612ae357600080fd5b505afa158015612af7573d6000803e3d6000fd5b505050506040513d6020811015612b0d57600080fd5b5051835184906002858a0201908110612b2257fe5b602002602001018181525050846001600160a01b0316632c668ec1828b6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b158015612b8357600080fd5b505afa158015612b97573d6000803e3d6000fd5b505050506040513d6020811015612bad57600080fd5b5051835184906003858a0201908110612bc257fe5b602002602001018181525050846001600160a01b031663ab2f3ad4826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612c1b57600080fd5b505afa158015612c2f573d6000803e3d6000fd5b505050506040513d6020811015612c4557600080fd5b5051835184906004858a0201908110612c5a57fe5b602002602001018181525050846001600160a01b0316634a993ee9826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612cb357600080fd5b505afa158015612cc7573d6000803e3d6000fd5b505050506040513d6020811015612cdd57600080fd5b5051835184906005858a0201908110612cf257fe5b602002602001018181525050846001600160a01b031663ad1e4f8d826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612d4b57600080fd5b505afa158015612d5f573d6000803e3d6000fd5b505050506040513d6020811015612d7557600080fd5b5051835184906006858a0201908110612d8a57fe5b602002602001018181525050846001600160a01b03166381a612d6826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612de357600080fd5b505afa158015612df7573d6000803e3d6000fd5b505050506040513d6020811015612e0d57600080fd5b5051835184906007858a0201908110612e2257fe5b602002602001018181525050846001600160a01b031663e124e6d2826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612e7b57600080fd5b505afa158015612e8f573d6000803e3d6000fd5b505050506040513d6020811015612ea557600080fd5b5051835184906008858a0201908110612eba57fe5b602002602001018181525050846001600160a01b031663f07456ce826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612f1357600080fd5b505afa158015612f27573d6000803e3d6000fd5b505050506040513d6020811015612f3d57600080fd5b5051835184906009858a0201908110612f5257fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600060248301529151918716926356c8c2c192604480840193829003018186803b158015612fac57600080fd5b505afa158015612fc0573d6000803e3d6000fd5b505050506040513d6020811015612fd657600080fd5b505183518490600a858a0201908110612feb57fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038481166004830152600160248301529151918716926356c8c2c192604480840193829003018186803b15801561304557600080fd5b505afa158015613059573d6000803e3d6000fd5b505050506040513d602081101561306f57600080fd5b505183518490600b858a020190811061308457fe5b60209081029190910101525060010161292a565b60608082516001600160401b03811180156130b257600080fd5b506040519080825280602002602001820160405280156130dc578160200160208202803683370190505b50905060005b835181101561180557846001600160a01b0316631ce9cb8f85838151811061310657fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561314b57600080fd5b505afa15801561315f573d6000803e3d6000fd5b505050506040513d602081101561317557600080fd5b5051825183908390811061318557fe5b60209081029190910101526001016130e2565b601281565b60606000600e905060008690506000816001600160a01b031663741bef1a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156131e557600080fd5b505afa1580156131f9573d6000803e3d6000fd5b505050506040513d602081101561320f57600080fd5b5051855190915060609084026001600160401b038111801561323057600080fd5b5060405190808252806020026020018201604052801561325a578160200160208202803683370190505b50905060005b86518110156115de57600087828151811061327757fe5b6020026020010151905060006001600160a01b0316816001600160a01b0316141561329f5750885b60008054600160a01b900460ff166132b8576000613332565b856001600160a01b0316639698d25a836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561330557600080fd5b505afa158015613319573d6000803e3d6000fd5b505050506040513d602081101561332f57600080fd5b50515b9050856001600160a01b03166352f55eed836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561338157600080fd5b505afa158015613395573d6000803e3d6000fd5b505050506040513d60208110156133ab57600080fd5b505184518590858a029081106133bd57fe5b602002602001018181525050856001600160a01b031663c3c7b9e9836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561341657600080fd5b505afa15801561342a573d6000803e3d6000fd5b505050506040513d602081101561344057600080fd5b5051845185906001868b020190811061345557fe5b602002602001018181525050856001600160a01b0316631aa4ace5836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156134ae57600080fd5b505afa1580156134c2573d6000803e3d6000fd5b505050506040513d60208110156134d857600080fd5b5051845185906002868b02019081106134ed57fe5b602002602001018181525050856001600160a01b0316632c668ec1838c6040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b15801561354e57600080fd5b505afa158015613562573d6000803e3d6000fd5b505050506040513d602081101561357857600080fd5b5051845185906003868b020190811061358d57fe5b602002602001018181525050856001600160a01b031663ab2f3ad4836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156135e657600080fd5b505afa1580156135fa573d6000803e3d6000fd5b505050506040513d602081101561361057600080fd5b5051845185906004868b020190811061362557fe5b602002602001018181525050856001600160a01b0316634a993ee9836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561367e57600080fd5b505afa158015613692573d6000803e3d6000fd5b505050506040513d60208110156136a857600080fd5b5051845185906005868b02019081106136bd57fe5b602002602001018181525050856001600160a01b031663ad1e4f8d836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561371657600080fd5b505afa15801561372a573d6000803e3d6000fd5b505050506040513d602081101561374057600080fd5b5051845185906006868b020190811061375557fe5b602002602001018181525050856001600160a01b0316638a78daa8836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156137ae57600080fd5b505afa1580156137c2573d6000803e3d6000fd5b505050506040513d60208110156137d857600080fd5b5051845185906007868b02019081106137ed57fe5b60200260200101818152505080848885026008018151811061380b57fe5b602002602001018181525050856001600160a01b03166381a612d6836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561386457600080fd5b505afa158015613878573d6000803e3d6000fd5b505050506040513d602081101561388e57600080fd5b5051845185906009868b02019081106138a357fe5b602002602001018181525050856001600160a01b031663e124e6d2836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156138fc57600080fd5b505afa158015613910573d6000803e3d6000fd5b505050506040513d602081101561392657600080fd5b505184518590600a868b020190811061393b57fe5b602002602001018181525050856001600160a01b031663f07456ce836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561399457600080fd5b505afa1580156139a8573d6000803e3d6000fd5b505050506040513d60208110156139be57600080fd5b505184518590600b868b02019081106139d357fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038581166004830152600060248301529151918816926356c8c2c192604480840193829003018186803b158015613a2d57600080fd5b505afa158015613a41573d6000803e3d6000fd5b505050506040513d6020811015613a5757600080fd5b505184518590600c868b0201908110613a6c57fe5b602090810291909101810191909152604080516356c8c2c160e01b81526001600160a01b038581166004830152600160248301529151918816926356c8c2c192604480840193829003018186803b158015613ac657600080fd5b505afa158015613ada573d6000803e3d6000fd5b505050506040513d6020811015613af057600080fd5b505184518590600d868b0201908110613b0557fe5b60209081029190910101525050600101613260565b60606000600290506060818451026001600160401b0381118015613b3d57600080fd5b50604051908082528060200260200182016040528015613b67578160200160208202803683370190505b50905060005b8451811015611a0b576000858281518110613b8457fe5b60200260200101519050806001600160a01b031663402914f5886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613bdb57600080fd5b505afa158015613bef573d6000803e3d6000fd5b505050506040513d6020811015613c0557600080fd5b505183518490848702908110613c1757fe5b602002602001018181525050806001600160a01b0316632459f51d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c5c57600080fd5b505afa158015613c70573d6000803e3d6000fd5b505050506040513d6020811015613c8657600080fd5b505183518490600185880201908110613c9b57fe5b602090810291909101015250600101613b6d565b68327cb2734119d3b7a9601e1b81565b60606000600290506060818451026001600160401b0381118015613ce257600080fd5b50604051908082528060200260200182016040528015613d0c578160200160208202803683370190505b5090508560005b855181101561417f576000868281518110613d2a57fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415613d525750865b6000836001600160a01b03166342b60b03836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613da157600080fd5b505afa158015613db5573d6000803e3d6000fd5b505050506040513d6020811015613dcb57600080fd5b5051613e3b57836001600160a01b031663c4f718bf6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e0a57600080fd5b505afa158015613e1e573d6000803e3d6000fd5b505050506040513d6020811015613e3457600080fd5b5051613ea1565b836001600160a01b031663134ca63b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e7457600080fd5b505afa158015613e88573d6000803e3d6000fd5b505050506040513d6020811015613e9e57600080fd5b50515b90506000846001600160a01b031663c3c7b9e9846040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613ef257600080fd5b505afa158015613f06573d6000803e3d6000fd5b505050506040513d6020811015613f1c57600080fd5b5051604080516352f55eed60e01b81526001600160a01b0386811660048301529151929350600092918816916352f55eed91602480820192602092909190829003018186803b158015613f6e57600080fd5b505afa158015613f82573d6000803e3d6000fd5b505050506040513d6020811015613f9857600080fd5b505190508015613fcb57613fb081611f6785856157bc565b8789870281518110613fbe57fe5b6020026020010181815250505b6000866001600160a01b031663c65bc7b1866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561401a57600080fd5b505afa15801561402e573d6000803e3d6000fd5b505050506040513d602081101561404457600080fd5b5051111561416f576000866001600160a01b031663a93acac2866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561409b57600080fd5b505afa1580156140af573d6000803e3d6000fd5b505050506040513d60208110156140c557600080fd5b50516040805163c65bc7b160e01b81526001600160a01b0388811660048301529151929350600092918a169163c65bc7b191602480820192602092909190829003018186803b15801561411757600080fd5b505afa15801561412b573d6000803e3d6000fd5b505050506040513d602081101561414157600080fd5b5051905061414f8183615854565b898b89026001018151811061416057fe5b60200260200101818152505050505b505060019092019150613d139050565b5090925050505b9392505050565b6000546001600160a01b031633146141e4576040805162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b604482015290519081900360640190fd5b60008054911515600160a01b0260ff60a01b19909216919091179055565b80516060906002908190839082900482026001600160401b038111801561422857600080fd5b50604051908082528060200260200182016040528015614252578160200160208202803683370190505b50905060005b8386518161426257fe5b04811015614464576000868583028151811061427a57fe5b602002602001015190506000878684026001018151811061429757fe5b602002602001015190506000896001600160a01b031663e6a4390584846040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561430157600080fd5b505afa158015614315573d6000803e3d6000fd5b505050506040513d602081101561432b57600080fd5b5051604080516370a0823160e01b81526001600160a01b0380841660048301529151929350908516916370a0823191602480820192602092909190829003018186803b15801561437a57600080fd5b505afa15801561438e573d6000803e3d6000fd5b505050506040513d60208110156143a457600080fd5b5051855186908689029081106143b657fe5b602002602001018181525050816001600160a01b03166370a08231826040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561440f57600080fd5b505afa158015614423573d6000803e3d6000fd5b505050506040513d602081101561443957600080fd5b5051855186906001878a020190811061444e57fe5b6020908102919091010152505050600101614258565b5095945050505050565b600981565b600054600160a01b900460ff1681565b6000546001600160a01b031633146144da576040805162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000866001600160a01b03166381a612d6876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561454e57600080fd5b505afa158015614562573d6000803e3d6000fd5b505050506040513d602081101561457857600080fd5b5051604080516323b95ceb60e21b81526001600160a01b0389811660048301529151929350600092918a1691638ee573ac91602480820192602092909190829003018186803b1580156145ca57600080fd5b505afa1580156145de573d6000803e3d6000fd5b505050506040513d60208110156145f457600080fd5b5051604080516323b95ceb60e21b81526001600160a01b0389811660048301529151929350600092918b1691638ee573ac91602480820192602092909190829003018186803b15801561464657600080fd5b505afa15801561465a573d6000803e3d6000fd5b505050506040513d602081101561467057600080fd5b5051905060008061469168327cb2734119d3b7a9601e1b611f678a886157bc565b90506146ad600a85900a611f6783670de0b6b3a76400006157bc565b905060008b6001600160a01b03166342b60b038c6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156146fe57600080fd5b505afa158015614712573d6000803e3d6000fd5b505050506040513d602081101561472857600080fd5b505180156147ab57508b6001600160a01b03166342b60b038b6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561477e57600080fd5b505afa158015614792573d6000803e3d6000fd5b505050506040513d60208110156147a857600080fd5b50515b905060008161481e578c6001600160a01b031663a22f23926040518163ffffffff1660e01b815260040160206040518083038186803b1580156147ed57600080fd5b505afa158015614801573d6000803e3d6000fd5b505050506040513d602081101561481757600080fd5b5051614884565b8c6001600160a01b031663df73a2676040518163ffffffff1660e01b815260040160206040518083038186803b15801561485757600080fd5b505afa15801561486b573d6000803e3d6000fd5b505050506040513d602081101561488157600080fd5b50515b90506000826148f7578d6001600160a01b0316637a210a2b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156148c657600080fd5b505afa1580156148da573d6000803e3d6000fd5b505050506040513d60208110156148f057600080fd5b505161495d565b8d6001600160a01b03166310eb56c26040518163ffffffff1660e01b815260040160206040518083038186803b15801561493057600080fd5b505afa158015614944573d6000803e3d6000fd5b505050506040513d602081101561495a57600080fd5b50515b905060008e6001600160a01b031663c7e074c38f87868660016040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b1580156149d157600080fd5b505afa1580156149e5573d6000803e3d6000fd5b505050506040513d60208110156149fb57600080fd5b8101908080519060200190929190505050905060008f6001600160a01b031663c7e074c38f88878760006040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182151581526020019550505050505060206040518083038186803b158015614a8057600080fd5b505afa158015614a94573d6000803e3d6000fd5b505050506040513d6020811015614aaa57600080fd5b50519050808211614abb5780614abd565b815b965050505050505060008a6001600160a01b031663e124e6d28a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015614b1457600080fd5b505afa158015614b28573d6000803e3d6000fd5b505050506040513d6020811015614b3e57600080fd5b505190506000614b5282611f678b896157bc565b9050614b7185600a0a611f6786600a0a846157bc90919063ffffffff16565b90506000614b8f612710611f67614b88828861577a565b85906157bc565b90506000614b9d838361577a565b919e919d50909b505050505050505050505050565b60608082516001600160401b0381118015614bcc57600080fd5b50604051908082528060200260200182016040528015614bf6578160200160208202803683370190505b50905060005b8351811015611805576000848281518110614c1357fe5b6020026020010151905060006001600160a01b0316816001600160a01b03161415614c6157856001600160a01b031631838381518110614c4f57fe5b60200260200101818152505050614cf6565b806001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015614cae57600080fd5b505afa158015614cc2573d6000803e3d6000fd5b505050506040513d6020811015614cd857600080fd5b50518351849084908110614ce857fe5b602002602001018181525050505b600101614bfc565b60608060098551026001600160401b0381118015614d1b57600080fd5b50604051908082528060200260200182016040528015614d45578160200160208202803683370190505b50905060005b85518110156150ef5760008060008060008060008e6001600160a01b0316634a3f088d8f8f8b81518110614d7b57fe5b60200260200101518f8c81518110614d8f57fe5b60200260200101518f8d81518110614da357fe5b60200260200101516040518563ffffffff1660e01b815260040180856001600160a01b03168152602001846001600160a01b03168152602001836001600160a01b0316815260200182151581526020019450505050506101006040518083038186803b158015614e1257600080fd5b505afa158015614e26573d6000803e3d6000fd5b505050506040513d610100811015614e3d57600080fd5b50805160208201516040830151606084015160a085015160c086015160e0909601518f51959d50939b509199509750955091935090915087908a9060098b02908110614e8557fe5b602002602001018181525050858960098a0260010181518110614ea457fe5b602002602001018181525050848960098a0260020181518110614ec357fe5b602002602001018181525050838960098a0260030181518110614ee257fe5b60200260200101818152505081614efa576000614efd565b60015b60ff168960098a0260040181518110614f1257fe5b602002602001018181525050828960098a0260050181518110614f3157fe5b602002602001018181525050808960098a0260060181518110614f5057fe5b602002602001018181525050505050505050506000826009830281518110614f7457fe5b602002602001015190506000836009840260020181518110614f9257fe5b602002602001015190506000846009850260060181518110614fb057fe5b6020026020010151905060008211156150e4576000808c6001600160a01b0316635c07eaab8b8881518110614fe157fe5b602002602001015187878d8b81518110614ff757fe5b6020026020010151886040518663ffffffff1660e01b815260040180866001600160a01b03168152602001858152602001848152602001831515815260200182815260200195505050505050604080518083038186803b15801561505a57600080fd5b505afa15801561506e573d6000803e3d6000fd5b505050506040513d604081101561508457600080fd5b50805160209091015190925090508161509e5760006150a1565b60015b60ff168760098802600701815181106150b657fe5b602002602001018181525050808760098802600801815181106150d557fe5b60200260200101818152505050505b505050600101614d4b565b509695505050505050565b600080846001600160a01b03166381a612d6856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561514a57600080fd5b505afa15801561515e573d6000803e3d6000fd5b505050506040513d602081101561517457600080fd5b505160408051637092736960e11b81526001600160a01b03868116600483015291519293506000929188169163e124e6d291602480820192602092909190829003018186803b1580156151c657600080fd5b505afa1580156151da573d6000803e3d6000fd5b505050506040513d60208110156151f057600080fd5b5051604080516323b95ceb60e21b81526001600160a01b038881166004830152915192935060009291891691638ee573ac91602480820192602092909190829003018186803b15801561524257600080fd5b505afa158015615256573d6000803e3d6000fd5b505050506040513d602081101561526c57600080fd5b5051604080516323b95ceb60e21b81526001600160a01b0388811660048301529151929350600092918a1691638ee573ac91602480820192602092909190829003018186803b1580156152be57600080fd5b505afa1580156152d2573d6000803e3d6000fd5b505050506040513d60208110156152e857600080fd5b5051604080516352f55eed60e01b81526001600160a01b038981166004830152915192935060009283928c16916352f55eed916024808301926020929190829003018186803b15801561533a57600080fd5b505afa15801561534e573d6000803e3d6000fd5b505050506040513d602081101561536457600080fd5b50516040805163c3c7b9e960e01b81526001600160a01b038b811660048301529151929350600092918d169163c3c7b9e991602480820192602092909190829003018186803b1580156153b657600080fd5b505afa1580156153ca573d6000803e3d6000fd5b505050506040513d60208110156153e057600080fd5b505160408051634a993ee960e01b81526001600160a01b038c811660048301529151929350600092918e1691634a993ee991602480820192602092909190829003018186803b15801561543257600080fd5b505afa158015615446573d6000803e3d6000fd5b505050506040513d602081101561545c57600080fd5b50519050600081831161546f5781615471565b825b905083811061548c5760009950505050505050505050614186565b6000615498858361577a565b90506154c587600a0a611f678a600a0a6154bf8e611f678f886157bc90919063ffffffff16565b906157bc565b955050505050506000896001600160a01b031663ad1e4f8d8a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561551b57600080fd5b505afa15801561552f573d6000803e3d6000fd5b505050506040513d602081101561554557600080fd5b5051905080156115de57896001600160a01b0316631aa4ace58a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561559c57600080fd5b505afa1580156155b0573d6000803e3d6000fd5b505050506040513d60208110156155c657600080fd5b50518110156155de5760009650505050505050614186565b60006156638b6001600160a01b0316631aa4ace58c6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561563057600080fd5b505afa158015615644573d6000803e3d6000fd5b505050506040513d602081101561565a57600080fd5b5051839061577a565b905061567f670de0b6b3a7640000611f6783600a89900a6157bc565b905061569b87611f678368327cb2734119d3b7a9601e1b6157bc565b9050808311156156b357965061418695505050505050565b505098975050505050505050565b600080805b83518110156118055760008482815181106156dd57fe5b602002602001015190506000866001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561573657600080fd5b505afa15801561574a573d6000803e3d6000fd5b505050506040513d602081101561576057600080fd5b5051905061576e8482615854565b935050506001016156c6565b600061418683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506158ac565b6000826157cb57506000611809565b828202828482816157d857fe5b04146141865760405162461bcd60e51b81526004018080602001828103825260218152602001806159a96021913960400191505060405180910390fd5b600061418683836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250615943565b600082820183811015614186576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b6000818484111561593b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156159005781810151838201526020016158e8565b50505050905090810190601f16801561592d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836159925760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156159005781810151838201526020016158e8565b50600083858161599e57fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122064e40d714a9e51161afd4054a6edc0ef45f77bda91e3a3e155e706b57f4969e664736f6c634300060c0033