Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BalancerMarketMaker
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;
// ====================================================================
// ======================== BalancerMarketMaker.sol ===================
// ====================================================================
/**
* @title Balancer Stable/Stable Pool Market Maker
* @dev Implementation:
* Increases and decreases the liquidity
*/
import { Stabilizer, TransferHelper, ISweep } from "./Stabilizer.sol";
import { IBalancerPool, IBalancerVault, IAsset, JoinKind, ExitKind } from "./IBalancer.sol";
contract BalancerMarketMaker is Stabilizer {
error BadAddress(address asset);
event LiquidityAdded(uint256 usdxAmount, uint256 sweepAmount);
event LiquidityRemoved(uint256 usdxAmount, uint256 sweepAmount);
event SweepPurchased(uint256 sweeAmount);
IBalancerPool public pool;
IBalancerVault public vault;
bytes32 public poolId;
IAsset[] public poolAssets;
uint8 public sweepIndex;
uint8 public usdxIndex;
uint8 public bptIndex;
uint24 private constant PRECISION = 1e6;
constructor(
string memory _name,
address _sweep,
address _usdx,
address _oracleUsdx,
address _poolAddress,
address _borrower
) Stabilizer(_name, _sweep, _usdx, _oracleUsdx, _borrower) {
pool = IBalancerPool(_poolAddress);
vault = IBalancerVault(pool.getVault());
poolId = pool.getPoolId();
(poolAssets, , ) = vault.getPoolTokens(poolId);
sweepIndex = findAssetIndex(address(sweep), poolAssets);
usdxIndex = findAssetIndex(address(usdx), poolAssets);
bptIndex = findAssetIndex(address(pool), poolAssets);
}
/* ========== Views ========== */
/**
* @notice Current Value of investment.
* @return total with 6 decimal to be compatible with dollar coins.
*/
function currentValue() public view override returns (uint256) {
uint256 accruedFeeInUSD = sweep.convertToUSD(accruedFee());
return assetValue() + super.currentValue() - accruedFeeInUSD;
}
/**
* @notice Gets the asset price of AMM
* @return the amm usdx amount
*/
function assetValue() public view returns (uint256) {
uint256 bpt = pool.balanceOf(address(this));
uint256 rate = pool.getRate();
uint256 usdcAmount = (bpt * rate * (10 ** usdx.decimals())) / (10 ** (pool.decimals() * 2));
return _oracleUsdxToUsd(usdcAmount);
}
/* ========== Actions ========== */
function buySweep(uint256 sweepAmount, uint256 slippage) external nonReentrant {
uint256 sweepAvailable = sweep.minters(address(this)).maxAmount - sweepBorrowed;
if (sweepAvailable < sweepAmount*2) revert NotEnoughBalance();
uint256 targetPrice = _oracleUsdToUsdx(sweep.targetPrice());
uint256 buyPrice = targetPrice + ((sweep.arbSpread() * targetPrice) / PRECISION);
uint256 usdxAmount = (sweepAmount * buyPrice) / (10 ** sweep.decimals());
TransferHelper.safeTransferFrom(address(usdx), msg.sender, address(this), usdxAmount);
TransferHelper.safeApprove(address(usdx), address(vault), usdxAmount);
TransferHelper.safeApprove(address(sweep), address(vault), sweepAmount);
_borrow(sweepAmount*2);
_addLiquidity(usdxAmount, sweepAmount, slippage);
TransferHelper.safeTransfer(address(sweep), msg.sender, sweepAmount);
emit SweepPurchased(usdxAmount);
}
function initPool(uint256 usdxAmount, uint256 sweepAmount) external nonReentrant onlyBorrower {
address self = address(this);
if(sweep.isMintingAllowed()){
_borrow(sweepAmount);
} else {
TransferHelper.safeTransferFrom(address(sweep), msg.sender, self, sweepAmount);
}
TransferHelper.safeTransferFrom(address(usdx), msg.sender, self, usdxAmount);
TransferHelper.safeApprove(address(usdx), address(vault), usdxAmount);
TransferHelper.safeApprove(address(sweep), address(vault), sweepAmount);
uint256[] memory amounts = new uint256[](3);
amounts[bptIndex] = 2**112;
amounts[usdxIndex] = usdxAmount;
amounts[sweepIndex] = sweepAmount;
bytes memory userData = abi.encode(JoinKind.INIT, amounts);
IBalancerVault.JoinPoolRequest memory request = IBalancerVault.JoinPoolRequest(poolAssets, amounts, userData, false);
vault.joinPool(poolId, self, self, request);
}
function _addLiquidity(uint256 usdxAmount, uint256 sweepAmount, uint256 slippage) internal {
address self = address(this);
uint256[] memory amounts = new uint256[](3);
amounts[usdxIndex] = usdxAmount;
amounts[sweepIndex] = sweepAmount;
uint256[] memory userDataAmounts = new uint256[](2);
userDataAmounts[0] = (sweepIndex > usdxIndex) ? usdxAmount : sweepAmount;
userDataAmounts[1] = (sweepIndex > usdxIndex) ? sweepAmount : usdxAmount;
uint256 usdxMin = usdxAmount * pool.getTokenRate(address(usdx)) / (10 ** usdx.decimals());
uint256 sweepMin = sweepAmount * pool.getTokenRate(address(sweep)) / (10 ** sweep.decimals());
uint256 minTotalAmountOut = (usdxMin + sweepMin) * (PRECISION - slippage) / PRECISION;
bytes memory userData = abi.encode(JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT, userDataAmounts, minTotalAmountOut);
IBalancerVault.JoinPoolRequest memory request = IBalancerVault.JoinPoolRequest(poolAssets, amounts, userData, false);
vault.joinPool(poolId, self, self, request);
}
function addLiquidity(uint256 usdxAmount, uint256 sweepAmount, uint256 slippage) external nonReentrant onlyBorrower {
address self = address(this);
if(sweep.isMintingAllowed()){
uint256 sweepLimit = sweep.minters(address(this)).maxAmount;
uint256 sweepAvailable = sweepLimit - sweepBorrowed;
if (sweepAvailable < sweepAmount) revert NotEnoughBalance();
if(sweepAmount > 0) _borrow(sweepAmount);
} else {
TransferHelper.safeTransferFrom(address(sweep), msg.sender, self, sweepAmount);
}
TransferHelper.safeTransferFrom(address(usdx), msg.sender, self, usdxAmount);
TransferHelper.safeApprove(address(usdx), address(vault), usdxAmount);
TransferHelper.safeApprove(address(sweep), address(vault), sweepAmount);
_addLiquidity(usdxAmount, sweepAmount, slippage);
emit LiquidityAdded(usdxAmount, sweepAmount);
}
function removeLiquidity(uint256 usdxAmount, uint256 sweepAmount, uint256 slippage) external nonReentrant onlyBorrower {
address self = address(this);
uint256 usdxMax = usdxAmount * pool.getTokenRate(address(usdx)) / (10**usdx.decimals());
uint256 sweepMax = sweepAmount * pool.getTokenRate(address(sweep)) / (10**sweep.decimals());
uint256 maxAmountIn = (usdxMax + sweepMax) * (PRECISION + slippage) / PRECISION;
uint256[] memory amounts = new uint256[](3);
amounts[usdxIndex] = usdxAmount;
amounts[sweepIndex] = sweepAmount;
uint256[] memory userDataAmounts = new uint256[](2);
userDataAmounts[0] = (sweepIndex > usdxIndex) ? usdxAmount : sweepAmount;
userDataAmounts[1] = (sweepIndex > usdxIndex) ? sweepAmount : usdxAmount;
bytes memory userData = abi.encode(ExitKind.BPT_IN_FOR_EXACT_TOKENS_OUT, userDataAmounts, maxAmountIn);
IBalancerVault.ExitPoolRequest memory request = IBalancerVault.ExitPoolRequest(poolAssets, amounts, userData, false);
vault.exitPool(poolId, self, self, request);
if(sweepAmount > 0) _repay(sweepAmount);
emit LiquidityRemoved(usdxAmount, sweepAmount);
}
function findAssetIndex(address asset, IAsset[] memory assets) internal pure returns (uint8) {
for (uint8 i = 0; i < assets.length; i++) {
if ( address(assets[i]) == asset ) {
return i;
}
}
revert BadAddress(asset);
}
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;
interface IPriceFeed {
function latestAnswer() external view returns (int256);
function latestTimestamp() external view returns (uint256);
function latestRound() external view returns (uint256);
function getAnswer(uint256 roundId) external view returns (int256);
function getTimestamp(uint256 roundId) external view returns (uint256);
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(
uint80 _roundId
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
library ChainlinkLibrary {
uint8 constant USD_DECIMALS = 6;
function getDecimals(IPriceFeed oracle) internal view returns (uint8) {
return oracle.decimals();
}
function getPrice(IPriceFeed oracle) internal view returns (uint256) {
(
uint80 roundID,
int256 price,
,
uint256 timeStamp,
uint80 answeredInRound
) = oracle.latestRoundData();
require(answeredInRound >= roundID, "Old data");
require(timeStamp > 0, "Round not complete");
return uint256(price);
}
function getPrice(
IPriceFeed oracle,
IPriceFeed sequencerOracle,
uint256 frequency
) internal view returns (uint256) {
if (address(sequencerOracle) != address(0))
checkUptime(sequencerOracle);
(uint256 roundId, int256 price, , uint256 updatedAt, ) = oracle
.latestRoundData();
require(price > 0 && roundId != 0 && updatedAt != 0, "Invalid Price");
if (frequency > 0)
require(block.timestamp - updatedAt <= frequency, "Stale Price");
return uint256(price);
}
function checkUptime(IPriceFeed sequencerOracle) internal view {
(, int256 answer, uint256 startedAt, , ) = sequencerOracle
.latestRoundData();
require(answer <= 0, "Sequencer Down"); // 0: Sequencer is up, 1: Sequencer is down
require(block.timestamp - startedAt > 1 hours, "Grace Period Not Over");
}
function convertTokenToToken(
uint256 amount0,
uint8 token0Decimals,
uint8 token1Decimals,
IPriceFeed oracle0,
IPriceFeed oracle1
) internal view returns (uint256 amount1) {
uint256 price0 = getPrice(oracle0);
uint256 price1 = getPrice(oracle1);
amount1 =
(amount0 * price0 * (10 ** token1Decimals)) /
(price1 * (10 ** token0Decimals));
}
function convertTokenToUsd(
uint256 amount,
uint8 tokenDecimals,
IPriceFeed oracle
) internal view returns (uint256 amountUsd) {
uint8 decimals = getDecimals(oracle);
uint256 price = getPrice(oracle);
amountUsd =
(amount * price * (10 ** USD_DECIMALS)) /
10 ** (decimals + tokenDecimals);
}
function convertUsdToToken(
uint256 amountUsd,
uint256 tokenDecimals,
IPriceFeed oracle
) internal view returns (uint256 amount) {
uint8 decimals = getDecimals(oracle);
uint256 price = getPrice(oracle);
amount =
(amountUsd * 10 ** (decimals + tokenDecimals)) /
(price * (10 ** USD_DECIMALS));
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;
interface IAMM {
function swapExactInput(
address tokenA,
address tokenB,
uint24 fee,
uint256 amountIn,
uint256 amountOutMin
) external returns (uint256);
function buySweep(
address token,
uint256 amountIn,
uint256 amountOutMin
) external returns (uint256);
function sellSweep(
address token,
uint256 amountIn,
uint256 amountOutMin
) external returns (uint256);
function sequencer() external view returns (address);
function poolFee() external view returns (uint24);
function getTWAPrice() external view returns (uint256 twaPrice);
function getPrice() external view returns (uint256 price);
function getRate() external view returns (uint256 rate);
function getPositions(uint256) external view returns (uint256 usdxAmount, uint256 sweepAmount, uint256 lp);
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;
import "./IERC20Metadata.sol";
interface IBalancerVault {
struct JoinPoolRequest {
IAsset[] assets;
uint256[] maxAmountsIn;
bytes userData;
bool fromInternalBalance;
}
struct ExitPoolRequest {
IAsset[] assets;
uint256[] minAmountsOut;
bytes userData;
bool toInternalBalance;
}
function joinPool(bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request) external payable;
function exitPool(bytes32 poolId, address sender, address recipient, ExitPoolRequest memory request) external payable;
function getPoolTokens(bytes32 poolId) external view returns (IAsset[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock);
function swap(SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline) external returns (uint256 amountOut);
}
interface IAsset {
// solhint-disable-previous-line no-empty-blocks
}
interface IBalancerPool is IERC20Metadata {
function getPoolId() external view returns (bytes32);
function getVault() external view returns (address);
function getRate() external view returns (uint256);
function getTokenRate(address) external view returns (uint256);
}
struct SingleSwap {
bytes32 poolId;
SwapKind kind;
IAsset assetIn;
IAsset assetOut;
uint256 amount;
bytes userData;
}
struct FundManagement {
address sender;
bool fromInternalBalance;
address payable recipient;
bool toInternalBalance;
}
interface IComposableStablePoolFactory {
function create(
string memory name,
string memory symbol,
IERC20[] memory tokens,
uint256 amplificationParameter,
IRateProvider[] memory rateProviders,
uint256[] memory tokenRateCacheDurations,
bool exemptFromYieldProtocolFeeFlag,
uint256 swapFeePercentage,
address owner,
bytes32 salt
) external returns(address poolAddress);
}
interface IRateProvider {
function getRate() external view returns (uint256);
}
enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT }
enum ExitKind { EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT, EXACT_BPT_IN_FOR_ALL_TOKENS_OUT }
enum SwapKind { GIVEN_IN, GIVEN_OUT }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
uint256 amount
) external returns (bool);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;
interface ISweep {
struct Minter {
uint256 maxAmount;
uint256 mintedAmount;
bool isListed;
bool isEnabled;
}
function isMintingAllowed() external view returns (bool);
function DEFAULT_ADMIN_ADDRESS() external view returns (address);
function balancer() external view returns (address);
function treasury() external view returns (address);
function allowance(
address holder,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function decimals() external view returns (uint8);
function decreaseAllowance(
address spender,
uint256 subtractedValue
) external returns (bool);
function isValidMinter(address) external view returns (bool);
function amm() external view returns (address);
function ammPrice() external view returns (uint256);
function twaPrice() external view returns (uint256);
function increaseAllowance(
address spender,
uint256 addedValue
) external returns (bool);
function name() external view returns (string memory);
function owner() external view returns (address);
function fastMultisig() external view returns (address);
function burn(uint256 amount) external;
function mint(uint256 amount) external;
function minters(address minterAaddress) external returns (Minter memory);
function minterAddresses(uint256 index) external view returns (address);
function getMinters() external view returns (address[] memory);
function targetPrice() external view returns (uint256);
function interestRate() external view returns (int256);
function periodStart() external view returns (uint256);
function stepValue() external view returns (int256);
function arbSpread() external view returns (uint256);
function refreshInterestRate(int256 newInterestRate, uint256 newPeriodStart) external;
function setTargetPrice(
uint256 currentTargetPrice,
uint256 nextTargetPrice
) external;
function setInterestRate(
int256 currentInterestRate,
int256 nextInterestRate
) external;
function setPeriodStart(
uint256 currentPeriodStart,
uint256 nextPeriodStart
) external;
function startNewPeriod() external;
function symbol() external view returns (string memory);
function totalSupply() external view returns (uint256);
function convertToUSD(uint256 amount) external view returns (uint256);
function convertToSWEEP(uint256 amount) external view returns (uint256);
function transfer(
address recipient,
uint256 amount
) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;
library OvnMath {
uint256 constant BASIS_DENOMINATOR = 1e6;
function abs(uint256 x, uint256 y) internal pure returns (uint256) {
return (x > y) ? (x - y) : (y - x);
}
function addBasisPoints(
uint256 amount,
uint256 basisPoints
) internal pure returns (uint256) {
return (amount * (BASIS_DENOMINATOR + basisPoints)) / BASIS_DENOMINATOR;
}
function reverseAddBasisPoints(
uint256 amount,
uint256 basisPoints
) internal pure returns (uint256) {
return (amount * BASIS_DENOMINATOR) / (BASIS_DENOMINATOR + basisPoints);
}
function subBasisPoints(
uint256 amount,
uint256 basisPoints
) internal pure returns (uint256) {
return (amount * (BASIS_DENOMINATOR - basisPoints)) / BASIS_DENOMINATOR;
}
function reverseSubBasisPoints(
uint256 amount,
uint256 basisPoints
) internal pure returns (uint256) {
return (amount * BASIS_DENOMINATOR) / (BASIS_DENOMINATOR - basisPoints);
}
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.19;
// ==========================================================
// ======================= Owned.sol ========================
// ==========================================================
import "./ISweep.sol";
contract Owned {
ISweep public immutable sweep;
// Errors
error NotGovernance();
error NotMultisigOrGov();
error ZeroAddressDetected();
constructor(address _sweep) {
if(_sweep == address(0)) revert ZeroAddressDetected();
sweep = ISweep(_sweep);
}
modifier onlyGov() {
if (msg.sender != sweep.owner()) revert NotGovernance();
_;
}
modifier onlyMultisigOrGov() {
if (msg.sender != sweep.fastMultisig() && msg.sender != sweep.owner())
revert NotMultisigOrGov();
_;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "./Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;
// ====================================================================
// ====================== Stabilizer.sol ==============================
// ====================================================================
/**
* @title Stabilizer
* @dev Implementation:
* Allows to take debt by minting sweep and repaying by burning sweep
* Allows to buy and sell sweep in an AMM
* Allows auto invest according the borrower configuration
* Allows auto repays by the balancer to control sweep price
* Allow liquidate the Asset when is defaulted
* Repayments made by burning sweep
* EquityRatio = Junior / (Junior + Senior)
*/
import "./IAMM.sol";
import "./Owned.sol";
import "./Chainlink.sol";
import "./OvnMath.sol";
import "./Pausable.sol";
import "./IERC20Metadata.sol";
import "./Math.sol";
import "./TransferHelper.sol";
import "./ReentrancyGuard.sol";
contract Stabilizer is Owned, Pausable, ReentrancyGuard {
using Math for uint256;
IERC20Metadata public usdx;
IPriceFeed public oracleUsdx;
// Variables
string public name;
address public borrower;
int256 public minEquityRatio; // Minimum Equity Ratio. 10000 is 1%
uint256 public sweepBorrowed;
uint256 public loanLimit;
uint256 public callTime;
uint256 public callDelay; // 86400 is 1 day
uint256 public callAmount;
uint256 public spreadFee; // 10000 is 1%
uint256 public spreadDate;
string public link;
int256 public autoInvestMinRatio; // 10000 is 1%
uint256 public autoInvestMinAmount;
bool public autoInvestEnabled;
bool public settingsEnabled;
uint256 public startingTime;
uint256 public startingPrice;
uint256 public decreaseFactor; // 10000 is 1%
uint256 public minLiquidationRatio; // 100000 is 10%
bool public auctionAllowed;
// Constants for various precisions
uint256 private constant DAY_SECONDS = 60 * 60 * 24; // seconds of Day
uint256 private constant DAYS_ONE_YEAR = 365; // days of Year
uint256 private constant PRECISION = 1e6;
uint256 private constant ORACLE_FREQUENCY = 1 days;
/* ========== Events ========== */
event Borrowed(uint256 indexed sweepAmount);
event Repaid(uint256 indexed sweepAmount);
event Withdrawn(address indexed token, uint256 indexed amount);
event PayFee(uint256 indexed sweepAmount);
event Bought(uint256 indexed sweepAmount);
event Sold(uint256 indexed sweepAmount);
event BoughtSWEEP(uint256 indexed sweepAmount);
event SoldSWEEP(uint256 indexed usdxAmount);
event LoanLimitChanged(uint256 loanLimit);
event Proposed(address indexed borrower);
event Rejected(address indexed borrower);
event SweepBorrowedChanged(uint256 indexed sweepAmount);
event Liquidated(address indexed user);
event AutoCalled(uint256 indexed sweepAmount);
event AutoInvested(uint256 indexed sweepAmount);
event CallCancelled(uint256 indexed sweepAmount);
event ConfigurationChanged(
int256 indexed minEquityRatio,
uint256 indexed spreadFee,
uint256 loanLimit,
uint256 decreaseFactor,
uint256 callDelay,
int256 autoInvestMinRatio,
uint256 autoInvestMinAmount,
uint256 minLiquidationRatio,
bool autoInvestEnabled,
bool _auctionAllowed,
string url
);
/* ========== Errors ========== */
error NotBorrower();
error NotBalancer();
error NotSweep();
error SettingsDisabled();
error OverZero();
error AssetDefaulted();
error AuctionNotActive();
error ActionNotAllowed();
error InvalidMinter();
error NotEnoughBalance();
error EquityRatioExcessed();
error InvalidToken();
error SpreadNotEnough();
error NotDefaulted();
error NotAutoInvest();
error NotAutoInvestMinAmount();
error NotAutoInvestMinRatio();
/* ========== Modifies ========== */
modifier onlyBorrower() {
_onlyBorrower();
_;
}
modifier onlySettingsEnabled() {
_onlySettingsEnabled();
_;
}
modifier validAmount(uint256 amount) {
_validAmount(amount);
_;
}
constructor(
string memory _name,
address _sweep,
address _usdx,
address _oracleUsdx,
address _borrower
) Owned(_sweep) {
if (_borrower == address(0)) revert ZeroAddressDetected();
name = _name;
usdx = IERC20Metadata(_usdx);
oracleUsdx = IPriceFeed(_oracleUsdx);
borrower = _borrower;
settingsEnabled = true;
}
/* ========== Views ========== */
/**
* @notice Defaulted
* @return bool that tells if stabilizer is in default.
*/
function isDefaulted() public view returns (bool) {
return
(callDelay > 0 && callAmount > 0 && block.timestamp > callTime) ||
(sweepBorrowed > 0 && getEquityRatio() < minEquityRatio);
}
/**
* @notice Get Equity Ratio
* @return the current equity ratio based in the internal storage.
* @dev this value have a precision of 6 decimals.
*/
function getEquityRatio() public view returns (int256) {
return _calculateEquityRatio(0, 0);
}
/**
* @notice Get Spread Amount
* fee = borrow_amount * spread_ratio * (time / time_per_year)
* @return uint256 calculated spread amount.
*/
function accruedFee() public view returns (uint256) {
if (sweepBorrowed > 0) {
uint256 period = (block.timestamp - spreadDate) / DAY_SECONDS;
return
(sweepBorrowed * spreadFee * period) /
(DAYS_ONE_YEAR * PRECISION);
}
return 0;
}
/**
* @notice Get Debt Amount
* debt = borrow_amount + spread fee
* @return uint256 calculated debt amount.
*/
function getDebt() public view returns (uint256) {
return sweepBorrowed + accruedFee();
}
/**
* @notice Get Current Value
* value = sweep balance + usdx balance
* @return uint256.
*/
function currentValue() public view virtual returns (uint256) {
(uint256 usdxBalance, uint256 sweepBalance) = _balances();
uint256 sweepInUsd = sweep.convertToUSD(sweepBalance);
uint256 usdxInUsd = _oracleUsdxToUsd(usdxBalance);
return usdxInUsd + sweepInUsd;
}
/**
* @notice Get AMM from Sweep
* @return address.
*/
function amm() public view virtual returns (IAMM) {
return IAMM(sweep.amm());
}
/**
* @notice Get Junior Tranche Value
* @return int256 calculated junior tranche amount.
*/
function getJuniorTrancheValue() external view returns (int256) {
uint256 seniorTrancheInUSD = sweep.convertToUSD(sweepBorrowed);
uint256 totalValue = currentValue();
return int256(totalValue) - int256(seniorTrancheInUSD);
}
/**
* @notice Returns the SWEEP required to liquidate the stabilizer in the auction.
* @return auctionPrice
*/
function getAuctionAmount() public view returns (uint256) {
uint256 minPrice = sweepBorrowed * (PRECISION - minLiquidationRatio) / PRECISION;
uint256 timeElapsed = (block.timestamp - startingTime) / 5 minutes;
uint256 ratio = timeElapsed * decreaseFactor;
if(ratio > PRECISION) return minPrice;
uint256 decreaseRatio = PRECISION - ratio;
uint256 auctionPrice = (startingPrice * decreaseRatio) / PRECISION;
return minPrice > auctionPrice ? minPrice : auctionPrice;
}
/* ========== Settings ========== */
/**
* @notice Pause
* @dev Stops investment actions.
*/
function pause() external onlyMultisigOrGov {
_pause();
}
/**
* @notice Unpause
* @dev Start investment actions.
*/
function unpause() external onlyMultisigOrGov {
_unpause();
}
/**
* @notice Configure intial settings
* @param _minEquityRatio The minimum equity ratio can be negative.
* @param _spreadFee The fee that the protocol will get for providing the loan when the stabilizer takes debt
* @param _loanLimit How much debt a Stabilizer can take in SWEEP.
* @param _decreaseFactor A percentage that will be discounted from the price as time passes from the auction start.
* @param _callDelay Time in seconds after AutoCall until the Stabilizer gets defaulted if the debt is not paid in that period
* @param _autoInvestMinRatio Minimum equity ratio that should be kept to allow the execution of an auto invest
* @param _autoInvestMinAmount Minimum amount to be invested to allow the execution of an auto invest
* @param _autoInvestEnabled Represents if an auto invest execution is allowed or not
* @param _auctionAllowed Represents if an auction is allowed or not
* @param _url A URL link to a Web page that describes the borrower and the asset
* @dev Sets the initial configuration of the Stabilizer.
* This configuration will be analyzed by the protocol and if accepted,
* used to include the Stabilizer in the minter's whitelist of Sweep.
* The minimum equity ratio can not be less than 1%
*/
function configure(
int256 _minEquityRatio,
uint256 _spreadFee,
uint256 _loanLimit,
uint256 _decreaseFactor,
uint256 _callDelay,
int256 _autoInvestMinRatio,
uint256 _autoInvestMinAmount,
uint256 _minLiquidationRatio,
bool _autoInvestEnabled,
bool _auctionAllowed,
string calldata _url
) external onlyBorrower onlySettingsEnabled {
minEquityRatio = _minEquityRatio;
spreadFee = _spreadFee;
loanLimit = _loanLimit;
decreaseFactor = _decreaseFactor;
callDelay = _callDelay;
autoInvestMinRatio = _autoInvestMinRatio;
autoInvestMinAmount = _autoInvestMinAmount;
minLiquidationRatio = _minLiquidationRatio;
autoInvestEnabled = _autoInvestEnabled;
auctionAllowed = _auctionAllowed;
link = _url;
emit ConfigurationChanged(
_minEquityRatio,
_spreadFee,
_loanLimit,
decreaseFactor,
_callDelay,
_autoInvestMinRatio,
_autoInvestMinAmount,
_minLiquidationRatio,
_autoInvestEnabled,
_auctionAllowed,
_url
);
}
/**
* @notice Changes the account that control the global configuration to the protocol/governance admin
* @dev after disable settings by admin
* the protocol will evaluate adding the stabilizer to the minter list.
*/
function propose() external onlyBorrower {
settingsEnabled = false;
emit Proposed(borrower);
}
/**
* @notice Changes the account that control the global configuration to the borrower
* @dev after enable settings for the borrower
* he/she should edit the values to align to the protocol requirements
*/
function reject() external onlyGov {
settingsEnabled = true;
emit Rejected(borrower);
}
/* ========== Actions ========== */
/**
* @notice Borrows Sweep
* Asks the stabilizer to mint a certain amount of sweep token.
* @param sweepAmount.
* @dev Increases the sweepBorrowed (senior tranche).
*/
function borrow(
uint256 sweepAmount
)
external
onlyBorrower
whenNotPaused
validAmount(sweepAmount)
nonReentrant
{
if (!sweep.isValidMinter(address(this))) revert InvalidMinter();
uint256 sweepAvailable = loanLimit - sweepBorrowed;
if (sweepAvailable < sweepAmount) revert NotEnoughBalance();
int256 currentEquityRatio = _calculateEquityRatio(sweepAmount, 0);
if (currentEquityRatio < minEquityRatio) revert EquityRatioExcessed();
_borrow(sweepAmount);
}
/**
* @notice Repays Sweep
* Burns the sweep amount to reduce the debt (senior tranche).
* @param sweepAmount Amount to be burnt by Sweep.
* @dev Decreases the sweep borrowed.
*/
function repay(uint256 sweepAmount) external onlyBorrower nonReentrant {
_repay(sweepAmount);
}
/**
* @notice Pay the spread to the treasury
*/
function payFee() external onlyBorrower nonReentrant {
uint256 spreadAmount = accruedFee();
spreadDate = block.timestamp;
uint256 sweepBalance = sweep.balanceOf(address(this));
if (spreadAmount > sweepBalance) revert SpreadNotEnough();
if (spreadAmount > 0) {
TransferHelper.safeTransfer(
address(sweep),
sweep.treasury(),
spreadAmount
);
emit PayFee(spreadAmount);
}
}
/**
* @notice Set Loan Limit.
* @param newLoanLimit.
* @dev How much debt an Stabilizer can take in SWEEP.
*/
function setLoanLimit(uint256 newLoanLimit) external {
if (msg.sender != sweep.balancer()) revert NotBalancer();
loanLimit = newLoanLimit;
emit LoanLimitChanged(newLoanLimit);
}
/**
* @notice Update Sweep Borrowed Amount.
* @param amount.
*/
function updateSweepBorrowed(uint256 amount) external {
if (msg.sender != address(sweep)) revert NotSweep();
sweepBorrowed = amount;
emit SweepBorrowedChanged(amount);
}
/**
* @notice Auto Call.
* @param sweepAmount to repay.
* @dev Strategy:
* 1) repays debt with SWEEP balance
* 2) repays remaining debt by divesting
* 3) repays remaining debt by buying on SWEEP in the AMM
*/
function autoCall(
uint256 sweepAmount,
uint256 price,
uint256 slippage
) external nonReentrant {
if (msg.sender != sweep.balancer()) revert NotBalancer();
(uint256 usdxBalance, uint256 sweepBalance) = _balances();
uint256 repayAmount = sweepAmount.min(sweepBorrowed);
if (callDelay > 0) {
callTime = block.timestamp + callDelay;
callAmount = repayAmount;
}
if (sweepBalance < repayAmount) {
uint256 missingSweep = repayAmount - sweepBalance;
uint256 sweepInUsd = sweep.convertToUSD(missingSweep);
uint256 missingUsdx = _oracleUsdToUsdx(sweepInUsd);
if (missingUsdx > usdxBalance) {
_divest(missingUsdx - usdxBalance, slippage);
}
if (usdx.balanceOf(address(this)) > 0) {
uint256 missingUsd = _oracleUsdxToUsd(missingUsdx);
uint256 sweepInUsdx = missingUsd.mulDiv(
10 ** sweep.decimals(),
price
);
uint256 minAmountOut = OvnMath.subBasisPoints(
sweepInUsdx,
slippage
);
_buy(missingUsdx, minAmountOut);
}
}
if (sweep.balanceOf(address(this)) > 0 && repayAmount > 0) {
_repay(repayAmount);
}
emit AutoCalled(sweepAmount);
}
/**
* @notice Cancel Call
* @dev Cancels the auto call request by clearing variables for an asset
* that has a callDelay: meaning that it does not autorepay.
*/
function cancelCall() external {
if (msg.sender != sweep.balancer()) revert NotBalancer();
callAmount = 0;
callTime = 0;
emit CallCancelled(callAmount);
}
/**
* @notice Auto Invest.
* @param sweepAmount to mint.
* @param price.
* @param slippage.
*/
function autoInvest(
uint256 sweepAmount,
uint256 price,
uint256 slippage
) external nonReentrant {
if (msg.sender != sweep.balancer()) revert NotBalancer();
uint256 sweepLimit = sweep.minters(address(this)).maxAmount;
uint256 sweepAvailable = sweepLimit - sweepBorrowed;
sweepAmount = sweepAmount.min(sweepAvailable);
int256 currentEquityRatio = _calculateEquityRatio(sweepAmount, 0);
if (!autoInvestEnabled) revert NotAutoInvest();
if (sweepAmount < autoInvestMinAmount) revert NotAutoInvestMinAmount();
if (currentEquityRatio < autoInvestMinRatio)
revert NotAutoInvestMinRatio();
_borrow(sweepAmount);
uint256 usdAmount = sweepAmount.mulDiv(price, 10 ** sweep.decimals());
uint256 usdInUsdx = _oracleUsdToUsdx(usdAmount);
uint256 minAmountOut = OvnMath.subBasisPoints(usdInUsdx, slippage);
uint256 usdxAmount = _sell(sweepAmount, minAmountOut);
_invest(usdxAmount, 0, slippage);
emit AutoInvested(sweepAmount);
}
/**
* @notice Buy
* Buys sweep amount from the stabilizer's balance to the AMM (swaps USDX to SWEEP).
* @param usdxAmount Amount to be changed in the AMM.
* @param amountOutMin Minimum amount out.
* @dev Increases the sweep balance and decrease usdx balance.
*/
function buySweepOnAMM(
uint256 usdxAmount,
uint256 amountOutMin
)
external
onlyBorrower
whenNotPaused
nonReentrant
returns (uint256 sweepAmount)
{
sweepAmount = _buy(usdxAmount, amountOutMin);
emit Bought(sweepAmount);
}
/**
* @notice Sell Sweep
* Sells sweep amount from the stabilizer's balance to the AMM (swaps SWEEP to USDX).
* @param sweepAmount.
* @param amountOutMin Minimum amount out.
* @dev Decreases the sweep balance and increase usdx balance
*/
function sellSweepOnAMM(
uint256 sweepAmount,
uint256 amountOutMin
)
external
onlyBorrower
whenNotPaused
nonReentrant
returns (uint256 usdxAmount)
{
usdxAmount = _sell(sweepAmount, amountOutMin);
emit Sold(sweepAmount);
}
/**
* @notice Buy Sweep with Stabilizer
* Buys sweep amount from the stabilizer's balance to the Borrower (swaps USDX to SWEEP).
* @param usdxAmount.
* @dev Decreases the sweep balance and increase usdx balance
*/
function swapUsdxToSweep(
uint256 usdxAmount
) external onlyBorrower whenNotPaused validAmount(usdxAmount) nonReentrant {
uint256 usdxInUsd = _oracleUsdxToUsd(usdxAmount);
uint256 sweepAmount = sweep.convertToSWEEP(usdxInUsd);
uint256 sweepBalance = sweep.balanceOf(address(this));
if (sweepAmount > sweepBalance) revert NotEnoughBalance();
TransferHelper.safeTransferFrom(
address(usdx),
msg.sender,
address(this),
usdxAmount
);
TransferHelper.safeTransfer(address(sweep), msg.sender, sweepAmount);
emit BoughtSWEEP(sweepAmount);
}
/**
* @notice Sell Sweep with Stabilizer
* Sells sweep amount to the stabilizer (swaps SWEEP to USDX).
* @param sweepAmount.
* @dev Decreases the sweep balance and increase usdx balance
*/
function swapSweepToUsdx(
uint256 sweepAmount
)
external
onlyBorrower
whenNotPaused
validAmount(sweepAmount)
nonReentrant
{
uint256 sweepInUsd = sweep.convertToUSD(sweepAmount);
uint256 usdxAmount = _oracleUsdToUsdx(sweepInUsd);
uint256 usdxBalance = usdx.balanceOf(address(this));
if (usdxAmount > usdxBalance) revert NotEnoughBalance();
TransferHelper.safeTransferFrom(
address(sweep),
msg.sender,
address(this),
sweepAmount
);
TransferHelper.safeTransfer(address(usdx), msg.sender, usdxAmount);
emit SoldSWEEP(usdxAmount);
}
/**
* @notice Withdraw SWEEP
* Takes out sweep balance if the new equity ratio is higher than the minimum equity ratio.
* @param token.
* @param amount.
* @dev Decreases the sweep balance.
*/
function withdraw(
address token,
uint256 amount
) external onlyBorrower whenNotPaused validAmount(amount) nonReentrant {
if (amount > IERC20Metadata(token).balanceOf(address(this)))
revert NotEnoughBalance();
if (sweepBorrowed > 0) {
if (token != address(sweep) && token != address(usdx))
revert InvalidToken();
uint256 usdAmount = token == address(sweep)
? sweep.convertToUSD(amount)
: _oracleUsdxToUsd(amount);
int256 currentEquityRatio = _calculateEquityRatio(0, usdAmount);
if (currentEquityRatio < minEquityRatio)
revert EquityRatioExcessed();
}
TransferHelper.safeTransfer(token, msg.sender, amount);
emit Withdrawn(token, amount);
}
/**
* @notice Start auction
* Initiates a dutch auction for liquidation.
*/
function startAuction() external {
if (!isDefaulted()) revert NotDefaulted();
if(!auctionAllowed || startingPrice > 0) revert ActionNotAllowed();
startingTime = block.timestamp;
uint256 minEquity = (PRECISION - uint256(minEquityRatio));
startingPrice = getDebt() * PRECISION / minEquity;
}
/**
* @notice Buy auction
* Allows a user to participate in the auction by buying assets
*/
function buyAuction() external nonReentrant {
if(startingTime == 0) revert AuctionNotActive();
uint256 debt = getAuctionAmount();
address token = _getToken();
_liquidate(token, debt);
}
/* ========== Internals ========== */
/**
* @notice Invest To Asset.
*/
function _invest(uint256, uint256, uint256) internal virtual {}
/**
* @notice Divest From Asset.
*/
function _divest(uint256, uint256) internal virtual returns (uint256) {}
/**
* @notice Get asset address to liquidate.
*/
function _getToken() internal virtual returns (address) {}
/**
* @notice Stop the auction.
*/
function _stopAuction() internal {
startingTime = 0;
startingPrice = 0;
}
/**
* @notice Liquidates
* A liquidator repays the debt in sweep and gets the same value
* of the assets that the stabilizer holds at a discount
*/
function _liquidate(
address token,
uint256 debt
) internal {
if (!isDefaulted()) revert NotDefaulted();
address self = address(this);
uint256 usdxBalance = usdx.balanceOf(self);
uint256 tokenBalance = IERC20Metadata(token).balanceOf(self);
uint256 sweepBalance = sweep.balanceOf(self);
if(debt > sweepBalance) {
// Takes SWEEP from the liquidator and repays debt
TransferHelper.safeTransferFrom(
address(sweep),
msg.sender,
self,
debt - sweepBalance
);
}
// Gives all the assets to the liquidator
TransferHelper.safeTransfer(address(usdx), msg.sender, usdxBalance);
TransferHelper.safeTransfer(token, msg.sender, tokenBalance);
_repay(debt);
emit Liquidated(msg.sender);
}
function _buy(
uint256 usdxAmount,
uint256 amountOutMin
) internal returns (uint256) {
uint256 usdxBalance = usdx.balanceOf(address(this));
usdxAmount = usdxAmount.min(usdxBalance);
if (usdxAmount == 0) revert NotEnoughBalance();
IAMM _amm = amm();
TransferHelper.safeApprove(address(usdx), address(_amm), usdxAmount);
uint256 sweepAmount = _amm.buySweep(
address(usdx),
usdxAmount,
amountOutMin
);
return sweepAmount;
}
function _sell(
uint256 sweepAmount,
uint256 amountOutMin
) internal returns (uint256) {
uint256 sweepBalance = sweep.balanceOf(address(this));
sweepAmount = sweepAmount.min(sweepBalance);
if (sweepAmount == 0) revert NotEnoughBalance();
IAMM _amm = amm();
TransferHelper.safeApprove(address(sweep), address(_amm), sweepAmount);
uint256 usdxAmount = _amm.sellSweep(
address(usdx),
sweepAmount,
amountOutMin
);
return usdxAmount;
}
function _borrow(uint256 sweepAmount) internal {
uint256 spreadAmount = accruedFee();
sweep.mint(sweepAmount);
sweepBorrowed += sweepAmount;
spreadDate = block.timestamp;
if (spreadAmount > 0) {
TransferHelper.safeTransfer(
address(sweep),
sweep.treasury(),
spreadAmount
);
emit PayFee(spreadAmount);
}
emit Borrowed(sweepAmount);
}
function _repay(uint256 sweepAmount) internal {
uint256 sweepBalance = sweep.balanceOf(address(this));
sweepAmount = sweepAmount.min(sweepBalance);
if (sweepAmount == 0) revert NotEnoughBalance();
callAmount = (callAmount > sweepAmount)
? (callAmount - sweepAmount)
: 0;
if (callDelay > 0 && callAmount == 0) callTime = 0;
uint256 spreadAmount = accruedFee();
spreadDate = block.timestamp;
sweepAmount = sweepAmount - spreadAmount;
if (sweepBorrowed < sweepAmount) {
sweepAmount = sweepBorrowed;
sweepBorrowed = 0;
} else {
sweepBorrowed -= sweepAmount;
}
TransferHelper.safeTransfer(
address(sweep),
sweep.treasury(),
spreadAmount
);
TransferHelper.safeApprove(address(sweep), address(this), sweepAmount);
sweep.burn(sweepAmount);
emit Repaid(sweepAmount);
if(!isDefaulted()) _stopAuction();
}
/**
* @notice Calculate Equity Ratio
* Calculated the equity ratio based on the internal storage.
* @param sweepDelta Variation of SWEEP to recalculate the new equity ratio.
* @param usdDelta Variation of USD to recalculate the new equity ratio.
* @return the new equity ratio used to control the Mint and Withdraw functions.
* @dev Current Equity Ratio percentage has a precision of 4 decimals.
*/
function _calculateEquityRatio(
uint256 sweepDelta,
uint256 usdDelta
) internal view returns (int256) {
uint256 currentValue_ = currentValue();
uint256 sweepDeltaInUsd = sweep.convertToUSD(sweepDelta);
uint256 totalValue = currentValue_ + sweepDeltaInUsd - usdDelta;
if (totalValue == 0) {
if (sweepBorrowed > 0) return -1e6;
else return 0;
}
uint256 seniorTrancheInUsd = sweep.convertToUSD(
sweepBorrowed + sweepDelta
);
// 1e6 is decimals of the percentage result
int256 currentEquityRatio = ((int256(totalValue) -
int256(seniorTrancheInUsd)) * 1e6) / int256(totalValue);
if (currentEquityRatio < -1e6) currentEquityRatio = -1e6;
return currentEquityRatio;
}
/**
* @notice Get Balances of the usdx and SWEEP.
**/
function _balances()
internal
view
returns (uint256 usdxBalance, uint256 sweepBalance)
{
usdxBalance = usdx.balanceOf(address(this));
sweepBalance = sweep.balanceOf(address(this));
}
function _onlyBorrower() internal view {
if (msg.sender != borrower) revert NotBorrower();
}
function _onlySettingsEnabled() internal view {
if (!settingsEnabled) revert SettingsDisabled();
}
function _validAmount(uint256 amount) internal pure {
if (amount == 0) revert OverZero();
}
function _oracleUsdxToUsd(
uint256 usdxAmount
) internal view returns (uint256) {
return
ChainlinkLibrary.convertTokenToUsd(
usdxAmount,
usdx.decimals(),
oracleUsdx
);
}
function _oracleUsdToUsdx(
uint256 usdAmount
) internal view returns (uint256) {
return
ChainlinkLibrary.convertUsdToToken(
usdAmount,
usdx.decimals(),
oracleUsdx
);
}
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;
import './IERC20.sol';
library TransferHelper {
/// @notice Transfers tokens from the targeted address to the given destination
/// @notice Errors with 'STF' if transfer fails
/// @param token The contract address of the token to be transferred
/// @param from The originating address from which the tokens will be transferred
/// @param to The destination address of the transfer
/// @param value The amount to be transferred
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)
);
require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
}
/// @notice Transfers tokens from msg.sender to a recipient
/// @dev Errors with ST if transfer fails
/// @param token The contract address of the token which will be transferred
/// @param to The recipient of the transfer
/// @param value The value of the transfer
function safeTransfer(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
}
/// @notice Approves the stipulated contract to spend the given allowance in the given token
/// @dev Errors with 'SA' if transfer fails
/// @param token The contract address of the token to be approved
/// @param to The target of the approval
/// @param value The amount of the given token the target will be allowed to spend
function safeApprove(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');
}
/// @notice Transfers ETH to the recipient address
/// @dev Fails with `STE`
/// @param to The destination of the transfer
/// @param value The value to be transferred
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, 'STE');
}
}
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_sweep","type":"address"},{"internalType":"address","name":"_usdx","type":"address"},{"internalType":"address","name":"_oracleUsdx","type":"address"},{"internalType":"address","name":"_poolAddress","type":"address"},{"internalType":"address","name":"_borrower","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ActionNotAllowed","type":"error"},{"inputs":[],"name":"AssetDefaulted","type":"error"},{"inputs":[],"name":"AuctionNotActive","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"BadAddress","type":"error"},{"inputs":[],"name":"EquityRatioExcessed","type":"error"},{"inputs":[],"name":"InvalidMinter","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"NotAutoInvest","type":"error"},{"inputs":[],"name":"NotAutoInvestMinAmount","type":"error"},{"inputs":[],"name":"NotAutoInvestMinRatio","type":"error"},{"inputs":[],"name":"NotBalancer","type":"error"},{"inputs":[],"name":"NotBorrower","type":"error"},{"inputs":[],"name":"NotDefaulted","type":"error"},{"inputs":[],"name":"NotEnoughBalance","type":"error"},{"inputs":[],"name":"NotGovernance","type":"error"},{"inputs":[],"name":"NotMultisigOrGov","type":"error"},{"inputs":[],"name":"NotSweep","type":"error"},{"inputs":[],"name":"OverZero","type":"error"},{"inputs":[],"name":"SettingsDisabled","type":"error"},{"inputs":[],"name":"SpreadNotEnough","type":"error"},{"inputs":[],"name":"ZeroAddressDetected","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"AutoCalled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"AutoInvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"Borrowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"Bought","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"BoughtSWEEP","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"CallCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"minEquityRatio","type":"int256"},{"indexed":true,"internalType":"uint256","name":"spreadFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loanLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreaseFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"callDelay","type":"uint256"},{"indexed":false,"internalType":"int256","name":"autoInvestMinRatio","type":"int256"},{"indexed":false,"internalType":"uint256","name":"autoInvestMinAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minLiquidationRatio","type":"uint256"},{"indexed":false,"internalType":"bool","name":"autoInvestEnabled","type":"bool"},{"indexed":false,"internalType":"bool","name":"_auctionAllowed","type":"bool"},{"indexed":false,"internalType":"string","name":"url","type":"string"}],"name":"ConfigurationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Liquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"usdxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"LiquidityAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"usdxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"LiquidityRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"loanLimit","type":"uint256"}],"name":"LoanLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"PayFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"}],"name":"Proposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"}],"name":"Rejected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"Repaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"Sold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"usdxAmount","type":"uint256"}],"name":"SoldSWEEP","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"SweepBorrowedChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"sweeAmount","type":"uint256"}],"name":"SweepPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"accruedFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdxAmount","type":"uint256"},{"internalType":"uint256","name":"sweepAmount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"amm","outputs":[{"internalType":"contract IAMM","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auctionAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"autoCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"autoInvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoInvestEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoInvestMinAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoInvestMinRatio","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"borrower","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bptIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"buySweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdxAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"}],"name":"buySweepOnAMM","outputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"callAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"_minEquityRatio","type":"int256"},{"internalType":"uint256","name":"_spreadFee","type":"uint256"},{"internalType":"uint256","name":"_loanLimit","type":"uint256"},{"internalType":"uint256","name":"_decreaseFactor","type":"uint256"},{"internalType":"uint256","name":"_callDelay","type":"uint256"},{"internalType":"int256","name":"_autoInvestMinRatio","type":"int256"},{"internalType":"uint256","name":"_autoInvestMinAmount","type":"uint256"},{"internalType":"uint256","name":"_minLiquidationRatio","type":"uint256"},{"internalType":"bool","name":"_autoInvestEnabled","type":"bool"},{"internalType":"bool","name":"_auctionAllowed","type":"bool"},{"internalType":"string","name":"_url","type":"string"}],"name":"configure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decreaseFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuctionAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEquityRatio","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getJuniorTrancheValue","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdxAmount","type":"uint256"},{"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"initPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isDefaulted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"link","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"loanLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minEquityRatio","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minLiquidationRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleUsdx","outputs":[{"internalType":"contract IPriceFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract IBalancerPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolAssets","outputs":[{"internalType":"contract IAsset","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"propose","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdxAmount","type":"uint256"},{"internalType":"uint256","name":"sweepAmount","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"repay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"}],"name":"sellSweepOnAMM","outputs":[{"internalType":"uint256","name":"usdxAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLoanLimit","type":"uint256"}],"name":"setLoanLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settingsEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"spreadDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"spreadFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"swapSweepToUsdx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdxAmount","type":"uint256"}],"name":"swapUsdxToSweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sweep","outputs":[{"internalType":"contract ISweep","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sweepBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sweepIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"updateSweepBorrowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdx","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdxIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IBalancerVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b50604051620064f6380380620064f68339810160408190526200003491620005d3565b8585858584836001600160a01b0381166200006257604051632887dd7560e11b815260040160405180910390fd5b6001600160a01b039081166080526000805460ff191690556001805581166200009e57604051632887dd7560e11b815260040160405180910390fd5b6004620000ac868262000774565b50600280546001600160a01b03199081166001600160a01b039586161790915560038054821693851693909317909255600580549092169083161790556011805461010061ff0019909116811790915560168054610100600160a81b03191687841683021790819055604080516311b2515f60e31b81529051929091049092169350638d928af8925060048083019260209291908290030181865afa1580156200015a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000180919062000840565b601780546001600160a01b0319166001600160a01b039283161790556016546040805163038fff2d60e41b81529051610100909204909216916338fff2d09160048083019260209291908290030181865afa158015620001e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020a919062000867565b6018819055601754604051631f29a8cd60e31b815260048101929092526001600160a01b03169063f94d466890602401600060405180830381865afa15801562000258573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200028291908101906200091a565b5050805162000299906019906020840190620004de565b5050620003066080516019805480602002602001604051908101604052809291908181526020018280548015620002fa57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620002db575b50506200044892505050565b601a805460ff191660ff9290921691909117905560025460198054604080516020808402820181019092528281526200038c946001600160a01b03169390929091830182828015620002fa576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311620002db5750506200044892505050565b601a60016101000a81548160ff021916908360ff16021790555062000422601660019054906101000a90046001600160a01b03166019805480602002602001604051908101604052809291908181526020018280548015620002fa576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311620002db5750506200044892505050565b601a60026101000a81548160ff021916908360ff16021790555050505050505062000a39565b6000805b82518160ff161015620004af57836001600160a01b0316838260ff16815181106200047b576200047b620009f5565b60200260200101516001600160a01b0316036200049a579050620004d8565b80620004a68162000a0b565b9150506200044c565b50604051637833514560e11b81526001600160a01b038416600482015260240160405180910390fd5b92915050565b82805482825590600052602060002090810192821562000536579160200282015b828111156200053657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620004ff565b506200054492915062000548565b5090565b5b8082111562000544576000815560010162000549565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620005a057620005a06200055f565b604052919050565b6001600160a01b0381168114620005be57600080fd5b50565b8051620005ce81620005a8565b919050565b60008060008060008060c08789031215620005ed57600080fd5b86516001600160401b03808211156200060557600080fd5b818901915089601f8301126200061a57600080fd5b8151818111156200062f576200062f6200055f565b6020915062000647601f8201601f1916830162000575565b8181528b838386010111156200065c57600080fd5b60005b828110156200067c5784810184015182820185015283016200065f565b506000838383010152809950505062000697818a01620005c1565b96505050620006a960408801620005c1565b9350620006b960608801620005c1565b9250620006c960808801620005c1565b9150620006d960a08801620005c1565b90509295509295509295565b600181811c90821680620006fa57607f821691505b6020821081036200071b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200076f57600081815260208120601f850160051c810160208610156200074a5750805b601f850160051c820191505b818110156200076b5782815560010162000756565b5050505b505050565b81516001600160401b038111156200079057620007906200055f565b620007a881620007a18454620006e5565b8462000721565b602080601f831160018114620007e05760008415620007c75750858301515b600019600386901b1c1916600185901b1785556200076b565b600085815260208120601f198616915b828110156200081157888601518255948401946001909101908401620007f0565b5085821015620008305787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200085357600080fd5b81516200086081620005a8565b9392505050565b6000602082840312156200087a57600080fd5b5051919050565b60006001600160401b038211156200089d576200089d6200055f565b5060051b60200190565b600082601f830112620008b957600080fd5b81516020620008d2620008cc8362000881565b62000575565b82815260059290921b84018101918181019086841115620008f257600080fd5b8286015b848110156200090f5780518352918301918301620008f6565b509695505050505050565b6000806000606084860312156200093057600080fd5b83516001600160401b03808211156200094857600080fd5b818601915086601f8301126200095d57600080fd5b8151602062000970620008cc8362000881565b82815260059290921b8401810191818101908a8411156200099057600080fd5b948201945b83861015620009bb578551620009ab81620005a8565b8252948201949082019062000995565b91890151919750909350505080821115620009d557600080fd5b50620009e486828701620008a7565b925050604084015190509250925092565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff810362000a3057634e487b7160e01b600052601160045260246000fd5b60010192915050565b6080516158e862000c0e6000396000818161054d015281816107b701528181610863015281816108f80152818161099c01528181610a7c01528181610ace01528181610c8201528181610d1001528181610dbb01528181610e4301528181610f8d0152818161102d0152818161104e015281816111180152818161118d0152818161120f01528181611322015281816113c00152818161149301528181611530015281816115f70152818161165c015281816116e0015281816118400152818161199701528181611a4f01528181611b1801528181611c3901528181611d3401528181611dd201528181611fab01528181612050015281816123a20152818161243a0152818161249f01528181612a1901528181612b4901528181612c6101528181612d2f01528181612e780152818161310301528181613173015281816131ce01528181613358015281816134720152818161380701528181613891015281816138b201528181613bb901528181613c5e015281816140690152818161419b015281816141bc0152818161421d01528181614259015281816144d7015281816145ab0152818161466001528181614834015281816148df01528181614ab001528181614b2a0152614c4101526158e86000f3fe608060405234801561001057600080fd5b50600436106103d05760003560e01c80636b64c769116101ff578063bb3521201161011a578063de839ba4116100ad578063f69aa3d51161007c578063f69aa3d514610745578063f95c1b2614610758578063fa45d56214610765578063fbfa77cf1461077857600080fd5b8063de839ba41461070d578063ea8364aa14610716578063f3fef3a314610729578063f686138d1461073c57600080fd5b8063c5ebeaec116100e9578063c5ebeaec146106e0578063c6beb586146106f3578063d366a41f146106fc578063d6fbf2021461070457600080fd5b8063bb352120146106aa578063bc5477ad146106b3578063c0f4a005146106c6578063c198f8ba146106d857600080fd5b8063a195166511610192578063a71891c311610161578063a71891c31461067f578063ad81fced14610687578063b220a79b14610690578063ba2d0344146106a257600080fd5b8063a19516651461065d578063a38aaa9014610666578063a516ed021461066e578063a6a8f1f91461067657600080fd5b80638456cb59116101ce5780638456cb591461061c578063857620e1146106245780638d1d7c61146106375780639e1b00451461064a57600080fd5b80636b64c769146105e6578063717e794d146105ee5780637df1f1b9146105f65780638351faf51461060957600080fd5b806329b154c3116102ef5780633e0dc34e116102825780634dc415de116102515780634dc415de146105b85780635c975abb146105c057806361ab077f146105cb578063698996f8146105de57600080fd5b80633e0dc34e1461058b5780633f4ba83a14610594578063422f10431461059c57806348dcacab146105af57600080fd5b80633168b03f116102be5780633168b03f1461053557806335faa41614610548578063371fd8e61461056f57806339518b5e1461058257600080fd5b806329b154c3146104fe5780632a943945146105115780632d76643c14610519578063311176d71461052257600080fd5b806314a6bf0f11610367578063234439441161033657806323443944146104be57806325d9b792146104c657806329610252146104d95780632982db00146104e157600080fd5b806314a6bf0f1461047557806316f0115b1461047d5780631c4695f4146104ad5780631de01bc9146104b557600080fd5b80630f5e07c7116103a35780630f5e07c71461044357806312bec0021461044c57806312f21a1a146104595780631370720f1461046257600080fd5b8063050d6f78146103d557806306fdde03146103ea5780630a246871146104085780630e5f5dbd1461042d575b600080fd5b6103e86103e3366004614f51565b61078b565b005b6103f2610b38565b6040516103ff9190614fc3565b60405180910390f35b601a5461041b9062010000900460ff1681565b60405160ff90911681526020016103ff565b610435610bc6565b6040519081526020016103ff565b61043560095481565b601a5461041b9060ff1681565b610435600d5481565b6103e8610470366004614fd6565b610c31565b610435610e18565b6016546104959061010090046001600160a01b031681565b6040516001600160a01b0390911681526020016103ff565b6103f2610e34565b610435600a5481565b6103e8610e41565b6104956104d4366004614fd6565b610f2a565b6103e8610f54565b6016546104ee9060ff1681565b60405190151581526020016103ff565b6103e861050c366004614fd6565b61110d565b610495611189565b61043560075481565b600254610495906001600160a01b031681565b6103e8610543366004614fd6565b61120d565b6104957f000000000000000000000000000000000000000000000000000000000000000081565b6103e861057d366004614fd6565b6112fb565b61043560125481565b61043560185481565b6103e8611320565b6103e86105aa366004614fef565b61147c565b610435600b5481565b6103e86116de565b60005460ff166104ee565b6104356105d9366004614f51565b6117da565b61043561183b565b6103e86118fb565b610435611992565b600554610495906001600160a01b031681565b6103e8610617366004614fef565b611a45565b6103e8611d32565b6103e8610632366004614fef565b611e8e565b600354610495906001600160a01b031681565b6103e8610658366004614f51565b61238b565b61043560105481565b6104ee612693565b6103e86126d9565b61043560155481565b61043561271c565b61043560085481565b601a5461041b90610100900460ff1681565b610435612950565b61043560145481565b6103e86106c1366004614fef565b612a0f565b6011546104ee90610100900460ff1681565b6103e8612df4565b6103e86106ee366004614fd6565b612e41565b61043560065481565b610435612f83565b61043560135481565b610435600c5481565b6103e8610724366004615072565b612f90565b6103e861073736600461514e565b61304f565b610435600f5481565b610435610753366004614f51565b6132c2565b6011546104ee9060ff1681565b6103e8610773366004614fd6565b61331d565b601754610495906001600160a01b031681565b6107936134e7565b600754604051633d1bb33160e21b8152306004820152600091906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f46eccc4906024016080604051808303816000875af1158015610800573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108249190615190565b5161082f919061521b565b905061083c83600261522e565b81101561085c5760405163569d45cf60e11b815260040160405180910390fd5b60006108e87f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663dc38679c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e39190615245565b613545565b90506000620f424062ffffff16827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e19538476040518163ffffffff1660e01b8152600401602060405180830381865afa158015610954573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109789190615245565b610982919061522e565b61098c9190615274565b6109969083615288565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c919061529b565b610a2790600a6153a2565b610a31838861522e565b610a3b9190615274565b600254909150610a56906001600160a01b03163330846135da565b600254601754610a73916001600160a01b039081169116836136e4565b601754610aab907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b0316886136e4565b610abe610ab987600261522e565b6137e4565b610ac9818787613993565b610af47f00000000000000000000000000000000000000000000000000000000000000003388613e38565b6040518181527f6e19477745f02fa64cb79e709afd8b6a5da159ef7b135546eafd67c38e425c439060200160405180910390a150505050610b3460018055565b5050565b60048054610b45906153b1565b80601f0160208091040260200160405190810160405280929190818152602001828054610b71906153b1565b8015610bbe5780601f10610b9357610100808354040283529160200191610bbe565b820191906000526020600020905b815481529060010190602001808311610ba157829003601f168201915b505050505081565b60075460009015610c2b57600062015180600d5442610be5919061521b565b610bef9190615274565b9050610c00620f424061016d61522e565b81600c54600754610c11919061522e565b610c1b919061522e565b610c259190615274565b91505090565b50600090565b610c39613f31565b610c41613f5c565b80610c4b81613fa2565b610c536134e7565b6000610c5e83613fc3565b604051633068b6b560e21b8152600481018290529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c1a2dad490602401602060405180830381865afa158015610cc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ced9190615245565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7b9190615245565b905080821115610d9e5760405163569d45cf60e11b815260040160405180910390fd5b600254610db6906001600160a01b03163330886135da565b610de17f00000000000000000000000000000000000000000000000000000000000000003384613e38565b60405182907fbc87b68cd9f40bbab98db9b9e4d393c4ef32d4660271a908b81cfa10d8a59df990600090a2505050610b3460018055565b6000610e22610bc6565b600754610e2f9190615288565b905090565b600e8054610b45906153b1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec391906153eb565b6001600160a01b0316336001600160a01b031614610ef45760405163698bba4b60e01b815260040160405180910390fd5b6000600b81905560098190556040517f219124ae95cc25cf220d998f2867d37fb4ab4908cce7c51adfa33ce747aa5747908290a2565b60198181548110610f3a57600080fd5b6000918252602090912001546001600160a01b0316905081565b610f5c613f31565b610f646134e7565b6000610f6e610bc6565b42600d556040516370a0823160e01b81523060048201529091506000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110009190615245565b905080821115611022576040516206230160eb1b815260040160405180910390fd5b8115611100576110d47f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ce91906153eb565b84613e38565b60405182907fda0ff68ccd5fb797a8f86207386ea961ca6990c15ace2424ab51eb871ed4959990600090a25b505061110b60018055565b565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111565760405163bc9eca6160e01b815260040160405180910390fd5b600781905560405181907f35ba42ee3c2daa6cf14836eefff16b184565798767ec1e5d723008848aeaf7e390600090a250565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632a9439456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f91906153eb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128f91906153eb565b6001600160a01b0316336001600160a01b0316146112c05760405163698bba4b60e01b815260040160405180910390fd5b60088190556040518181527f7760d892a7883522367f0eaea35e968381a018418c249cd9aaaca190fe5d88179060200160405180910390a150565b611303613f31565b61130b6134e7565b61131481614051565b61131d60018055565b50565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663baf4a3126040518163ffffffff1660e01b8152600401602060405180830381865afa15801561137e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a291906153eb565b6001600160a01b0316336001600160a01b03161415801561145657507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144091906153eb565b6001600160a01b0316336001600160a01b031614155b1561147457604051631e1c735b60e21b815260040160405180910390fd5b61110b614303565b6114846134e7565b61148c613f31565b60003090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632b4818836040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115139190615408565b156115f257604051633d1bb33160e21b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f46eccc4906024016080604051808303816000875af1158015611581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a59190615190565b516007549091506000906115b9908361521b565b9050848110156115dc5760405163569d45cf60e11b815260040160405180910390fd5b84156115eb576115eb856137e4565b505061161e565b61161e7f00000000000000000000000000000000000000000000000000000000000000003383866135da565b600254611636906001600160a01b03163383876135da565b600254601754611653916001600160a01b039081169116866136e4565b60175461168b907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b0316856136e4565b611696848484613993565b60408051858152602081018590527f38f8a0c92f4c5b0b6877f878cb4c0c8d348a47b76d716c8e78f425043df9515b910160405180910390a1506116d960018055565b505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561173c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176091906153eb565b6001600160a01b0316336001600160a01b03161461179157604051632d5be4cb60e21b815260040160405180910390fd5b6011805461ff0019166101001790556005546040516001600160a01b03909116907faf77f8960cf590e245ec8b6d41c193a5dcacad8986ae4eb57ac9e5be7b6af03190600090a2565b60006117e4613f31565b6117ec613f5c565b6117f46134e7565b6117fe8383614355565b60405190915081907f4e08ba899977cf7d4c2964bce71c6b9a7ef76ee5166a4c1249a1e08016e33ef190600090a261183560018055565b92915050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166389da7df8611875610bc6565b6040518263ffffffff1660e01b815260040161189391815260200190565b602060405180830381865afa1580156118b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d49190615245565b9050806118df6144a4565b6118e761271c565b6118f19190615288565b610c25919061521b565b611903612693565b6119205760405163038cbd4b60e31b815260040160405180910390fd5b60165460ff16158061193457506000601354115b156119525760405163829e373360e01b815260040160405180910390fd5b4260125560065460009061196990620f424061521b565b905080620f4240611978610e18565b611982919061522e565b61198c9190615274565b60135550565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166389da7df86007546040518263ffffffff1660e01b81526004016119e591815260200190565b602060405180830381865afa158015611a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a269190615245565b90506000611a3261183b565b9050611a3e8282615425565b9250505090565b611a4d6134e7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611acf91906153eb565b6001600160a01b0316336001600160a01b031614611b005760405163698bba4b60e01b815260040160405180910390fd5b604051633d1bb33160e21b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f46eccc4906024016080604051808303816000875af1158015611b69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8d9190615190565b51600754909150600090611ba1908361521b565b9050611bad8582614564565b94506000611bbc86600061457c565b60115490915060ff16611be2576040516305b02a1960e01b815260040160405180910390fd5b601054861015611c05576040516312cd610d60e21b815260040160405180910390fd5b600f54811215611c28576040516378764b0f60e01b815260040160405180910390fd5b611c31866137e4565b6000611ccc867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb9919061529b565b611cc490600a6153a2565b899190614740565b90506000611cd982613545565b90506000611ce782886147ee565b90506000611cf58a83614812565b90506040518a907f8f77e6a87a8210bff9857b08990b1f360b73d6e92d422a9a0e2c78e449682a9c90600090a2505050505050506116d960018055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663baf4a3126040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db491906153eb565b6001600160a01b0316336001600160a01b031614158015611e6857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5291906153eb565b6001600160a01b0316336001600160a01b031614155b15611e8657604051631e1c735b60e21b815260040160405180910390fd5b61110b614947565b611e966134e7565b611e9e613f31565b6002546040805163313ce56760e01b8152905130926000926001600160a01b039091169163313ce567916004808201926020929091908290030181865afa158015611eed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f11919061529b565b611f1c90600a6153a2565b601654600254604051632a6f500560e11b81526001600160a01b03918216600482015261010090920416906354dea00a90602401602060405180830381865afa158015611f6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f919190615245565b611f9b908761522e565b611fa59190615274565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202b919061529b565b61203690600a6153a2565b601654604051632a6f500560e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152610100909204909116906354dea00a90602401602060405180830381865afa1580156120a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ca9190615245565b6120d4908761522e565b6120de9190615274565b90506000620f42406120f08682615288565b6120fa8486615288565b612104919061522e565b61210e9190615274565b60408051600380825260808201909252919250600091906020820160608036833701905050601a54815191925089918391610100900460ff169081106121565761215661544c565b6020908102919091010152601a5481518891839160ff90911690811061217e5761217e61544c565b60209081029190910101526040805160028082526060820190925260009181602001602082028036833701905050601a5490915060ff610100820481169116116121c857876121ca565b885b816000815181106121dd576121dd61544c565b6020908102919091010152601a5460ff610100820481169116116122015788612203565b875b816001815181106122165761221661544c565b60200260200101818152505060006001828560405160200161223a939291906154b3565b60408051601f198184030181526019805460a06020820286018101909452608085018181529295506000949384939291908401828280156122a457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612286575b505050918352505060208101869052604080820185905260006060909201919091526017546018549151638bdb391360e01b81529293506001600160a01b031691638bdb3913916122fd918c9081908790600401615583565b600060405180830381600087803b15801561231757600080fd5b505af115801561232b573d6000803e3d6000fd5b5050505060008a1115612341576123418a614051565b604080518c8152602081018c90527f6f0f96292ae0038c04f9b6bab30f185d9ca02c471d0983f563f2a4f674aef137910160405180910390a150505050505050506116d960018055565b6123936134e7565b61239b613f31565b60003090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632b4818836040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124229190615408565b1561243557612430826137e4565b612461565b6124617f00000000000000000000000000000000000000000000000000000000000000003383856135da565b600254612479906001600160a01b03163383866135da565b600254601754612496916001600160a01b039081169116856136e4565b6017546124ce907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b0316846136e4565b604080516003808252608082019092526000916020820160608036833701905050601a548151919250600160701b91839162010000900460ff169081106125175761251761544c565b6020026020010181815250508381601a60019054906101000a900460ff1660ff16815181106125485761254861544c565b6020908102919091010152601a5481518491839160ff9091169081106125705761257061544c565b602002602001018181525050600080826040516020016125919291906155c9565b60408051601f198184030181526019805460a06020820286018101909452608085018181529295506000949384939291908401828280156125fb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116125dd575b50505091835250506020810185905260408082018590526000606090920191909152601754601854915163172b958560e31b81529293506001600160a01b03169163b95cac289161265491889081908790600401615583565b600060405180830381600087803b15801561266e57600080fd5b505af1158015612682573d6000803e3d6000fd5b5050505050505050610b3460018055565b600080600a541180156126a857506000600b54115b80156126b5575060095442115b80610e2f57506000600754118015610e2f57506006546126d3612f83565b12905090565b6126e16134e7565b601254600003612704576040516334dc687f60e11b815260040160405180910390fd5b600061270e612950565b905060006111008183614984565b6016546040516370a0823160e01b815230600482015260009182916101009091046001600160a01b0316906370a0823190602401602060405180830381865afa15801561276d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127919190615245565b90506000601660019054906101000a90046001600160a01b03166001600160a01b031663679aefce6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280c9190615245565b90506000601660019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612863573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612887919061529b565b6128929060026155f1565b61289d90600a6153a2565b600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612914919061529b565b61291f90600a6153a2565b612929848661522e565b612933919061522e565b61293d9190615274565b905061294881613fc3565b935050505090565b600080620f4240601554620f4240612968919061521b565b600754612975919061522e565b61297f9190615274565b9050600061012c60125442612994919061521b565b61299e9190615274565b90506000601454826129b0919061522e565b9050620f42408111156129c557509092915050565b60006129d482620f424061521b565b90506000620f4240826013546129ea919061522e565b6129f49190615274565b9050808511612a035780612a05565b845b9550505050505090565b612a176134e7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9991906153eb565b6001600160a01b0316336001600160a01b031614612aca5760405163698bba4b60e01b815260040160405180910390fd5b600080612ad5614bb8565b915091506000612af06007548761456490919063ffffffff16565b600a5490915015612b1157600a54612b089042615288565b600955600b8190555b80821015612d17576000612b25838361521b565b60405163113b4fbf60e31b8152600481018290529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906389da7df890602401602060405180830381865afa158015612b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb49190615245565b90506000612bc182613545565b905085811115612bda57612bd8610c2b878361521b565b505b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612c23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c479190615245565b1115612d13576000612c5882613fc3565b90506000612cf47f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce1919061529b565b612cec90600a6153a2565b83908c614740565b90506000612d02828b6147ee565b9050612d0e8482614355565b505050505b5050505b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da29190615245565b118015612daf5750600081115b15612dbd57612dbd81614051565b60405186907fdfcd68ceed46252749a4089f344aec4b4ee7f28a068f704c21799355325f3da990600090a25050506116d960018055565b612dfc613f31565b6011805461ff00191690556005546040516001600160a01b03909116907facf29ad8d63913d38e7e1176963a4afb76bf0918516051da68408ecb6f98065d90600090a2565b612e49613f31565b612e51613f5c565b80612e5b81613fa2565b612e636134e7565b60405163b67e9df760e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b67e9df790602401602060405180830381865afa158015612ec7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eeb9190615408565b612f085760405163d8d5894f60e01b815260040160405180910390fd5b6000600754600854612f1a919061521b565b905082811015612f3d5760405163569d45cf60e11b815260040160405180910390fd5b6000612f4a84600061457c565b9050600654811215612f6f5760405163374c72ff60e11b815260040160405180910390fd5b612f78846137e4565b5050610b3460018055565b6000610e2f60008061457c565b612f98613f31565b612fa0614cba565b60068c9055600c8b905560088a90556014899055600a889055600f879055601086905560158590556011805460ff199081168615151790915560168054909116841515179055600e612ff3828483615653565b508a8c7fed1352796b02006c8bf7ef68956cb9fc55c08f9193eee9cec7ee590840bbbaad8c6014548c8c8c8c8c8c8c8c6040516130399a99989796959493929190615713565b60405180910390a3505050505050505050505050565b613057613f31565b61305f613f5c565b8061306981613fa2565b6130716134e7565b6040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa1580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d99190615245565b8211156130f95760405163569d45cf60e11b815260040160405180910390fd5b60075415613278577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161415801561315157506002546001600160a01b03848116911614155b1561316f5760405163c1ab6dc160e01b815260040160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316146131b8576131b383613fc3565b613241565b60405163113b4fbf60e31b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906389da7df890602401602060405180830381865afa15801561321d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132419190615245565b9050600061325060008361457c565b90506006548112156132755760405163374c72ff60e11b815260040160405180910390fd5b50505b613283833384613e38565b60405182906001600160a01b038516907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d590600090a36116d960018055565b60006132cc613f31565b6132d4613f5c565b6132dc6134e7565b6132e68383614812565b60405190915083907f92f64ca637d023f354075a4be751b169c1a8a9ccb6d33cdd0cb352054399572790600090a261183560018055565b613325613f31565b61332d613f5c565b8061333781613fa2565b61333f6134e7565b60405163113b4fbf60e31b8152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906389da7df890602401602060405180830381865afa1580156133a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133cb9190615245565b905060006133d882613545565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa158015613426573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344a9190615245565b90508082111561346d5760405163569d45cf60e11b815260040160405180910390fd5b6134997f00000000000000000000000000000000000000000000000000000000000000003330886135da565b6002546134b0906001600160a01b03163384613e38565b60405182907fdcadafc28aac48a048c875f5f3127f2189b02d21291b563568cf8892a596bbb090600090a2505050610b3460018055565b60026001540361353e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600155565b600061183582600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561359e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c2919061529b565b60035460ff91909116906001600160a01b0316614ce2565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161363e9190615784565b6000604051808303816000865af19150503d806000811461367b576040519150601f19603f3d011682016040523d82523d6000602084013e613680565b606091505b50915091508180156136aa5750805115806136aa5750808060200190518101906136aa9190615408565b6136dc5760405162461bcd60e51b815260206004820152600360248201526229aa2360e91b6044820152606401613535565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916137409190615784565b6000604051808303816000865af19150503d806000811461377d576040519150601f19603f3d011682016040523d82523d6000602084013e613782565b606091505b50915091508180156137ac5750805115806137ac5750808060200190518101906137ac9190615408565b6137dd5760405162461bcd60e51b8152602060048201526002602482015261534160f01b6044820152606401613535565b5050505050565b60006137ee610bc6565b60405163140e25ad60e31b8152600481018490529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a0712d6890602401600060405180830381600087803b15801561385357600080fd5b505af1158015613867573d6000803e3d6000fd5b50505050816007600082825461387d9190615288565b909155505042600d558015613964576139387f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561390e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061393291906153eb565b83613e38565b60405181907fda0ff68ccd5fb797a8f86207386ea961ca6990c15ace2424ab51eb871ed4959990600090a25b60405182907f69c0ed5a77051ba5f0c42418bb6db6d3f73884dea69811c50bf320298df6ca5c90600090a25050565b604080516003808252608082019092523091600091906020820160608036833701905050601a54815191925086918391610100900460ff169081106139da576139da61544c565b6020908102919091010152601a5481518591839160ff909116908110613a0257613a0261544c565b60209081029190910101526040805160028082526060820190925260009181602001602082028036833701905050601a5490915060ff61010082048116911611613a4c5784613a4e565b855b81600081518110613a6157613a6161544c565b6020908102919091010152601a5460ff61010082048116911611613a855785613a87565b845b81600181518110613a9a57613a9a61544c565b6020026020010181815250506000600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613afb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b1f919061529b565b613b2a90600a6153a2565b601654600254604051632a6f500560e11b81526001600160a01b03918216600482015261010090920416906354dea00a90602401602060405180830381865afa158015613b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9f9190615245565b613ba9908961522e565b613bb39190615274565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c39919061529b565b613c4490600a6153a2565b601654604051632a6f500560e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152610100909204909116906354dea00a90602401602060405180830381865afa158015613cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd89190615245565b613ce2908961522e565b613cec9190615274565b90506000620f4240613cfe888261521b565b613d088486615288565b613d12919061522e565b613d1c9190615274565b9050600060018583604051602001613d36939291906157a0565b60408051601f198184030181526019805460a0602082028601810190945260808501818152929550600094938493929190840182828015613da057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d82575b50505091835250506020810189905260408082018590526000606090920191909152601754601854915163172b958560e31b81529293506001600160a01b03169163b95cac2891613df9918c9081908790600401615583565b600060405180830381600087803b158015613e1357600080fd5b505af1158015613e27573d6000803e3d6000fd5b505050505050505050505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691613e949190615784565b6000604051808303816000865af19150503d8060008114613ed1576040519150601f19603f3d011682016040523d82523d6000602084013e613ed6565b606091505b5091509150818015613f00575080511580613f00575080806020019051810190613f009190615408565b6137dd5760405162461bcd60e51b815260206004820152600260248201526114d560f21b6044820152606401613535565b6005546001600160a01b0316331461110b57604051631963d1e760e31b815260040160405180910390fd5b60005460ff161561110b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401613535565b8060000361131d57604051639d635cff60e01b815260040160405180910390fd5b600061183582600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561401c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614040919061529b565b6003546001600160a01b0316614d3f565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156140b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140dc9190615245565b90506140e88282614564565b91508160000361410b5760405163569d45cf60e11b815260040160405180910390fd5b81600b541161411b576000614129565b81600b54614129919061521b565b600b55600a541580159061413d5750600b54155b156141485760006009555b6000614152610bc6565b42600d559050614162818461521b565b925082600754101561417e576007805460009091559250614196565b8260076000828254614190919061521b565b90915550505b6142187f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561390e573d6000803e3d6000fd5b6142437f000000000000000000000000000000000000000000000000000000000000000030856136e4565b604051630852cd8d60e31b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b1580156142a557600080fd5b505af11580156142b9573d6000803e3d6000fd5b50506040518592507f33a382daad6aace935340a474d09fec82af4bec7e2b69518d283231b03a65f249150600090a26142f0612693565b6116d9576116d960006012819055601355565b61430b614d8f565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6002546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156143a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143c69190615245565b90506143d28482614564565b9350836000036143f55760405163569d45cf60e11b815260040160405180910390fd5b60006143ff611189565b600254909150614419906001600160a01b031682876136e4565b60025460405163231831c760e21b81526001600160a01b0391821660048201526024810187905260448101869052600091831690638c60c71c906064015b6020604051808303816000875af1158015614476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061449a9190615245565b9695505050505050565b60008060006144b1614bb8565b60405163113b4fbf60e31b81526004810182905291935091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906389da7df890602401602060405180830381865afa15801561451e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145429190615245565b9050600061454f84613fc3565b905061455b8282615288565b94505050505090565b60008183106145735781614575565b825b9392505050565b60008061458761183b565b60405163113b4fbf60e31b8152600481018690529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906389da7df890602401602060405180830381865afa1580156145f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146169190615245565b90506000846146258385615288565b61462f919061521b565b90508060000361465c576007541561465057620f423f199350505050611835565b60009350505050611835565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166389da7df88860075461469b9190615288565b6040518263ffffffff1660e01b81526004016146b991815260200190565b602060405180830381865afa1580156146d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146fa9190615245565b90506000826147098382615425565b61471690620f42406157c0565b61472091906157f0565b9050620f423f198112156147355750620f423f195b979650505050505050565b600080806000198587098587029250828110838203039150508060000361477a578382816147705761477061525e565b0492505050614575565b80841161478657600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6000620f42406147fe838261521b565b614808908561522e565b6145759190615274565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561487b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061489f9190615245565b90506148ab8482614564565b9350836000036148ce5760405163569d45cf60e11b815260040160405180910390fd5b60006148d8611189565b90506149057f000000000000000000000000000000000000000000000000000000000000000082876136e4565b600254604051631c6d209760e11b81526001600160a01b03918216600482015260248101879052604481018690526000918316906338da412e90606401614457565b61494f613f5c565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586143383390565b61498c612693565b6149a95760405163038cbd4b60e31b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201819052916000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156149f7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a1b9190615245565b6040516370a0823160e01b81526001600160a01b0384811660048301529192506000918616906370a0823190602401602060405180830381865afa158015614a67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a8b9190615245565b6040516370a0823160e01b81526001600160a01b0385811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015614af7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b1b9190615245565b905080851115614b5a57614b5a7f00000000000000000000000000000000000000000000000000000000000000003386614b55858a61521b565b6135da565b600254614b71906001600160a01b03163385613e38565b614b7c863384613e38565b614b8585614051565b60405133907f1e1ef858062a7196d1891e397a5cde9891e6ddf61a81e9d269a3aaa7a95dacd890600090a2505050505050565b6002546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa158015614c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c299190615245565b6040516370a0823160e01b81523060048201529092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015614c90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cb49190615245565b90509091565b601154610100900460ff1661110b57604051634e751a9560e11b815260040160405180910390fd5b600080614cee83614dd8565b90506000614cfb84614e3c565b9050614d096006600a6153a2565b614d13908261522e565b614d208660ff8516615288565b614d2b90600a61581e565b614d35908861522e565b61449a9190615274565b600080614d4b83614dd8565b90506000614d5884614e3c565b9050614d64858361582a565b614d6f90600a6153a2565b614d7b6006600a6153a2565b614d85838961522e565b614d35919061522e565b60005460ff1661110b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401613535565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611835919061529b565b6000806000806000856001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015614e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ea69190615862565b9450945050935093508369ffffffffffffffffffff168169ffffffffffffffffffff161015614f025760405162461bcd60e51b81526020600482015260086024820152674f6c64206461746160c01b6044820152606401613535565b60008211614f475760405162461bcd60e51b8152602060048201526012602482015271526f756e64206e6f7420636f6d706c65746560701b6044820152606401613535565b5090949350505050565b60008060408385031215614f6457600080fd5b50508035926020909101359150565b60005b83811015614f8e578181015183820152602001614f76565b50506000910152565b60008151808452614faf816020860160208601614f73565b601f01601f19169290920160200192915050565b6020815260006145756020830184614f97565b600060208284031215614fe857600080fd5b5035919050565b60008060006060848603121561500457600080fd5b505081359360208301359350604090920135919050565b801515811461131d57600080fd5b60008083601f84011261503b57600080fd5b50813567ffffffffffffffff81111561505357600080fd5b60208301915083602082850101111561506b57600080fd5b9250929050565b6000806000806000806000806000806000806101608d8f03121561509557600080fd5b8c359b5060208d01359a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d0135955060e08d013594506150d86101008e013561501b565b6101008d013593506150ee6101208e013561501b565b6101208d0135925067ffffffffffffffff6101408e0135111561511057600080fd5b6151218e6101408f01358f01615029565b81935080925050509295989b509295989b509295989b565b6001600160a01b038116811461131d57600080fd5b6000806040838503121561516157600080fd5b823561516c81615139565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b6000608082840312156151a257600080fd5b6040516080810181811067ffffffffffffffff821117156151c5576151c561517a565b8060405250825181526020830151602082015260408301516151e68161501b565b604082015260608301516151f98161501b565b60608201529392505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561183557611835615205565b808202811582820484141761183557611835615205565b60006020828403121561525757600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b6000826152835761528361525e565b500490565b8082018082111561183557611835615205565b6000602082840312156152ad57600080fd5b815160ff8116811461457557600080fd5b600181815b808511156152f95781600019048211156152df576152df615205565b808516156152ec57918102915b93841c93908002906152c3565b509250929050565b60008261531057506001611835565b8161531d57506000611835565b8160018114615333576002811461533d57615359565b6001915050611835565b60ff84111561534e5761534e615205565b50506001821b611835565b5060208310610133831016604e8410600b841016171561537c575081810a611835565b61538683836152be565b806000190482111561539a5761539a615205565b029392505050565b600061457560ff841683615301565b600181811c908216806153c557607f821691505b6020821081036153e557634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156153fd57600080fd5b815161457581615139565b60006020828403121561541a57600080fd5b81516145758161501b565b818103600083128015838313168383128216171561544557615445615205565b5092915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b600081518084526020808501945080840160005b838110156154a85781518752958201959082019060010161548c565b509495945050505050565b6000600385106154c5576154c5615462565b848252606060208301526154dc6060830185615478565b9050826040830152949350505050565b8051608080845281519084018190526000916020919082019060a0860190845b818110156155315783516001600160a01b03168352928401929184019160010161550c565b50508285015191508581038387015261554a8183615478565b92505050604083015184820360408601526155658282614f97565b915050606083015161557b606086018215159052565b509392505050565b8481526001600160a01b0384811660208301528316604082015260806060820181905260009061449a908301846154ec565b600481106155c5576155c5615462565b9052565b6155d381846155b5565b6040602082015260006155e96040830184615478565b949350505050565b60ff818116838216029081169081811461544557615445615205565b601f8211156116d957600081815260208120601f850160051c810160208610156156345750805b601f850160051c820191505b818110156136dc57828155600101615640565b67ffffffffffffffff83111561566b5761566b61517a565b61567f8361567983546153b1565b8361560d565b6000601f8411600181146156b3576000851561569b5750838201355b600019600387901b1c1916600186901b1783556137dd565b600083815260209020601f19861690835b828110156156e457868501358255602094850194600190920191016156c4565b50868210156157015760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006101208c83528b60208401528a60408401528960608401528860808401528760a084015286151560c084015285151560e0840152806101008401528381840152506101408385828501376000838501820152601f909301601f19169091019091019a9950505050505050505050565b60008251615796818460208701614f73565b9190910192915050565b6157aa81856155b5565b6060602082015260006154dc6060830185615478565b80820260008212600160ff1b841416156157dc576157dc615205565b818105831482151761183557611835615205565b6000826157ff576157ff61525e565b600160ff1b82146000198414161561581957615819615205565b500590565b60006145758383615301565b60ff818116838216019081111561183557611835615205565b805169ffffffffffffffffffff8116811461585d57600080fd5b919050565b600080600080600060a0868803121561587a57600080fd5b61588386615843565b94506020860151935060408601519250606086015191506158a660808701615843565b9050929550929590935056fea264697066735822122036dd9e7470219475513bedd465d9c9f75f829a107aff554b6ceb88bfc00acf7464736f6c6343000813003300000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000008fffffd4afb6115b954bd326cbe7b4ba576818f6000000000000000000000000a468570db143321bc034bbd74a6cc2694d15b2520000000000000000000000003afd8feed6bbd1d8254d92eafa1f695dce16387a000000000000000000000000000000000000000000000000000000000000001542616c616e636572204d61726b6574204d616b65720000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103d05760003560e01c80636b64c769116101ff578063bb3521201161011a578063de839ba4116100ad578063f69aa3d51161007c578063f69aa3d514610745578063f95c1b2614610758578063fa45d56214610765578063fbfa77cf1461077857600080fd5b8063de839ba41461070d578063ea8364aa14610716578063f3fef3a314610729578063f686138d1461073c57600080fd5b8063c5ebeaec116100e9578063c5ebeaec146106e0578063c6beb586146106f3578063d366a41f146106fc578063d6fbf2021461070457600080fd5b8063bb352120146106aa578063bc5477ad146106b3578063c0f4a005146106c6578063c198f8ba146106d857600080fd5b8063a195166511610192578063a71891c311610161578063a71891c31461067f578063ad81fced14610687578063b220a79b14610690578063ba2d0344146106a257600080fd5b8063a19516651461065d578063a38aaa9014610666578063a516ed021461066e578063a6a8f1f91461067657600080fd5b80638456cb59116101ce5780638456cb591461061c578063857620e1146106245780638d1d7c61146106375780639e1b00451461064a57600080fd5b80636b64c769146105e6578063717e794d146105ee5780637df1f1b9146105f65780638351faf51461060957600080fd5b806329b154c3116102ef5780633e0dc34e116102825780634dc415de116102515780634dc415de146105b85780635c975abb146105c057806361ab077f146105cb578063698996f8146105de57600080fd5b80633e0dc34e1461058b5780633f4ba83a14610594578063422f10431461059c57806348dcacab146105af57600080fd5b80633168b03f116102be5780633168b03f1461053557806335faa41614610548578063371fd8e61461056f57806339518b5e1461058257600080fd5b806329b154c3146104fe5780632a943945146105115780632d76643c14610519578063311176d71461052257600080fd5b806314a6bf0f11610367578063234439441161033657806323443944146104be57806325d9b792146104c657806329610252146104d95780632982db00146104e157600080fd5b806314a6bf0f1461047557806316f0115b1461047d5780631c4695f4146104ad5780631de01bc9146104b557600080fd5b80630f5e07c7116103a35780630f5e07c71461044357806312bec0021461044c57806312f21a1a146104595780631370720f1461046257600080fd5b8063050d6f78146103d557806306fdde03146103ea5780630a246871146104085780630e5f5dbd1461042d575b600080fd5b6103e86103e3366004614f51565b61078b565b005b6103f2610b38565b6040516103ff9190614fc3565b60405180910390f35b601a5461041b9062010000900460ff1681565b60405160ff90911681526020016103ff565b610435610bc6565b6040519081526020016103ff565b61043560095481565b601a5461041b9060ff1681565b610435600d5481565b6103e8610470366004614fd6565b610c31565b610435610e18565b6016546104959061010090046001600160a01b031681565b6040516001600160a01b0390911681526020016103ff565b6103f2610e34565b610435600a5481565b6103e8610e41565b6104956104d4366004614fd6565b610f2a565b6103e8610f54565b6016546104ee9060ff1681565b60405190151581526020016103ff565b6103e861050c366004614fd6565b61110d565b610495611189565b61043560075481565b600254610495906001600160a01b031681565b6103e8610543366004614fd6565b61120d565b6104957f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357481565b6103e861057d366004614fd6565b6112fb565b61043560125481565b61043560185481565b6103e8611320565b6103e86105aa366004614fef565b61147c565b610435600b5481565b6103e86116de565b60005460ff166104ee565b6104356105d9366004614f51565b6117da565b61043561183b565b6103e86118fb565b610435611992565b600554610495906001600160a01b031681565b6103e8610617366004614fef565b611a45565b6103e8611d32565b6103e8610632366004614fef565b611e8e565b600354610495906001600160a01b031681565b6103e8610658366004614f51565b61238b565b61043560105481565b6104ee612693565b6103e86126d9565b61043560155481565b61043561271c565b61043560085481565b601a5461041b90610100900460ff1681565b610435612950565b61043560145481565b6103e86106c1366004614fef565b612a0f565b6011546104ee90610100900460ff1681565b6103e8612df4565b6103e86106ee366004614fd6565b612e41565b61043560065481565b610435612f83565b61043560135481565b610435600c5481565b6103e8610724366004615072565b612f90565b6103e861073736600461514e565b61304f565b610435600f5481565b610435610753366004614f51565b6132c2565b6011546104ee9060ff1681565b6103e8610773366004614fd6565b61331d565b601754610495906001600160a01b031681565b6107936134e7565b600754604051633d1bb33160e21b8152306004820152600091906001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574169063f46eccc4906024016080604051808303816000875af1158015610800573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108249190615190565b5161082f919061521b565b905061083c83600261522e565b81101561085c5760405163569d45cf60e11b815260040160405180910390fd5b60006108e87f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663dc38679c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e39190615245565b613545565b90506000620f424062ffffff16827f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663e19538476040518163ffffffff1660e01b8152600401602060405180830381865afa158015610954573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109789190615245565b610982919061522e565b61098c9190615274565b6109969083615288565b905060007f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109f8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1c919061529b565b610a2790600a6153a2565b610a31838861522e565b610a3b9190615274565b600254909150610a56906001600160a01b03163330846135da565b600254601754610a73916001600160a01b039081169116836136e4565b601754610aab907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574906001600160a01b0316886136e4565b610abe610ab987600261522e565b6137e4565b610ac9818787613993565b610af47f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435743388613e38565b6040518181527f6e19477745f02fa64cb79e709afd8b6a5da159ef7b135546eafd67c38e425c439060200160405180910390a150505050610b3460018055565b5050565b60048054610b45906153b1565b80601f0160208091040260200160405190810160405280929190818152602001828054610b71906153b1565b8015610bbe5780601f10610b9357610100808354040283529160200191610bbe565b820191906000526020600020905b815481529060010190602001808311610ba157829003601f168201915b505050505081565b60075460009015610c2b57600062015180600d5442610be5919061521b565b610bef9190615274565b9050610c00620f424061016d61522e565b81600c54600754610c11919061522e565b610c1b919061522e565b610c259190615274565b91505090565b50600090565b610c39613f31565b610c41613f5c565b80610c4b81613fa2565b610c536134e7565b6000610c5e83613fc3565b604051633068b6b560e21b8152600481018290529091506000906001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574169063c1a2dad490602401602060405180830381865afa158015610cc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ced9190615245565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357416906370a0823190602401602060405180830381865afa158015610d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7b9190615245565b905080821115610d9e5760405163569d45cf60e11b815260040160405180910390fd5b600254610db6906001600160a01b03163330886135da565b610de17f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435743384613e38565b60405182907fbc87b68cd9f40bbab98db9b9e4d393c4ef32d4660271a908b81cfa10d8a59df990600090a2505050610b3460018055565b6000610e22610bc6565b600754610e2f9190615288565b905090565b600e8054610b45906153b1565b7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec391906153eb565b6001600160a01b0316336001600160a01b031614610ef45760405163698bba4b60e01b815260040160405180910390fd5b6000600b81905560098190556040517f219124ae95cc25cf220d998f2867d37fb4ab4908cce7c51adfa33ce747aa5747908290a2565b60198181548110610f3a57600080fd5b6000918252602090912001546001600160a01b0316905081565b610f5c613f31565b610f646134e7565b6000610f6e610bc6565b42600d556040516370a0823160e01b81523060048201529091506000907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316906370a0823190602401602060405180830381865afa158015610fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110009190615245565b905080821115611022576040516206230160eb1b815260040160405180910390fd5b8115611100576110d47f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435747f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ce91906153eb565b84613e38565b60405182907fda0ff68ccd5fb797a8f86207386ea961ca6990c15ace2424ab51eb871ed4959990600090a25b505061110b60018055565b565b336001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357416146111565760405163bc9eca6160e01b815260040160405180910390fd5b600781905560405181907f35ba42ee3c2daa6cf14836eefff16b184565798767ec1e5d723008848aeaf7e390600090a250565b60007f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316632a9439456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f91906153eb565b7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128f91906153eb565b6001600160a01b0316336001600160a01b0316146112c05760405163698bba4b60e01b815260040160405180910390fd5b60088190556040518181527f7760d892a7883522367f0eaea35e968381a018418c249cd9aaaca190fe5d88179060200160405180910390a150565b611303613f31565b61130b6134e7565b61131481614051565b61131d60018055565b50565b7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663baf4a3126040518163ffffffff1660e01b8152600401602060405180830381865afa15801561137e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a291906153eb565b6001600160a01b0316336001600160a01b03161415801561145657507f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144091906153eb565b6001600160a01b0316336001600160a01b031614155b1561147457604051631e1c735b60e21b815260040160405180910390fd5b61110b614303565b6114846134e7565b61148c613f31565b60003090507f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316632b4818836040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115139190615408565b156115f257604051633d1bb33160e21b81523060048201526000907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03169063f46eccc4906024016080604051808303816000875af1158015611581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a59190615190565b516007549091506000906115b9908361521b565b9050848110156115dc5760405163569d45cf60e11b815260040160405180910390fd5b84156115eb576115eb856137e4565b505061161e565b61161e7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435743383866135da565b600254611636906001600160a01b03163383876135da565b600254601754611653916001600160a01b039081169116866136e4565b60175461168b907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574906001600160a01b0316856136e4565b611696848484613993565b60408051858152602081018590527f38f8a0c92f4c5b0b6877f878cb4c0c8d348a47b76d716c8e78f425043df9515b910160405180910390a1506116d960018055565b505050565b7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561173c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176091906153eb565b6001600160a01b0316336001600160a01b03161461179157604051632d5be4cb60e21b815260040160405180910390fd5b6011805461ff0019166101001790556005546040516001600160a01b03909116907faf77f8960cf590e245ec8b6d41c193a5dcacad8986ae4eb57ac9e5be7b6af03190600090a2565b60006117e4613f31565b6117ec613f5c565b6117f46134e7565b6117fe8383614355565b60405190915081907f4e08ba899977cf7d4c2964bce71c6b9a7ef76ee5166a4c1249a1e08016e33ef190600090a261183560018055565b92915050565b6000807f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03166389da7df8611875610bc6565b6040518263ffffffff1660e01b815260040161189391815260200190565b602060405180830381865afa1580156118b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d49190615245565b9050806118df6144a4565b6118e761271c565b6118f19190615288565b610c25919061521b565b611903612693565b6119205760405163038cbd4b60e31b815260040160405180910390fd5b60165460ff16158061193457506000601354115b156119525760405163829e373360e01b815260040160405180910390fd5b4260125560065460009061196990620f424061521b565b905080620f4240611978610e18565b611982919061522e565b61198c9190615274565b60135550565b6000807f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03166389da7df86007546040518263ffffffff1660e01b81526004016119e591815260200190565b602060405180830381865afa158015611a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a269190615245565b90506000611a3261183b565b9050611a3e8282615425565b9250505090565b611a4d6134e7565b7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611acf91906153eb565b6001600160a01b0316336001600160a01b031614611b005760405163698bba4b60e01b815260040160405180910390fd5b604051633d1bb33160e21b81523060048201526000907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03169063f46eccc4906024016080604051808303816000875af1158015611b69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8d9190615190565b51600754909150600090611ba1908361521b565b9050611bad8582614564565b94506000611bbc86600061457c565b60115490915060ff16611be2576040516305b02a1960e01b815260040160405180910390fd5b601054861015611c05576040516312cd610d60e21b815260040160405180910390fd5b600f54811215611c28576040516378764b0f60e01b815260040160405180910390fd5b611c31866137e4565b6000611ccc867f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb9919061529b565b611cc490600a6153a2565b899190614740565b90506000611cd982613545565b90506000611ce782886147ee565b90506000611cf58a83614812565b90506040518a907f8f77e6a87a8210bff9857b08990b1f360b73d6e92d422a9a0e2c78e449682a9c90600090a2505050505050506116d960018055565b7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663baf4a3126040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db491906153eb565b6001600160a01b0316336001600160a01b031614158015611e6857507f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5291906153eb565b6001600160a01b0316336001600160a01b031614155b15611e8657604051631e1c735b60e21b815260040160405180910390fd5b61110b614947565b611e966134e7565b611e9e613f31565b6002546040805163313ce56760e01b8152905130926000926001600160a01b039091169163313ce567916004808201926020929091908290030181865afa158015611eed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f11919061529b565b611f1c90600a6153a2565b601654600254604051632a6f500560e11b81526001600160a01b03918216600482015261010090920416906354dea00a90602401602060405180830381865afa158015611f6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f919190615245565b611f9b908761522e565b611fa59190615274565b905060007f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202b919061529b565b61203690600a6153a2565b601654604051632a6f500560e11b81526001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357481166004830152610100909204909116906354dea00a90602401602060405180830381865afa1580156120a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ca9190615245565b6120d4908761522e565b6120de9190615274565b90506000620f42406120f08682615288565b6120fa8486615288565b612104919061522e565b61210e9190615274565b60408051600380825260808201909252919250600091906020820160608036833701905050601a54815191925089918391610100900460ff169081106121565761215661544c565b6020908102919091010152601a5481518891839160ff90911690811061217e5761217e61544c565b60209081029190910101526040805160028082526060820190925260009181602001602082028036833701905050601a5490915060ff610100820481169116116121c857876121ca565b885b816000815181106121dd576121dd61544c565b6020908102919091010152601a5460ff610100820481169116116122015788612203565b875b816001815181106122165761221661544c565b60200260200101818152505060006001828560405160200161223a939291906154b3565b60408051601f198184030181526019805460a06020820286018101909452608085018181529295506000949384939291908401828280156122a457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612286575b505050918352505060208101869052604080820185905260006060909201919091526017546018549151638bdb391360e01b81529293506001600160a01b031691638bdb3913916122fd918c9081908790600401615583565b600060405180830381600087803b15801561231757600080fd5b505af115801561232b573d6000803e3d6000fd5b5050505060008a1115612341576123418a614051565b604080518c8152602081018c90527f6f0f96292ae0038c04f9b6bab30f185d9ca02c471d0983f563f2a4f674aef137910160405180910390a150505050505050506116d960018055565b6123936134e7565b61239b613f31565b60003090507f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316632b4818836040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124229190615408565b1561243557612430826137e4565b612461565b6124617f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435743383856135da565b600254612479906001600160a01b03163383866135da565b600254601754612496916001600160a01b039081169116856136e4565b6017546124ce907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574906001600160a01b0316846136e4565b604080516003808252608082019092526000916020820160608036833701905050601a548151919250600160701b91839162010000900460ff169081106125175761251761544c565b6020026020010181815250508381601a60019054906101000a900460ff1660ff16815181106125485761254861544c565b6020908102919091010152601a5481518491839160ff9091169081106125705761257061544c565b602002602001018181525050600080826040516020016125919291906155c9565b60408051601f198184030181526019805460a06020820286018101909452608085018181529295506000949384939291908401828280156125fb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116125dd575b50505091835250506020810185905260408082018590526000606090920191909152601754601854915163172b958560e31b81529293506001600160a01b03169163b95cac289161265491889081908790600401615583565b600060405180830381600087803b15801561266e57600080fd5b505af1158015612682573d6000803e3d6000fd5b5050505050505050610b3460018055565b600080600a541180156126a857506000600b54115b80156126b5575060095442115b80610e2f57506000600754118015610e2f57506006546126d3612f83565b12905090565b6126e16134e7565b601254600003612704576040516334dc687f60e11b815260040160405180910390fd5b600061270e612950565b905060006111008183614984565b6016546040516370a0823160e01b815230600482015260009182916101009091046001600160a01b0316906370a0823190602401602060405180830381865afa15801561276d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127919190615245565b90506000601660019054906101000a90046001600160a01b03166001600160a01b031663679aefce6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280c9190615245565b90506000601660019054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612863573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612887919061529b565b6128929060026155f1565b61289d90600a6153a2565b600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612914919061529b565b61291f90600a6153a2565b612929848661522e565b612933919061522e565b61293d9190615274565b905061294881613fc3565b935050505090565b600080620f4240601554620f4240612968919061521b565b600754612975919061522e565b61297f9190615274565b9050600061012c60125442612994919061521b565b61299e9190615274565b90506000601454826129b0919061522e565b9050620f42408111156129c557509092915050565b60006129d482620f424061521b565b90506000620f4240826013546129ea919061522e565b6129f49190615274565b9050808511612a035780612a05565b845b9550505050505090565b612a176134e7565b7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663e563037e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9991906153eb565b6001600160a01b0316336001600160a01b031614612aca5760405163698bba4b60e01b815260040160405180910390fd5b600080612ad5614bb8565b915091506000612af06007548761456490919063ffffffff16565b600a5490915015612b1157600a54612b089042615288565b600955600b8190555b80821015612d17576000612b25838361521b565b60405163113b4fbf60e31b8152600481018290529091506000906001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357416906389da7df890602401602060405180830381865afa158015612b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb49190615245565b90506000612bc182613545565b905085811115612bda57612bd8610c2b878361521b565b505b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612c23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c479190615245565b1115612d13576000612c5882613fc3565b90506000612cf47f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ce1919061529b565b612cec90600a6153a2565b83908c614740565b90506000612d02828b6147ee565b9050612d0e8482614355565b505050505b5050505b6040516370a0823160e01b81523060048201526000907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316906370a0823190602401602060405180830381865afa158015612d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da29190615245565b118015612daf5750600081115b15612dbd57612dbd81614051565b60405186907fdfcd68ceed46252749a4089f344aec4b4ee7f28a068f704c21799355325f3da990600090a25050506116d960018055565b612dfc613f31565b6011805461ff00191690556005546040516001600160a01b03909116907facf29ad8d63913d38e7e1176963a4afb76bf0918516051da68408ecb6f98065d90600090a2565b612e49613f31565b612e51613f5c565b80612e5b81613fa2565b612e636134e7565b60405163b67e9df760e01b81523060048201527f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03169063b67e9df790602401602060405180830381865afa158015612ec7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eeb9190615408565b612f085760405163d8d5894f60e01b815260040160405180910390fd5b6000600754600854612f1a919061521b565b905082811015612f3d5760405163569d45cf60e11b815260040160405180910390fd5b6000612f4a84600061457c565b9050600654811215612f6f5760405163374c72ff60e11b815260040160405180910390fd5b612f78846137e4565b5050610b3460018055565b6000610e2f60008061457c565b612f98613f31565b612fa0614cba565b60068c9055600c8b905560088a90556014899055600a889055600f879055601086905560158590556011805460ff199081168615151790915560168054909116841515179055600e612ff3828483615653565b508a8c7fed1352796b02006c8bf7ef68956cb9fc55c08f9193eee9cec7ee590840bbbaad8c6014548c8c8c8c8c8c8c8c6040516130399a99989796959493929190615713565b60405180910390a3505050505050505050505050565b613057613f31565b61305f613f5c565b8061306981613fa2565b6130716134e7565b6040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa1580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d99190615245565b8211156130f95760405163569d45cf60e11b815260040160405180910390fd5b60075415613278577f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316836001600160a01b03161415801561315157506002546001600160a01b03848116911614155b1561316f5760405163c1ab6dc160e01b815260040160405180910390fd5b60007f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316846001600160a01b0316146131b8576131b383613fc3565b613241565b60405163113b4fbf60e31b8152600481018490527f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316906389da7df890602401602060405180830381865afa15801561321d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132419190615245565b9050600061325060008361457c565b90506006548112156132755760405163374c72ff60e11b815260040160405180910390fd5b50505b613283833384613e38565b60405182906001600160a01b038516907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d590600090a36116d960018055565b60006132cc613f31565b6132d4613f5c565b6132dc6134e7565b6132e68383614812565b60405190915083907f92f64ca637d023f354075a4be751b169c1a8a9ccb6d33cdd0cb352054399572790600090a261183560018055565b613325613f31565b61332d613f5c565b8061333781613fa2565b61333f6134e7565b60405163113b4fbf60e31b8152600481018390526000907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316906389da7df890602401602060405180830381865afa1580156133a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133cb9190615245565b905060006133d882613545565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa158015613426573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344a9190615245565b90508082111561346d5760405163569d45cf60e11b815260040160405180910390fd5b6134997f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435743330886135da565b6002546134b0906001600160a01b03163384613e38565b60405182907fdcadafc28aac48a048c875f5f3127f2189b02d21291b563568cf8892a596bbb090600090a2505050610b3460018055565b60026001540361353e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600155565b600061183582600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561359e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c2919061529b565b60035460ff91909116906001600160a01b0316614ce2565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161363e9190615784565b6000604051808303816000865af19150503d806000811461367b576040519150601f19603f3d011682016040523d82523d6000602084013e613680565b606091505b50915091508180156136aa5750805115806136aa5750808060200190518101906136aa9190615408565b6136dc5760405162461bcd60e51b815260206004820152600360248201526229aa2360e91b6044820152606401613535565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916137409190615784565b6000604051808303816000865af19150503d806000811461377d576040519150601f19603f3d011682016040523d82523d6000602084013e613782565b606091505b50915091508180156137ac5750805115806137ac5750808060200190518101906137ac9190615408565b6137dd5760405162461bcd60e51b8152602060048201526002602482015261534160f01b6044820152606401613535565b5050505050565b60006137ee610bc6565b60405163140e25ad60e31b8152600481018490529091507f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03169063a0712d6890602401600060405180830381600087803b15801561385357600080fd5b505af1158015613867573d6000803e3d6000fd5b50505050816007600082825461387d9190615288565b909155505042600d558015613964576139387f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435747f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561390e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061393291906153eb565b83613e38565b60405181907fda0ff68ccd5fb797a8f86207386ea961ca6990c15ace2424ab51eb871ed4959990600090a25b60405182907f69c0ed5a77051ba5f0c42418bb6db6d3f73884dea69811c50bf320298df6ca5c90600090a25050565b604080516003808252608082019092523091600091906020820160608036833701905050601a54815191925086918391610100900460ff169081106139da576139da61544c565b6020908102919091010152601a5481518591839160ff909116908110613a0257613a0261544c565b60209081029190910101526040805160028082526060820190925260009181602001602082028036833701905050601a5490915060ff61010082048116911611613a4c5784613a4e565b855b81600081518110613a6157613a6161544c565b6020908102919091010152601a5460ff61010082048116911611613a855785613a87565b845b81600181518110613a9a57613a9a61544c565b6020026020010181815250506000600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613afb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b1f919061529b565b613b2a90600a6153a2565b601654600254604051632a6f500560e11b81526001600160a01b03918216600482015261010090920416906354dea00a90602401602060405180830381865afa158015613b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9f9190615245565b613ba9908961522e565b613bb39190615274565b905060007f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c39919061529b565b613c4490600a6153a2565b601654604051632a6f500560e11b81526001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357481166004830152610100909204909116906354dea00a90602401602060405180830381865afa158015613cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd89190615245565b613ce2908961522e565b613cec9190615274565b90506000620f4240613cfe888261521b565b613d088486615288565b613d12919061522e565b613d1c9190615274565b9050600060018583604051602001613d36939291906157a0565b60408051601f198184030181526019805460a0602082028601810190945260808501818152929550600094938493929190840182828015613da057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d82575b50505091835250506020810189905260408082018590526000606090920191909152601754601854915163172b958560e31b81529293506001600160a01b03169163b95cac2891613df9918c9081908790600401615583565b600060405180830381600087803b158015613e1357600080fd5b505af1158015613e27573d6000803e3d6000fd5b505050505050505050505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691613e949190615784565b6000604051808303816000865af19150503d8060008114613ed1576040519150601f19603f3d011682016040523d82523d6000602084013e613ed6565b606091505b5091509150818015613f00575080511580613f00575080806020019051810190613f009190615408565b6137dd5760405162461bcd60e51b815260206004820152600260248201526114d560f21b6044820152606401613535565b6005546001600160a01b0316331461110b57604051631963d1e760e31b815260040160405180910390fd5b60005460ff161561110b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401613535565b8060000361131d57604051639d635cff60e01b815260040160405180910390fd5b600061183582600260009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561401c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614040919061529b565b6003546001600160a01b0316614d3f565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316906370a0823190602401602060405180830381865afa1580156140b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140dc9190615245565b90506140e88282614564565b91508160000361410b5760405163569d45cf60e11b815260040160405180910390fd5b81600b541161411b576000614129565b81600b54614129919061521b565b600b55600a541580159061413d5750600b54155b156141485760006009555b6000614152610bc6565b42600d559050614162818461521b565b925082600754101561417e576007805460009091559250614196565b8260076000828254614190919061521b565b90915550505b6142187f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435747f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561390e573d6000803e3d6000fd5b6142437f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357430856136e4565b604051630852cd8d60e31b8152600481018490527f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316906342966c6890602401600060405180830381600087803b1580156142a557600080fd5b505af11580156142b9573d6000803e3d6000fd5b50506040518592507f33a382daad6aace935340a474d09fec82af4bec7e2b69518d283231b03a65f249150600090a26142f0612693565b6116d9576116d960006012819055601355565b61430b614d8f565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6002546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156143a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143c69190615245565b90506143d28482614564565b9350836000036143f55760405163569d45cf60e11b815260040160405180910390fd5b60006143ff611189565b600254909150614419906001600160a01b031682876136e4565b60025460405163231831c760e21b81526001600160a01b0391821660048201526024810187905260448101869052600091831690638c60c71c906064015b6020604051808303816000875af1158015614476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061449a9190615245565b9695505050505050565b60008060006144b1614bb8565b60405163113b4fbf60e31b81526004810182905291935091506000906001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357416906389da7df890602401602060405180830381865afa15801561451e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145429190615245565b9050600061454f84613fc3565b905061455b8282615288565b94505050505090565b60008183106145735781614575565b825b9392505050565b60008061458761183b565b60405163113b4fbf60e31b8152600481018690529091506000906001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357416906389da7df890602401602060405180830381865afa1580156145f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146169190615245565b90506000846146258385615288565b61462f919061521b565b90508060000361465c576007541561465057620f423f199350505050611835565b60009350505050611835565b60007f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b03166389da7df88860075461469b9190615288565b6040518263ffffffff1660e01b81526004016146b991815260200190565b602060405180830381865afa1580156146d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146fa9190615245565b90506000826147098382615425565b61471690620f42406157c0565b61472091906157f0565b9050620f423f198112156147355750620f423f195b979650505050505050565b600080806000198587098587029250828110838203039150508060000361477a578382816147705761477061525e565b0492505050614575565b80841161478657600080fd5b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b6000620f42406147fe838261521b565b614808908561522e565b6145759190615274565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357416906370a0823190602401602060405180830381865afa15801561487b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061489f9190615245565b90506148ab8482614564565b9350836000036148ce5760405163569d45cf60e11b815260040160405180910390fd5b60006148d8611189565b90506149057f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357482876136e4565b600254604051631c6d209760e11b81526001600160a01b03918216600482015260248101879052604481018690526000918316906338da412e90606401614457565b61494f613f5c565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586143383390565b61498c612693565b6149a95760405163038cbd4b60e31b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201819052916000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156149f7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a1b9190615245565b6040516370a0823160e01b81526001600160a01b0384811660048301529192506000918616906370a0823190602401602060405180830381865afa158015614a67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a8b9190615245565b6040516370a0823160e01b81526001600160a01b0385811660048301529192506000917f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d4357416906370a0823190602401602060405180830381865afa158015614af7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b1b9190615245565b905080851115614b5a57614b5a7f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435743386614b55858a61521b565b6135da565b600254614b71906001600160a01b03163385613e38565b614b7c863384613e38565b614b8585614051565b60405133907f1e1ef858062a7196d1891e397a5cde9891e6ddf61a81e9d269a3aaa7a95dacd890600090a2505050505050565b6002546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa158015614c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c299190615245565b6040516370a0823160e01b81523060048201529092507f000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d435746001600160a01b0316906370a0823190602401602060405180830381865afa158015614c90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cb49190615245565b90509091565b601154610100900460ff1661110b57604051634e751a9560e11b815260040160405180910390fd5b600080614cee83614dd8565b90506000614cfb84614e3c565b9050614d096006600a6153a2565b614d13908261522e565b614d208660ff8516615288565b614d2b90600a61581e565b614d35908861522e565b61449a9190615274565b600080614d4b83614dd8565b90506000614d5884614e3c565b9050614d64858361582a565b614d6f90600a6153a2565b614d7b6006600a6153a2565b614d85838961522e565b614d35919061522e565b60005460ff1661110b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401613535565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611835919061529b565b6000806000806000856001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015614e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ea69190615862565b9450945050935093508369ffffffffffffffffffff168169ffffffffffffffffffff161015614f025760405162461bcd60e51b81526020600482015260086024820152674f6c64206461746160c01b6044820152606401613535565b60008211614f475760405162461bcd60e51b8152602060048201526012602482015271526f756e64206e6f7420636f6d706c65746560701b6044820152606401613535565b5090949350505050565b60008060408385031215614f6457600080fd5b50508035926020909101359150565b60005b83811015614f8e578181015183820152602001614f76565b50506000910152565b60008151808452614faf816020860160208601614f73565b601f01601f19169290920160200192915050565b6020815260006145756020830184614f97565b600060208284031215614fe857600080fd5b5035919050565b60008060006060848603121561500457600080fd5b505081359360208301359350604090920135919050565b801515811461131d57600080fd5b60008083601f84011261503b57600080fd5b50813567ffffffffffffffff81111561505357600080fd5b60208301915083602082850101111561506b57600080fd5b9250929050565b6000806000806000806000806000806000806101608d8f03121561509557600080fd5b8c359b5060208d01359a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d0135955060e08d013594506150d86101008e013561501b565b6101008d013593506150ee6101208e013561501b565b6101208d0135925067ffffffffffffffff6101408e0135111561511057600080fd5b6151218e6101408f01358f01615029565b81935080925050509295989b509295989b509295989b565b6001600160a01b038116811461131d57600080fd5b6000806040838503121561516157600080fd5b823561516c81615139565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b6000608082840312156151a257600080fd5b6040516080810181811067ffffffffffffffff821117156151c5576151c561517a565b8060405250825181526020830151602082015260408301516151e68161501b565b604082015260608301516151f98161501b565b60608201529392505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561183557611835615205565b808202811582820484141761183557611835615205565b60006020828403121561525757600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b6000826152835761528361525e565b500490565b8082018082111561183557611835615205565b6000602082840312156152ad57600080fd5b815160ff8116811461457557600080fd5b600181815b808511156152f95781600019048211156152df576152df615205565b808516156152ec57918102915b93841c93908002906152c3565b509250929050565b60008261531057506001611835565b8161531d57506000611835565b8160018114615333576002811461533d57615359565b6001915050611835565b60ff84111561534e5761534e615205565b50506001821b611835565b5060208310610133831016604e8410600b841016171561537c575081810a611835565b61538683836152be565b806000190482111561539a5761539a615205565b029392505050565b600061457560ff841683615301565b600181811c908216806153c557607f821691505b6020821081036153e557634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156153fd57600080fd5b815161457581615139565b60006020828403121561541a57600080fd5b81516145758161501b565b818103600083128015838313168383128216171561544557615445615205565b5092915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b600081518084526020808501945080840160005b838110156154a85781518752958201959082019060010161548c565b509495945050505050565b6000600385106154c5576154c5615462565b848252606060208301526154dc6060830185615478565b9050826040830152949350505050565b8051608080845281519084018190526000916020919082019060a0860190845b818110156155315783516001600160a01b03168352928401929184019160010161550c565b50508285015191508581038387015261554a8183615478565b92505050604083015184820360408601526155658282614f97565b915050606083015161557b606086018215159052565b509392505050565b8481526001600160a01b0384811660208301528316604082015260806060820181905260009061449a908301846154ec565b600481106155c5576155c5615462565b9052565b6155d381846155b5565b6040602082015260006155e96040830184615478565b949350505050565b60ff818116838216029081169081811461544557615445615205565b601f8211156116d957600081815260208120601f850160051c810160208610156156345750805b601f850160051c820191505b818110156136dc57828155600101615640565b67ffffffffffffffff83111561566b5761566b61517a565b61567f8361567983546153b1565b8361560d565b6000601f8411600181146156b3576000851561569b5750838201355b600019600387901b1c1916600186901b1783556137dd565b600083815260209020601f19861690835b828110156156e457868501358255602094850194600190920191016156c4565b50868210156157015760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006101208c83528b60208401528a60408401528960608401528860808401528760a084015286151560c084015285151560e0840152806101008401528381840152506101408385828501376000838501820152601f909301601f19169091019091019a9950505050505050505050565b60008251615796818460208701614f73565b9190910192915050565b6157aa81856155b5565b6060602082015260006154dc6060830185615478565b80820260008212600160ff1b841416156157dc576157dc615205565b818105831482151761183557611835615205565b6000826157ff576157ff61525e565b600160ff1b82146000198414161561581957615819615205565b500590565b60006145758383615301565b60ff818116838216019081111561183557611835615205565b805169ffffffffffffffffffff8116811461585d57600080fd5b919050565b600080600080600060a0868803121561587a57600080fd5b61588386615843565b94506020860151935060408601519250606086015191506158a660808701615843565b9050929550929590935056fea264697066735822122036dd9e7470219475513bedd465d9c9f75f829a107aff554b6ceb88bfc00acf7464736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000008fffffd4afb6115b954bd326cbe7b4ba576818f6000000000000000000000000a468570db143321bc034bbd74a6cc2694d15b2520000000000000000000000003afd8feed6bbd1d8254d92eafa1f695dce16387a000000000000000000000000000000000000000000000000000000000000001542616c616e636572204d61726b6574204d616b65720000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Balancer Market Maker
Arg [1] : _sweep (address): 0xB88a5Ac00917a02d82c7cd6CEBd73E2852d43574
Arg [2] : _usdx (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [3] : _oracleUsdx (address): 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6
Arg [4] : _poolAddress (address): 0xa468570dB143321Bc034BbD74A6Cc2694d15B252
Arg [5] : _borrower (address): 0x3afd8feED6Bbd1D8254d92eAFA1F695Dce16387a
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 000000000000000000000000b88a5ac00917a02d82c7cd6cebd73e2852d43574
Arg [2] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [3] : 0000000000000000000000008fffffd4afb6115b954bd326cbe7b4ba576818f6
Arg [4] : 000000000000000000000000a468570db143321bc034bbd74a6cc2694d15b252
Arg [5] : 0000000000000000000000003afd8feed6bbd1d8254d92eafa1f695dce16387a
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [7] : 42616c616e636572204d61726b6574204d616b65720000000000000000000000
Deployed Bytecode Sourcemap
585:7714:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2634:974;;;;;;:::i;:::-;;:::i;:::-;;1101:18:13;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1054:21:0;;;;;;;;;;;;;;;1195:4:15;1183:17;;;1165:36;;1153:2;1138:18;1054:21:0;1023:184:15;5438:315:13;;;:::i;:::-;;;1358:25:15;;;1346:2;1331:18;5438:315:13;1212:177:15;1290:23:13;;;;;;995::0;;;;;;;;;1444:25:13;;;;;;18300:662;;;;;;:::i;:::-;;:::i;5894:101::-;;;:::i;864:25:0:-;;;;;;;;-1:-1:-1;;;;;864:25:0;;;;;;-1:-1:-1;;;;;1765:32:15;;;1747:51;;1735:2;1720:18;864:25:0;1579:225:15;1475:18:13;;;:::i;1319:24::-;;;;;;15455:190;;;:::i;960:26:0:-;;;;;;:::i;:::-;;:::i;12416:509:13:-;;;:::i;1837:26::-;;;;;;;;;;;;2293:14:15;;2286:22;2268:41;;2256:2;2241:18;1837:26:13;2128:187:15;13360:198:13;;;;;;:::i;:::-;;:::i;6496:91::-;;;:::i;1225:28::-;;;;;;1017:26;;;;;-1:-1:-1;;;;;1017:26:13;;;13065:206;;;;;;:::i;:::-;;:::i;302:29:10:-;;;;;12241:107:13;;;;;;:::i;:::-;;:::i;1663:27::-;;;;;;932:21:0;;;;;;7897:73:13;;;:::i;5779:966:0:-;;;;;;:::i;:::-;;:::i;1367:25:13:-;;;;;;11109:108;;;:::i;1608:84:11:-;1655:4;1678:7;;;1608:84;;17161:306:13;;;;;;:::i;:::-;;:::i;1956:211:0:-;;;:::i;21053:334:13:-;;;:::i;6705:253::-;;;:::i;1125:23::-;;;;;-1:-1:-1;;;;;1125:23:13;;;15775:1084;;;;;;:::i;:::-;;:::i;7745:69::-;;;:::i;6753:1239:0:-;;;;;;:::i;:::-;;:::i;1049:28:13:-;;;;;-1:-1:-1;;;;;1049:28:13;;;3616:1023:0;;;;;;:::i;:::-;;:::i;1553:34:13:-;;;;;;4760:221;;;:::i;21504:::-;;;:::i;1780:34::-;;;;;;2273:310:0;;;:::i;1259:24:13:-;;;;;;1025:22:0;;;;;;;;;;;;7094:528:13;;;:::i;1730:29::-;;;;;;13812:1452;;;;;;:::i;:::-;;:::i;1629:27::-;;;;;;;;;;;;10757:115;;;:::i;11462:565::-;;;;;;:::i;:::-;;:::i;1154:28::-;;;;;;5161:106;;;:::i;1696:28::-;;;;;;1399:24;;;;;;9281:1228;;;;;;:::i;:::-;;:::i;20120:832::-;;;;;;:::i;:::-;;:::i;1500:32::-;;;;;;17745:306;;;;;;:::i;:::-;;:::i;1593:29::-;;;;;;;;;19186:702;;;;;;:::i;:::-;;:::i;896:27:0:-;;;;;-1:-1:-1;;;;;896:27:0;;;2634:974;2261:21:12;:19;:21::i;:::-;2790:13:0::1;::::0;2749:28:::1;::::0;-1:-1:-1;;;2749:28:0;;2771:4:::1;2749:28;::::0;::::1;1747:51:15::0;2724:22:0::1;::::0;2790:13;-1:-1:-1;;;;;2749:5:0::1;:13;::::0;::::1;::::0;1720:18:15;;2749:28:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38:::0;:54:::1;::::0;;::::1;:::i;:::-;2724:79:::0;-1:-1:-1;2835:13:0::1;:11:::0;2847:1:::1;2835:13;:::i;:::-;2818:14;:30;2814:61;;;2857:18;;-1:-1:-1::0;;;2857:18:0::1;;;;;;;;;;;2814:61;2888:19;2910:37;2927:5;-1:-1:-1::0;;;;;2927:17:0::1;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2910:16;:37::i;:::-;2888:59;;2958:16;1124:3;2992:45;;3013:11;2993:5;-1:-1:-1::0;;;;;2993:15:0::1;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:31;;;;:::i;:::-;2992:45;;;;:::i;:::-;2977:61;::::0;:11;:61:::1;:::i;:::-;2958:80;;3049:18;3104:5;-1:-1:-1::0;;;;;3104:14:0::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3098:22;::::0;:2:::1;:22;:::i;:::-;3071;3085:8:::0;3071:11;:22:::1;:::i;:::-;3070:51;;;;:::i;:::-;3174:4;::::0;3049:72;;-1:-1:-1;3134:85:0::1;::::0;-1:-1:-1;;;;;3174:4:0::1;3181:10;3201:4;3049:72:::0;3134:31:::1;:85::i;:::-;3265:4;::::0;3280:5:::1;::::0;3230:69:::1;::::0;-1:-1:-1;;;;;3265:4:0;;::::1;::::0;3280:5:::1;3288:10:::0;3230:26:::1;:69::i;:::-;3361:5;::::0;3310:71:::1;::::0;3345:5:::1;::::0;-1:-1:-1;;;;;3361:5:0::1;3369:11:::0;3310:26:::1;:71::i;:::-;3394:22;3402:13;:11:::0;3414:1:::1;3402:13;:::i;:::-;3394:7;:22::i;:::-;3429:48;3443:10;3455:11;3468:8;3429:13;:48::i;:::-;3490:68;3526:5;3534:10;3546:11;3490:27;:68::i;:::-;3574:26;::::0;1358:25:15;;;3574:26:0::1;::::0;1346:2:15;1331:18;3574:26:0::1;;;;;;;2713:895;;;;2303:20:12::0;1716:1;2809:22;;2629:209;2303:20;2634:974:0;;:::o;1101:18:13:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5438:315::-;5504:13;;5481:7;;5504:17;5500:228;;5537:14;1949:12;5573:10;;5555:15;:28;;;;:::i;:::-;5554:44;;;;:::i;:::-;5537:61;-1:-1:-1;5691:25:13;2088:3;2026;5691:25;:::i;:::-;5664:6;5652:9;;5636:13;;:25;;;;:::i;:::-;:34;;;;:::i;:::-;5635:82;;;;:::i;:::-;5612:105;;;5438:315;:::o;5500:228::-;-1:-1:-1;5745:1:13;;5438:315::o;18300:662::-;3991:15;:13;:15::i;:::-;1232:19:11::1;:17;:19::i;:::-;18407:10:13::2;4164:20;4177:6;4164:12;:20::i;:::-;2261:21:12::3;:19;:21::i;:::-;18442:17:13::4;18462:28;18479:10;18462:16;:28::i;:::-;18522:31;::::0;-1:-1:-1;;;18522:31:13;;::::4;::::0;::::4;1358:25:15::0;;;18442:48:13;;-1:-1:-1;18500:19:13::4;::::0;-1:-1:-1;;;;;18522:5:13::4;:20;::::0;::::4;::::0;1331:18:15;;18522:31:13::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18586:30;::::0;-1:-1:-1;;;18586:30:13;;18610:4:::4;18586:30;::::0;::::4;1747:51:15::0;18500:53:13;;-1:-1:-1;18563:20:13::4;::::0;-1:-1:-1;;;;;18586:5:13::4;:15;::::0;::::4;::::0;1720:18:15;;18586:30:13::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18563:53;;18644:12;18630:11;:26;18626:57;;;18665:18;;-1:-1:-1::0;;;18665:18:13::4;;;;;;;;;;;18626:57;18747:4;::::0;18694:143:::4;::::0;-1:-1:-1;;;;;18747:4:13::4;18766:10;18798:4;18817:10:::0;18694:31:::4;:143::i;:::-;18847:68;18883:5;18891:10;18903:11;18847:27;:68::i;:::-;18931:24;::::0;18943:11;;18931:24:::4;::::0;;;::::4;18432:530;;;2303:20:12::3;1716:1:::0;2809:22;;2629:209;5894:101:13;5934:7;5976:12;:10;:12::i;:::-;5960:13;;:28;;;;:::i;:::-;5953:35;;5894:101;:::o;1475:18::-;;;;;;;:::i;15455:190::-;15514:5;-1:-1:-1;;;;;15514:14:13;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;15500:30:13;:10;-1:-1:-1;;;;;15500:30:13;;15496:56;;15539:13;;-1:-1:-1;;;15539:13:13;;;;;;;;;;;15496:56;15575:1;15562:10;:14;;;15586:8;:12;;;15613:25;;;;15575:1;;15613:25;15455:190::o;960:26:0:-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;960:26:0;;-1:-1:-1;960:26:0;:::o;12416:509:13:-;3991:15;:13;:15::i;:::-;2261:21:12::1;:19;:21::i;:::-;12479:20:13::2;12502:12;:10;:12::i;:::-;12537:15;12524:10;:28:::0;12586:30:::2;::::0;-1:-1:-1;;;12586:30:13;;12610:4:::2;12586:30;::::0;::::2;1747:51:15::0;12479:35:13;;-1:-1:-1;12563:20:13::2;::::0;12586:5:::2;-1:-1:-1::0;;;;;12586:15:13::2;::::0;::::2;::::0;1720:18:15;;12586:30:13::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12563:53;;12646:12;12631;:27;12627:57;;;12667:17;;-1:-1:-1::0;;;12667:17:13::2;;;;;;;;;;;12627:57;12699:16:::0;;12695:224:::2;;12731:137;12784:5;12808;-1:-1:-1::0;;;;;12808:14:13::2;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12842:12;12731:27;:137::i;:::-;12888:20;::::0;12895:12;;12888:20:::2;::::0;;;::::2;12695:224;12469:456;;2303:20:12::1;1716:1:::0;2809:22;;2629:209;2303:20:::1;12416:509:13:o:0;13360:198::-;13428:10;-1:-1:-1;;;;;13450:5:13;13428:28;;13424:51;;13465:10;;-1:-1:-1;;;13465:10:13;;;;;;;;;;;13424:51;13485:13;:22;;;13523:28;;13501:6;;13523:28;;;;;13360:198;:::o;6496:91::-;6540:4;6568:5;-1:-1:-1;;;;;6568:9:13;;:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;13065:206::-;13146:5;-1:-1:-1;;;;;13146:14:13;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;13132:30:13;:10;-1:-1:-1;;;;;13132:30:13;;13128:56;;13171:13;;-1:-1:-1;;;13171:13:13;;;;;;;;;;;13128:56;13194:9;:24;;;13234:30;;1358:25:15;;;13234:30:13;;1346:2:15;1331:18;13234:30:13;;;;;;;13065:206;:::o;12241:107::-;3991:15;:13;:15::i;:::-;2261:21:12::1;:19;:21::i;:::-;12322:19:13::2;12329:11;12322:6;:19::i;:::-;2303:20:12::1;1716:1:::0;2809:22;;2629:209;2303:20:::1;12241:107:13::0;:::o;7897:73::-;745:5:10;-1:-1:-1;;;;;745:18:10;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;731:34:10;:10;-1:-1:-1;;;;;731:34:10;;;:65;;;;;783:5;-1:-1:-1;;;;;783:11:10;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;769:27:10;:10;-1:-1:-1;;;;;769:27:10;;;731:65;727:108;;;817:18;;-1:-1:-1;;;817:18:10;;;;;;;;;;;727:108;7953:10:13::1;:8;:10::i;5779:966:0:-:0;2261:21:12;:19;:21::i;:::-;3991:15:13::1;:13;:15::i;:::-;5906:12:0::2;5929:4;5906:28;;5950:5;-1:-1:-1::0;;;;;5950:22:0::2;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5947:420;;;6011:28;::::0;-1:-1:-1;;;6011:28:0;;6033:4:::2;6011:28;::::0;::::2;1747:51:15::0;5990:18:0::2;::::0;6011:5:::2;-1:-1:-1::0;;;;;6011:13:0::2;::::0;::::2;::::0;1720:18:15;;6011:28:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38:::0;6102:13:::2;::::0;6011:38;;-1:-1:-1;6011:38:0::2;::::0;6089:26:::2;::::0;6011:38;6089:26:::2;:::i;:::-;6064:51;;6151:11;6134:14;:28;6130:59;;;6171:18;;-1:-1:-1::0;;;6171:18:0::2;;;;;;;;;;;6130:59;6207:15:::0;;6204:40:::2;;6224:20;6232:11;6224:7;:20::i;:::-;5975:281;;5947:420;;;6277:78;6317:5;6325:10;6337:4;6343:11;6277:31;:78::i;:::-;6419:4;::::0;6379:76:::2;::::0;-1:-1:-1;;;;;6419:4:0::2;6426:10;6438:4:::0;6444:10;6379:31:::2;:76::i;:::-;6503:4;::::0;6518:5:::2;::::0;6468:69:::2;::::0;-1:-1:-1;;;;;6503:4:0;;::::2;::::0;6518:5:::2;6526:10:::0;6468:26:::2;:69::i;:::-;6599:5;::::0;6548:71:::2;::::0;6583:5:::2;::::0;-1:-1:-1;;;;;6599:5:0::2;6607:11:::0;6548:26:::2;:71::i;:::-;6632:48;6646:10;6658:11;6671:8;6632:13;:48::i;:::-;6698:39;::::0;;11139:25:15;;;11195:2;11180:18;;11173:34;;;6698:39:0::2;::::0;11112:18:15;6698:39:0::2;;;;;;;5895:850;2303:20:12::0;1716:1;2809:22;;2629:209;2303:20;5779:966:0;;;:::o;11109:108:13:-;627:5:10;-1:-1:-1;;;;;627:11:10;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;613:27:10;:10;-1:-1:-1;;;;;613:27:10;;609:55;;649:15;;-1:-1:-1;;;649:15:10;;;;;;;;;;;609:55;11154:15:13::1;:22:::0;;-1:-1:-1;;11154:22:13::1;;;::::0;;11201:8:::1;::::0;11192:18:::1;::::0;-1:-1:-1;;;;;11201:8:13;;::::1;::::0;11192:18:::1;::::0;11154:22;;11192:18:::1;11109:108::o:0;17161:306::-;17346:19;3991:15;:13;:15::i;:::-;1232:19:11::1;:17;:19::i;:::-;2261:21:12::2;:19;:21::i;:::-;17395:30:13::3;17400:10;17412:12;17395:4;:30::i;:::-;17441:19;::::0;17381:44;;-1:-1:-1;17381:44:13;;17441:19:::3;::::0;;;::::3;2303:20:12::2;1716:1:::0;2809:22;;2629:209;2303:20:::2;17161:306:13::0;;;;:::o;1956:211:0:-;2010:7;2030:23;2056:5;-1:-1:-1;;;;;2056:18:0;;2075:12;:10;:12::i;:::-;2056:32;;;;;;;;;;;;;1358:25:15;;1346:2;1331:18;;1212:177;2056:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2030:58;;2144:15;2121:20;:18;:20::i;:::-;2106:12;:10;:12::i;:::-;:35;;;;:::i;:::-;:53;;;;:::i;21053:334:13:-;21101:13;:11;:13::i;:::-;21096:41;;21123:14;;-1:-1:-1;;;21123:14:13;;;;;;;;;;;21096:41;21151:14;;;;21150:15;;:36;;;21185:1;21169:13;;:17;21150:36;21147:66;;;21195:18;;-1:-1:-1;;;21195:18:13;;;;;;;;;;;21147:66;21239:15;21224:12;:30;21305:14;;21264:17;;21285:35;;2088:3;21285:35;:::i;:::-;21264:57;;21371:9;2088:3;21347:9;:7;:9::i;:::-;:21;;;;:::i;:::-;:33;;;;:::i;:::-;21331:13;:49;-1:-1:-1;21053:334:13:o;6705:253::-;6761:6;6779:26;6808:5;-1:-1:-1;;;;;6808:18:13;;6827:13;;6808:33;;;;;;;;;;;;;1358:25:15;;1346:2;1331:18;;1212:177;6808:33:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6779:62;;6851:18;6872:14;:12;:14::i;:::-;6851:35;-1:-1:-1;6904:47:13;6932:18;6851:35;6904:47;:::i;:::-;6897:54;;;;6705:253;:::o;15775:1084::-;2261:21:12;:19;:21::i;:::-;15929:5:13::1;-1:-1:-1::0;;;;;15929:14:13::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;15915:30:13::1;:10;-1:-1:-1::0;;;;;15915:30:13::1;;15911:56;;15954:13;;-1:-1:-1::0;;;15954:13:13::1;;;;;;;;;;;15911:56;15998:28;::::0;-1:-1:-1;;;15998:28:13;;16020:4:::1;15998:28;::::0;::::1;1747:51:15::0;15977:18:13::1;::::0;15998:5:::1;-1:-1:-1::0;;;;;15998:13:13::1;::::0;::::1;::::0;1720:18:15;;15998:28:13::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38:::0;16084:13:::1;::::0;15998:38;;-1:-1:-1;15998:38:13::1;::::0;16071:26:::1;::::0;15998:38;16071:26:::1;:::i;:::-;16046:51:::0;-1:-1:-1;16121:31:13::1;:11:::0;16046:51;16121:15:::1;:31::i;:::-;16107:45;;16162:25;16190:37;16212:11;16225:1;16190:21;:37::i;:::-;16243:17;::::0;16162:65;;-1:-1:-1;16243:17:13::1;;16238:46;;16269:15;;-1:-1:-1::0;;;16269:15:13::1;;;;;;;;;;;16238:46;16312:19;;16298:11;:33;16294:70;;;16340:24;;-1:-1:-1::0;;;16340:24:13::1;;;;;;;;;;;16294:70;16399:18;;16378;:39;16374:87;;;16438:23;;-1:-1:-1::0;;;16438:23:13::1;;;;;;;;;;;16374:87;16472:20;16480:11;16472:7;:20::i;:::-;16503:17;16523:49;16542:5;16555;-1:-1:-1::0;;;;;16555:14:13::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16549:22;::::0;:2:::1;:22;:::i;:::-;16523:11:::0;;:49;:18:::1;:49::i;:::-;16503:69;;16582:17;16602:27;16619:9;16602:16;:27::i;:::-;16582:47;;16639:20;16662:43;16685:9;16696:8;16662:22;:43::i;:::-;16639:66;;16715:18;16736:32;16742:11;16755:12;16736:5;:32::i;:::-;16715:53;;16827:25;::::0;16840:11;;16827:25:::1;::::0;;;::::1;15901:958;;;;;;;2303:20:12::0;1716:1;2809:22;;2629:209;7745:69:13;745:5:10;-1:-1:-1;;;;;745:18:10;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;731:34:10;:10;-1:-1:-1;;;;;731:34:10;;;:65;;;;;783:5;-1:-1:-1;;;;;783:11:10;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;769:27:10;:10;-1:-1:-1;;;;;769:27:10;;;731:65;727:108;;;817:18;;-1:-1:-1;;;817:18:10;;;;;;;;;;;727:108;7799:8:13::1;:6;:8::i;6753:1239:0:-:0;2261:21:12;:19;:21::i;:::-;3991:15:13::1;:13;:15::i;:::-;6995:4:0::2;::::0;:15:::2;::::0;;-1:-1:-1;;;6995:15:0;;;;6906:4:::2;::::0;6883:12:::2;::::0;-1:-1:-1;;;;;6995:4:0;;::::2;::::0;:13:::2;::::0;:15:::2;::::0;;::::2;::::0;::::2;::::0;;;;;;;;;:4;:15:::2;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6991:19;::::0;:2:::2;:19;:::i;:::-;6955:4;::::0;6981::::2;::::0;6955:32:::2;::::0;-1:-1:-1;;;6955:32:0;;-1:-1:-1;;;;;6981:4:0;;::::2;6955:32;::::0;::::2;1747:51:15::0;6955:4:0::2;::::0;;::::2;;::::0;:17:::2;::::0;1720:18:15;;6955:32:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6942:45;::::0;:10;:45:::2;:::i;:::-;:69;;;;:::i;:::-;6924:87;;7022:16;7096:5;-1:-1:-1::0;;;;;7096:14:0::2;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7092:20;::::0;:2:::2;:20;:::i;:::-;7055:4;::::0;:33:::2;::::0;-1:-1:-1;;;7055:33:0;;-1:-1:-1;;;;;7081:5:0::2;1765:32:15::0;;7055:33:0::2;::::0;::::2;1747:51:15::0;7055:4:0::2;::::0;;::::2;::::0;;::::2;::::0;:17:::2;::::0;1720:18:15;;7055:33:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7041:47;::::0;:11;:47:::2;:::i;:::-;:72;;;;:::i;:::-;7022:91:::0;-1:-1:-1;7124:19:0::2;1124:3;7170:20;7182:8:::0;1124:3;7170:20:::2;:::i;:::-;7147:18;7157:8:::0;7147:7;:18:::2;:::i;:::-;7146:45;;;;:::i;:::-;:57;;;;:::i;:::-;7243:16;::::0;;7257:1:::2;7243:16:::0;;;;;::::2;::::0;;;7124:79;;-1:-1:-1;7216:24:0::2;::::0;7243:16;::::2;::::0;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;;7278:9:0::2;::::0;7270:18;;;;-1:-1:-1;7291:10:0;;7270:18;;7278:9:::2;::::0;::::2;;;::::0;7270:18;::::2;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:31;7320:10:::2;::::0;7312:19;;7334:11;;7312:7;;7320:10:::2;::::0;;::::2;::::0;7312:19;::::2;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:33;7393:16:::2;::::0;;7407:1:::2;7393:16:::0;;;;;::::2;::::0;;;7358:32:::2;::::0;7393:16:::2;;;;;;;;;;;::::0;-1:-1:-1;;7455:9:0::2;::::0;7358:51;;-1:-1:-1;7455:9:0::2;;::::0;::::2;::::0;::::2;7442:10:::0;::::2;:22;7441:51;;7481:11;7441:51;;;7468:10;7441:51;7420:15;7436:1;7420:18;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:72;7538:9:::2;::::0;::::2;;::::0;::::2;::::0;::::2;7525:10:::0;::::2;:22;7524:51;;7565:10;7524:51;;;7551:11;7524:51;7503:15;7519:1;7503:18;;;;;;;;:::i;:::-;;;;;;:72;;;::::0;::::2;7588:21;7623:36;7661:15;7678:11;7612:78;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;7612:78:0;;::::2;::::0;;;7782:10:::2;7751:68:::0;;;7612:78:::2;7751:68:::0;::::2;::::0;;;;;;;::::2;::::0;::::2;::::0;;;7612:78;;-1:-1:-1;7703:45:0::2;::::0;7612:78;;;7751:68;7782:10;7751:68;;;7782:10;7751:68;;::::2;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;7751:68:0::2;::::0;;;;;::::2;::::0;::::2;;::::0;;::::2;;;;-1:-1:-1::0;;;7751:68:0;;;-1:-1:-1;;7751:68:0::2;::::0;::::2;::::0;;;;;;;;;;-1:-1:-1;7751:68:0;;;;;;;;7830:5:::2;::::0;7845:6:::2;::::0;7830:43;;-1:-1:-1;;;7830:43:0;;7703:116;;-1:-1:-1;;;;;;7830:5:0::2;::::0;:14:::2;::::0;:43:::2;::::0;7853:4;;;;7703:116;;7830:43:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;7903:1;7889:11;:15;7886:39;;;7906:19;7913:11;7906:6;:19::i;:::-;7943:41;::::0;;11139:25:15;;;11195:2;11180:18;;11173:34;;;7943:41:0::2;::::0;11112:18:15;7943:41:0::2;;;;;;;6872:1120;;;;;;;;2303:20:12::0;1716:1;2809:22;;2629:209;3616:1023:0;2261:21:12;:19;:21::i;:::-;3991:15:13::1;:13;:15::i;:::-;3721:12:0::2;3744:4;3721:28;;3765:5;-1:-1:-1::0;;;;;3765:22:0::2;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3762:186;;;3805:20;3813:11;3805:7;:20::i;:::-;3762:186;;;3858:78;3898:5;3906:10;3918:4;3924:11;3858:31;:78::i;:::-;4000:4;::::0;3960:76:::2;::::0;-1:-1:-1;;;;;4000:4:0::2;4007:10;4019:4:::0;4025:10;3960:31:::2;:76::i;:::-;4082:4;::::0;4097:5:::2;::::0;4047:69:::2;::::0;-1:-1:-1;;;;;4082:4:0;;::::2;::::0;4097:5:::2;4105:10:::0;4047:26:::2;:69::i;:::-;4178:5;::::0;4127:71:::2;::::0;4162:5:::2;::::0;-1:-1:-1;;;;;4178:5:0::2;4186:11:::0;4127:26:::2;:71::i;:::-;4238:16;::::0;;4252:1:::2;4238:16:::0;;;;;::::2;::::0;;;4211:24:::2;::::0;4238:16:::2;::::0;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;;4273:8:0::2;::::0;4265:17;;;;-1:-1:-1;;;;4285:6:0;4265:17;;4273:8;;::::2;;;::::0;4265:17;::::2;;;;;:::i;:::-;;;;;;:26;;;::::0;::::2;4323:10;4302:7;4310:9;;;;;;;;;;;4302:18;;;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:31;4352:10:::2;::::0;4344:19;;4366:11;;4344:7;;4352:10:::2;::::0;;::::2;::::0;4344:19;::::2;;;;;:::i;:::-;;;;;;:33;;;::::0;::::2;4390:21;4425:13:::0;4440:7:::2;4414:34;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;4414:34:0;;::::2;::::0;;;4540:10:::2;4509:68:::0;;;4414:34:::2;4509:68:::0;::::2;::::0;;;;;;;::::2;::::0;::::2;::::0;;;4414:34;;-1:-1:-1;4461:45:0::2;::::0;4414:34;;;4509:68;4540:10;4509:68;;;4540:10;4509:68;;::::2;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;4509:68:0::2;::::0;;;;;::::2;::::0;::::2;;::::0;;::::2;;;;-1:-1:-1::0;;;4509:68:0;;;-1:-1:-1;;4509:68:0::2;::::0;::::2;::::0;;;;;;;;;;-1:-1:-1;4509:68:0;;;;;;;;4588:5:::2;::::0;4603:6:::2;::::0;4588:43;;-1:-1:-1;;;4588:43:0;;4461:116;;-1:-1:-1;;;;;;4588:5:0::2;::::0;:14:::2;::::0;:43:::2;::::0;4611:4;;;;4461:116;;4588:43:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;3710:929;;;;2303:20:12::0;1716:1;2809:22;;2629:209;4760:221:13;4804:4;4852:1;4840:9;;:13;:31;;;;;4870:1;4857:10;;:14;4840:31;:61;;;;;4893:8;;4875:15;:26;4840:61;4839:135;;;;4935:1;4919:13;;:17;:54;;;;;4959:14;;4940:16;:14;:16::i;:::-;:33;4820:154;;4760:221;:::o;21504:::-;2261:21:12;:19;:21::i;:::-;21561:12:13::1;;21577:1;21561:17:::0;21558:47:::1;;21587:18;;-1:-1:-1::0;;;21587:18:13::1;;;;;;;;;;;21558:47;21615:12;21630:18;:16;:18::i;:::-;21615:33:::0;-1:-1:-1;21658:13:13::1;21695:23;21706:5;21713:4;21695:10;:23::i;2273:310:0:-:0;2354:4;;:29;;-1:-1:-1;;;2354:29:0;;2377:4;2354:29;;;1747:51:15;2316:7:0;;;;2354:4;;;;-1:-1:-1;;;;;2354:4:0;;:14;;1720:18:15;;2354:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2340:43;;2394:12;2409:4;;;;;;;;;-1:-1:-1;;;;;2409:4:0;-1:-1:-1;;;;;2409:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2394:29;;2436:18;2506:4;;;;;;;;;-1:-1:-1;;;;;2506:4:0;-1:-1:-1;;;;;2506:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:19;;2524:1;2506:19;:::i;:::-;2499:27;;:2;:27;:::i;:::-;2478:4;;;;;;;;;-1:-1:-1;;;;;2478:4:0;-1:-1:-1;;;;;2478:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2472:21;;:2;:21;:::i;:::-;2458:10;2464:4;2458:3;:10;:::i;:::-;:36;;;;:::i;:::-;2457:70;;;;:::i;:::-;2436:91;;2547:28;2564:10;2547:16;:28::i;:::-;2540:35;;;;;2273:310;:::o;7094:528:13:-;7143:7;7162:16;2088:3;7210:19;;2088:3;7198:31;;;;:::i;:::-;7181:13;;:49;;;;:::i;:::-;:61;;;;:::i;:::-;7162:80;;7252:19;7309:9;7293:12;;7275:15;:30;;;;:::i;:::-;7274:44;;;;:::i;:::-;7252:66;;7328:13;7358:14;;7344:11;:28;;;;:::i;:::-;7328:44;;2088:3;7386:5;:17;7383:37;;;-1:-1:-1;7412:8:13;;7094:528;-1:-1:-1;;7094:528:13:o;7383:37::-;7431:21;7455:17;7467:5;2088:3;7455:17;:::i;:::-;7431:41;;7482:20;2088:3;7522:13;7506;;:29;;;;:::i;:::-;7505:43;;;;:::i;:::-;7482:66;;7577:12;7566:8;:23;:49;;7603:12;7566:49;;;7592:8;7566:49;7559:56;;;;;;;7094:528;:::o;13812:1452::-;2261:21:12;:19;:21::i;:::-;13964:5:13::1;-1:-1:-1::0;;;;;13964:14:13::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;13950:30:13::1;:10;-1:-1:-1::0;;;;;13950:30:13::1;;13946:56;;13989:13;;-1:-1:-1::0;;;13989:13:13::1;;;;;;;;;;;13946:56;14013:19;14034:20:::0;14058:11:::1;:9;:11::i;:::-;14012:57;;;;14079:19;14101:30;14117:13;;14101:11;:15;;:30;;;;:::i;:::-;14146:9;::::0;14079:52;;-1:-1:-1;14146:13:13;14142:120:::1;;14204:9;::::0;14186:27:::1;::::0;:15:::1;:27;:::i;:::-;14175:8;:38:::0;14227:10:::1;:24:::0;;;14142:120:::1;14291:11;14276:12;:26;14272:834;;;14318:20;14341:26;14355:12:::0;14341:11;:26:::1;:::i;:::-;14402:32;::::0;-1:-1:-1;;;14402:32:13;;::::1;::::0;::::1;1358:25:15::0;;;14318:49:13;;-1:-1:-1;14381:18:13::1;::::0;-1:-1:-1;;;;;14402:5:13::1;:18;::::0;::::1;::::0;1331::15;;14402:32:13::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14381:53;;14448:19;14470:28;14487:10;14470:16;:28::i;:::-;14448:50;;14531:11;14517;:25;14513:108;;;14562:44;14570:25;14584:11:::0;14570;:25:::1;:::i;14562:44::-;;14513:108;14639:4;::::0;:29:::1;::::0;-1:-1:-1;;;14639:29:13;;14662:4:::1;14639:29;::::0;::::1;1747:51:15::0;14671:1:13::1;::::0;-1:-1:-1;;;;;14639:4:13::1;::::0;:14:::1;::::0;1720:18:15;;14639:29:13::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;14635:461;;;14692:18;14713:29;14730:11;14713:16;:29::i;:::-;14692:50;;14760:19;14782:106;14827:5;-1:-1:-1::0;;;;;14827:14:13::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14821:22;::::0;:2:::1;:22;:::i;:::-;14782:10:::0;;14865:5;14782:17:::1;:106::i;:::-;14760:128;;14906:20;14929:103;14973:11;15006:8;14929:22;:103::i;:::-;14906:126;;15050:31;15055:11;15068:12;15050:4;:31::i;:::-;;14674:422;;;14635:461;14304:802;;;14272:834;15120:30;::::0;-1:-1:-1;;;15120:30:13;;15144:4:::1;15120:30;::::0;::::1;1747:51:15::0;15153:1:13::1;::::0;15120:5:::1;-1:-1:-1::0;;;;;15120:15:13::1;::::0;::::1;::::0;1720:18:15;;15120:30:13::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:34;:53;;;;;15172:1;15158:11;:15;15120:53;15116:103;;;15189:19;15196:11;15189:6;:19::i;:::-;15234:23;::::0;15245:11;;15234:23:::1;::::0;;;::::1;13936:1328;;;2303:20:12::0;1716:1;2809:22;;2629:209;10757:115:13;3991:15;:13;:15::i;:::-;10808::::1;:23:::0;;-1:-1:-1;;10808:23:13::1;::::0;;10856:8:::1;::::0;10847:18:::1;::::0;-1:-1:-1;;;;;10856:8:13;;::::1;::::0;10847:18:::1;::::0;10826:5:::1;::::0;10847:18:::1;10757:115::o:0;11462:565::-;3991:15;:13;:15::i;:::-;1232:19:11::1;:17;:19::i;:::-;11593:11:13::2;4164:20;4177:6;4164:12;:20::i;:::-;2261:21:12::3;:19;:21::i;:::-;11646:34:13::4;::::0;-1:-1:-1;;;11646:34:13;;11674:4:::4;11646:34;::::0;::::4;1747:51:15::0;11646:5:13::4;-1:-1:-1::0;;;;;11646:19:13::4;::::0;::::4;::::0;1720:18:15;;11646:34:13::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11641:63;;11689:15;;-1:-1:-1::0;;;11689:15:13::4;;;;;;;;;;;11641:63;11715:22;11752:13;;11740:9;;:25;;;;:::i;:::-;11715:50;;11796:11;11779:14;:28;11775:59;;;11816:18;;-1:-1:-1::0;;;11816:18:13::4;;;;;;;;;;;11775:59;11845:25;11873:37;11895:11;11908:1;11873:21;:37::i;:::-;11845:65;;11945:14;;11924:18;:35;11920:69;;;11968:21;;-1:-1:-1::0;;;11968:21:13::4;;;;;;;;;;;11920:69;12000:20;12008:11;12000:7;:20::i;:::-;11631:396;;2303:20:12::3;1716:1:::0;2809:22;;2629:209;5161:106:13;5208:6;5233:27;5255:1;5258;5233:21;:27::i;9281:1228::-;3991:15;:13;:15::i;:::-;4071:22:::1;:20;:22::i;:::-;9712:14:::2;:32:::0;;;9754:9:::2;:22:::0;;;9786:9:::2;:22:::0;;;9818:14:::2;:32:::0;;;9860:9:::2;:22:::0;;;9892:18:::2;:40:::0;;;9942:19:::2;:42:::0;;;9994:19:::2;:42:::0;;;10046:17:::2;:38:::0;;-1:-1:-1;;10046:38:13;;::::2;::::0;::::2;;;::::0;;;10094:14:::2;:32:::0;;;;::::2;::::0;::::2;;;::::0;;10136:4:::2;:11;10143:4:::0;;10136;:11:::2;:::i;:::-;;10226:10;10197:15;10163:339;10250:10;10274:14;;10302:10;10326:19;10359:20;10393;10427:18;10459:15;10488:4;;10163:339;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;9281:1228:::0;;;;;;;;;;;;:::o;20120:832::-;3991:15;:13;:15::i;:::-;1232:19:11::1;:17;:19::i;:::-;20239:6:13::2;4164:20;4177:6;4164:12;:20::i;:::-;2261:21:12::3;:19;:21::i;:::-;20283:46:13::4;::::0;-1:-1:-1;;;20283:46:13;;20323:4:::4;20283:46;::::0;::::4;1747:51:15::0;-1:-1:-1;;;;;20283:31:13;::::4;::::0;::::4;::::0;1720:18:15;;20283:46:13::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20274:6;:55;20270:98;;;20350:18;;-1:-1:-1::0;;;20350:18:13::4;;;;;;;;;;;20270:98;20383:13;::::0;:17;20379:462:::4;;20437:5;-1:-1:-1::0;;;;;20420:23:13::4;:5;-1:-1:-1::0;;;;;20420:23:13::4;;;:49;;;;-1:-1:-1::0;20464:4:13::4;::::0;-1:-1:-1;;;;;20447:22:13;;::::4;20464:4:::0;::::4;20447:22;;20420:49;20416:92;;;20494:14;;-1:-1:-1::0;;;20494:14:13::4;;;;;;;;;;;20416:92;20523:17;20560:5;-1:-1:-1::0;;;;;20543:23:13::4;:5;-1:-1:-1::0;;;;;20543:23:13::4;;:111;;20630:24;20647:6;20630:16;:24::i;:::-;20543:111;;;20585:26;::::0;-1:-1:-1;;;20585:26:13;;::::4;::::0;::::4;1358:25:15::0;;;20585:5:13::4;-1:-1:-1::0;;;;;20585:18:13::4;::::0;::::4;::::0;1331::15;;20585:26:13::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20523:131;;20668:25;20696:35;20718:1;20721:9;20696:21;:35::i;:::-;20668:63;;20770:14;;20749:18;:35;20745:85;;;20809:21;;-1:-1:-1::0;;;20809:21:13::4;;;;;;;;;;;20745:85;20402:439;;20379:462;20851:54;20879:5;20886:10;20898:6;20851:27;:54::i;:::-;20921:24;::::0;20938:6;;-1:-1:-1;;;;;20921:24:13;::::4;::::0;::::4;::::0;;;::::4;2303:20:12::3;1716:1:::0;2809:22;;2629:209;17745:306:13;17932:18;3991:15;:13;:15::i;:::-;1232:19:11::1;:17;:19::i;:::-;2261:21:12::2;:19;:21::i;:::-;17979:32:13::3;17985:11;17998:12;17979:5;:32::i;:::-;18027:17;::::0;17966:45;;-1:-1:-1;18032:11:13;;18027:17:::3;::::0;;;::::3;2303:20:12::2;1716:1:::0;2809:22;;2629:209;19186:702:13;3991:15;:13;:15::i;:::-;1232:19:11::1;:17;:19::i;:::-;19326:11:13::2;4164:20;4177:6;4164:12;:20::i;:::-;2261:21:12::3;:19;:21::i;:::-;19395:31:13::4;::::0;-1:-1:-1;;;19395:31:13;;::::4;::::0;::::4;1358:25:15::0;;;19374:18:13::4;::::0;19395:5:::4;-1:-1:-1::0;;;;;19395:18:13::4;::::0;::::4;::::0;1331::15;;19395:31:13::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19374:52;;19436:18;19457:28;19474:10;19457:16;:28::i;:::-;19517:4;::::0;:29:::4;::::0;-1:-1:-1;;;19517:29:13;;19540:4:::4;19517:29;::::0;::::4;1747:51:15::0;19436:49:13;;-1:-1:-1;19495:19:13::4;::::0;-1:-1:-1;;;;;19517:4:13;;::::4;::::0;:14:::4;::::0;1720:18:15;;19517:29:13::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19495:51;;19574:11;19561:10;:24;19557:55;;;19594:18;;-1:-1:-1::0;;;19594:18:13::4;;;;;;;;;;;19557:55;19623:145;19676:5;19696:10;19728:4;19747:11;19623:31;:145::i;:::-;19814:4;::::0;19778:66:::4;::::0;-1:-1:-1;;;;;19814:4:13::4;19821:10;19833::::0;19778:27:::4;:66::i;:::-;19860:21;::::0;19870:10;;19860:21:::4;::::0;;;::::4;19364:524;;;2303:20:12::3;1716:1:::0;2809:22;;2629:209;2336:287;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:12;;18823:2:15;2460:63:12;;;18805:21:15;18862:2;18842:18;;;18835:30;18901:33;18881:18;;;18874:61;18952:18;;2460:63:12;;;;;;;;;1759:1;2598:7;:18;2336:287::o;28189:263:13:-;28271:7;28309:136;28361:9;28388:4;;;;;;;;;-1:-1:-1;;;;;28388:4:13;-1:-1:-1;;;;;28388:13:13;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28421:10;;28309:136;;;;;;-1:-1:-1;;;;;28421:10:13;28309:34;:136::i;527:368:14:-;726:69;;;-1:-1:-1;;;;;19239:15:15;;;726:69:14;;;19221:34:15;19291:15;;;19271:18;;;19264:43;19323:18;;;;19316:34;;;726:69:14;;;;;;;;;;19156:18:15;;;;726:69:14;;;;;;;-1:-1:-1;;;;;726:69:14;-1:-1:-1;;;726:69:14;;;702:103;;-1:-1:-1;;;;702:10:14;;;;:103;;726:69;702:103;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;666:139;;;;823:7;:57;;;;-1:-1:-1;835:11:14;;:16;;:44;;;866:4;855:24;;;;;;;;;;;;:::i;:::-;815:73;;;;-1:-1:-1;;;815:73:14;;19855:2:15;815:73:14;;;19837:21:15;19894:1;19874:18;;;19867:29;-1:-1:-1;;;19912:18:15;;;19905:33;19955:18;;815:73:14;19653:326:15;815:73:14;656:239;;527:368;;;;:::o;1849:307::-;2008:58;;;-1:-1:-1;;;;;20176:32:15;;;2008:58:14;;;20158:51:15;20225:18;;;;20218:34;;;2008:58:14;;;;;;;;;;20131:18:15;;;;2008:58:14;;;;;;;-1:-1:-1;;;;;2008:58:14;-1:-1:-1;;;2008:58:14;;;1997:70;;-1:-1:-1;;;;1997:10:14;;;;:70;;2008:58;1997:70;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1961:106;;;;2085:7;:57;;;;-1:-1:-1;2097:11:14;;:16;;:44;;;2128:4;2117:24;;;;;;;;;;;;:::i;:::-;2077:72;;;;-1:-1:-1;;;2077:72:14;;20465:2:15;2077:72:14;;;20447:21:15;20504:1;20484:18;;;20477:29;-1:-1:-1;;;20522:18:15;;;20515:32;20564:18;;2077:72:14;20263:325:15;2077:72:14;1951:205;;1849:307;;;:::o;24482:478:13:-;24539:20;24562:12;:10;:12::i;:::-;24584:23;;-1:-1:-1;;;24584:23:13;;;;;1358:25:15;;;24539:35:13;;-1:-1:-1;24584:5:13;-1:-1:-1;;;;;24584:10:13;;;;1331:18:15;;24584:23:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24634:11;24617:13;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;24668:15:13;24655:10;:28;24698:16;;24694:223;;24730:137;24783:5;24807;-1:-1:-1;;;;;24807:14:13;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24841:12;24730:27;:137::i;:::-;24886:20;;24893:12;;24886:20;;;;;24694:223;24932:21;;24941:11;;24932:21;;;;;24529:431;24482:478;:::o;4647:1124:0:-;4825:16;;;4839:1;4825:16;;;;;;;;;4772:4;;4749:12;;4825:16;;;;;;;;;;;-1:-1:-1;;4860:9:0;;4852:18;;;;-1:-1:-1;4873:10:0;;4852:18;;4860:9;;;;;;4852:18;;;;;;:::i;:::-;;;;;;;;;;:31;4902:10;;4894:19;;4916:11;;4894:7;;4902:10;;;;;4894:19;;;;;;:::i;:::-;;;;;;;;;;:33;4975:16;;;4989:1;4975:16;;;;;;;;;4940:32;;4975:16;;;;;;;;;;;;-1:-1:-1;;5037:9:0;;4940:51;;-1:-1:-1;5037:9:0;;;;;;5024:10;;:22;5023:51;;5063:11;5023:51;;;5050:10;5023:51;5002:15;5018:1;5002:18;;;;;;;;:::i;:::-;;;;;;;;;;:72;5120:9;;;;;;;;5107:10;;:22;5106:51;;5147:10;5106:51;;;5133:11;5106:51;5085:15;5101:1;5085:18;;;;;;;;:::i;:::-;;;;;;:72;;;;;5170:15;5243:4;;;;;;;;;-1:-1:-1;;;;;5243:4:0;-1:-1:-1;;;;;5243:13:0;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5237:21;;:2;:21;:::i;:::-;5201:4;;5227;;5201:32;;-1:-1:-1;;;5201:32:0;;-1:-1:-1;;;;;5227:4:0;;;5201:32;;;1747:51:15;5201:4:0;;;;;;:17;;1720:18:15;;5201:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5188:45;;:10;:45;:::i;:::-;:71;;;;:::i;:::-;5170:89;;5270:16;5346:5;-1:-1:-1;;;;;5346:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5340:22;;:2;:22;:::i;:::-;5303:4;;:33;;-1:-1:-1;;;5303:33:0;;-1:-1:-1;;;;;5329:5:0;1765:32:15;;5303:33:0;;;1747:51:15;5303:4:0;;;;;;;;:17;;1720:18:15;;5303:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5289:47;;:11;:47;:::i;:::-;:74;;;;:::i;:::-;5270:93;-1:-1:-1;5374:25:0;1124:3;5426:20;5438:8;1124:3;5426:20;:::i;:::-;5403:18;5413:8;5403:7;:18;:::i;:::-;5402:45;;;;:::i;:::-;:57;;;;:::i;:::-;5374:85;;5472:21;5507:36;5545:15;5562:17;5496:84;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;5496:84:0;;;;;;5672:10;5641:68;;;5496:84;5641:68;;;;;;;;;;;;;;;5496:84;;-1:-1:-1;5593:45:0;;5496:84;;;5641:68;5672:10;5641:68;;;5672:10;5641:68;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5641:68:0;;;;;;;;;;;;;;;;-1:-1:-1;;;5641:68:0;;;-1:-1:-1;;5641:68:0;;;;;;;;;;;;;-1:-1:-1;5641:68:0;;;;;;;;5720:5;;5735:6;;5720:43;;-1:-1:-1;;;5720:43:0;;5593:116;;-1:-1:-1;;;;;;5720:5:0;;:14;;:43;;5743:4;;;;5593:116;;5720:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4738:1033;;;;;;;;4647:1124;;;:::o;1187:309:14:-;1347:59;;;-1:-1:-1;;;;;20176:32:15;;;1347:59:14;;;20158:51:15;20225:18;;;;20218:34;;;1347:59:14;;;;;;;;;;20131:18:15;;;;1347:59:14;;;;;;;-1:-1:-1;;;;;1347:59:14;-1:-1:-1;;;1347:59:14;;;1336:71;;-1:-1:-1;;;;1336:10:14;;;;:71;;1347:59;1336:71;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1300:107;;;;1425:7;:57;;;;-1:-1:-1;1437:11:14;;:16;;:44;;;1468:4;1457:24;;;;;;;;;;;;:::i;:::-;1417:72;;;;-1:-1:-1;;;1417:72:14;;21232:2:15;1417:72:14;;;21214:21:15;21271:1;21251:18;;;21244:29;-1:-1:-1;;;21289:18:15;;;21282:32;21331:18;;1417:72:14;21030:325:15;27583:104:13;27650:8;;-1:-1:-1;;;;;27650:8:13;27636:10;:22;27632:48;;27667:13;;-1:-1:-1;;;27667:13:13;;;;;;;;;;;1760:106:11;1655:4;1678:7;;;1829:9;1821:38;;;;-1:-1:-1;;;1821:38:11;;21562:2:15;1821:38:11;;;21544:21:15;21601:2;21581:18;;;21574:30;-1:-1:-1;;;21620:18:15;;;21613:46;21676:18;;1821:38:11;21360:340:15;27809:103:13;27875:6;27885:1;27875:11;27871:34;;27895:10;;-1:-1:-1;;;27895:10:13;;;;;;;;;;;27918:265;28001:7;28039:137;28091:10;28119:4;;;;;;;;;-1:-1:-1;;;;;28119:4:13;-1:-1:-1;;;;;28119:13:13;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28152:10;;-1:-1:-1;;;;;28152:10:13;28039:34;:137::i;24966:1038::-;25045:30;;-1:-1:-1;;;25045:30:13;;25069:4;25045:30;;;1747:51:15;25022:20:13;;25045:5;-1:-1:-1;;;;;25045:15:13;;;;1720:18:15;;25045:30:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25022:53;-1:-1:-1;25099:29:13;:11;25022:53;25099:15;:29::i;:::-;25085:43;;25143:11;25158:1;25143:16;25139:47;;25168:18;;-1:-1:-1;;;25168:18:13;;;;;;;;;;;25139:47;25224:11;25211:10;;:24;25210:83;;25292:1;25210:83;;;25265:11;25252:10;;:24;;;;:::i;:::-;25197:10;:96;25308:9;;:13;;;;:32;;-1:-1:-1;25325:10:13;;:15;25308:32;25304:50;;;25353:1;25342:8;:12;25304:50;25365:20;25388:12;:10;:12::i;:::-;25423:15;25410:10;:28;25365:35;-1:-1:-1;25463:26:13;25365:35;25463:11;:26;:::i;:::-;25449:40;;25519:11;25503:13;;:27;25499:175;;;25560:13;;;25603:1;25587:17;;;25560:13;-1:-1:-1;25499:175:13;;;25652:11;25635:13;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;25499:175:13;25684:121;25733:5;25753;-1:-1:-1;;;;;25753:14:13;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25684:121;25816:70;25851:5;25867:4;25874:11;25816:26;:70::i;:::-;25896:23;;-1:-1:-1;;;25896:23:13;;;;;1358:25:15;;;25896:5:13;-1:-1:-1;;;;;25896:10:13;;;;1331:18:15;;25896:23:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;25935:19:13;;25942:11;;-1:-1:-1;25935:19:13;;-1:-1:-1;25935:19:13;;;25968:13;:11;:13::i;:::-;25964:33;;25983:14;22253:1;22238:12;:16;;;22264:13;:17;22195:93;2426:117:11;1479:16;:14;:16::i;:::-;2494:5:::1;2484:15:::0;;-1:-1:-1;;2484:15:11::1;::::0;;2514:22:::1;719:10:2::0;2523:12:11::1;2514:22;::::0;-1:-1:-1;;;;;1765:32:15;;;1747:51;;1735:2;1720:18;2514:22:11::1;;;;;;;2426:117::o:0;23368:546:13:-;23505:4;;:29;;-1:-1:-1;;;23505:29:13;;23528:4;23505:29;;;1747:51:15;23464:7:13;;;;-1:-1:-1;;;;;23505:4:13;;;;:14;;1720:18:15;;23505:29:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23483:51;-1:-1:-1;23557:27:13;:10;23483:51;23557:14;:27::i;:::-;23544:40;;23598:10;23612:1;23598:15;23594:46;;23622:18;;-1:-1:-1;;;23622:18:13;;;;;;;;;;;23594:46;23651:9;23663:5;:3;:5::i;:::-;23713:4;;23651:17;;-1:-1:-1;23678:68:13;;-1:-1:-1;;;;;23713:4:13;23651:17;23735:10;23678:26;:68::i;:::-;23813:4;;23778:100;;-1:-1:-1;;;23778:100:13;;-1:-1:-1;;;;;23813:4:13;;;23778:100;;;21907:51:15;21974:18;;;21967:34;;;22017:18;;;22010:34;;;23756:19:13;;23778:13;;;;;21880:18:15;;23778:100:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23756:122;23368:546;-1:-1:-1;;;;;;23368:546:13:o;6118:298::-;6171:7;6191:19;6212:20;6236:11;:9;:11::i;:::-;6278:32;;-1:-1:-1;;;6278:32:13;;;;;1358:25:15;;;6190:57:13;;-1:-1:-1;6190:57:13;-1:-1:-1;6257:18:13;;-1:-1:-1;;;;;6278:5:13;:18;;;;1331::15;;6278:32:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6257:53;;6320:17;6340:29;6357:11;6340:16;:29::i;:::-;6320:49;-1:-1:-1;6387:22:13;6399:10;6320:49;6387:22;:::i;:::-;6380:29;;;;;;6118:298;:::o;588:104:8:-;646:7;676:1;672;:5;:13;;684:1;672:13;;;680:1;672:13;665:20;588:104;-1:-1:-1;;;588:104:8:o;26448:825:13:-;26562:6;26580:21;26604:14;:12;:14::i;:::-;26654:30;;-1:-1:-1;;;26654:30:13;;;;;1358:25:15;;;26580:38:13;;-1:-1:-1;26628:23:13;;-1:-1:-1;;;;;26654:5:13;:18;;;;1331::15;;26654:30:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26628:56;-1:-1:-1;26694:18:13;26749:8;26715:31;26628:56;26715:13;:31;:::i;:::-;:42;;;;:::i;:::-;26694:63;;26772:10;26786:1;26772:15;26768:107;;26807:13;;:17;26803:61;;-1:-1:-1;;26826:11:13;;;;;;;26803:61;26863:1;26856:8;;;;;;;26803:61;26885:26;26914:5;-1:-1:-1;;;;;26914:18:13;;26962:10;26946:13;;:26;;;;:::i;:::-;26914:68;;;;;;;;;;;;;1358:25:15;;1346:2;1331:18;;1212:177;26914:68:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26885:97;-1:-1:-1;27045:25:13;27152:10;27075:59;26885:97;27152:10;27075:59;:::i;:::-;27074:67;;27138:3;27074:67;:::i;:::-;27073:90;;;;:::i;:::-;27045:118;;-1:-1:-1;;27178:18:13;:25;27174:56;;;-1:-1:-1;;;27174:56:13;27248:18;26448:825;-1:-1:-1;;;;;;;26448:825:13:o;1667:3925:8:-;1779:14;;;-1:-1:-1;;2316:1:8;2313;2306:20;2359:1;2356;2352:9;2343:18;;2414:5;2410:2;2407:13;2399:5;2395:2;2391:14;2387:34;2378:43;;;2516:5;2525:1;2516:10;2512:75;;2561:11;2553:5;:19;;;;;:::i;:::-;;2546:26;;;;;;2512:75;2711:5;2697:11;:19;2689:28;;;;;;2973:17;3108:11;3105:1;3102;3095:25;4486:1;4467;3656;3641:12;;:16;;3626:32;;3761:22;;;;4467:15;;;4466:21;;4719;;;4715:25;;4704:36;4788:21;;;4784:25;;4773:36;4858:21;;;4854:25;;4843:36;4928:21;;;4924:25;;4913:36;4998:21;;;4994:25;;4983:36;5069:21;;;5065:25;;;5054:36;3611:12;4006;;;4002:23;;;3998:31;;;3222:20;;;3211:32;;;4118:12;;;;3269:21;;3859:16;;;;4109:21;;;;5533:15;;1667:3925;-1:-1:-1;;;;1667:3925:8:o;680:203:9:-;786:7;121:3;823:31;843:11;121:3;823:31;:::i;:::-;813:42;;:6;:42;:::i;:::-;812:64;;;;:::i;23920:556:13:-;24060:30;;-1:-1:-1;;;24060:30:13;;24084:4;24060:30;;;1747:51:15;24018:7:13;;;;-1:-1:-1;;;;;24060:5:13;:15;;;;1720:18:15;;24060:30:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24037:53;-1:-1:-1;24114:29:13;:11;24037:53;24114:15;:29::i;:::-;24100:43;;24157:11;24172:1;24157:16;24153:47;;24182:18;;-1:-1:-1;;;24182:18:13;;;;;;;;;;;24153:47;24211:9;24223:5;:3;:5::i;:::-;24211:17;;24238:70;24273:5;24289:4;24296:11;24238:26;:70::i;:::-;24375:4;;24339:102;;-1:-1:-1;;;24339:102:13;;-1:-1:-1;;;;;24375:4:13;;;24339:102;;;21907:51:15;21974:18;;;21967:34;;;22017:18;;;22010:34;;;24318:18:13;;24339:14;;;;;21880:18:15;;24339:102:13;21705:345:15;2179:115:11;1232:19;:17;:19::i;:::-;2238:7:::1;:14:::0;;-1:-1:-1;;2238:14:11::1;2248:4;2238:14;::::0;;2267:20:::1;2274:12;719:10:2::0;;640:96;22466:896:13;22561:13;:11;:13::i;:::-;22556:41;;22583:14;;-1:-1:-1;;;22583:14:13;;;;;;;;;;;22556:41;22667:4;;:20;;-1:-1:-1;;;22667:20:13;;22630:4;22667:20;;;1747:51:15;;;22630:4:13;22607:12;;-1:-1:-1;;;;;22667:4:13;;;;:14;;1720:18:15;;22667:20:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22720:37;;-1:-1:-1;;;22720:37:13;;-1:-1:-1;;;;;1765:32:15;;;22720:37:13;;;1747:51:15;22645:42:13;;-1:-1:-1;22697:20:13;;22720:31;;;;;1720:18:15;;22720:37:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22790:21;;-1:-1:-1;;;22790:21:13;;-1:-1:-1;;;;;1765:32:15;;;22790:21:13;;;1747:51:15;22697:60:13;;-1:-1:-1;22767:20:13;;22790:5;:15;;;;1720:18:15;;22790:21:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22767:44;;22831:12;22824:4;:19;22821:276;;;22922:164;22979:5;23003:10;23031:4;23053:19;23060:12;23053:4;:19;:::i;:::-;22922:31;:164::i;:::-;23193:4;;23157:67;;-1:-1:-1;;;;;23193:4:13;23200:10;23212:11;23157:27;:67::i;:::-;23234:60;23262:5;23269:10;23281:12;23234:27;:60::i;:::-;23305:12;23312:4;23305:6;:12::i;:::-;23333:22;;23344:10;;23333:22;;;;;22546:816;;;;22466:896;;:::o;27347:230::-;27486:4;;:29;;-1:-1:-1;;;27486:29:13;;27509:4;27486:29;;;1747:51:15;27415:19:13;;;;-1:-1:-1;;;;;27486:4:13;;;;:14;;1720:18:15;;27486:29:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27540:30;;-1:-1:-1;;;27540:30:13;;27564:4;27540:30;;;1747:51:15;27472:43:13;;-1:-1:-1;27540:5:13;-1:-1:-1;;;;;27540:15:13;;;;1720:18:15;;27540:30:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27525:45;;27347:230;;:::o;27693:110::-;27754:15;;;;;;;27749:47;;27778:18;;-1:-1:-1;;;27778:18:13;;;;;;;;;;;3448:375:1;3589:14;3615;3632:19;3644:6;3632:11;:19::i;:::-;3615:36;;3661:13;3677:16;3686:6;3677:8;:16::i;:::-;3661:32;-1:-1:-1;3796:18:1;1177:1;3796:2;:18;:::i;:::-;3787:28;;:5;:28;:::i;:::-;3745:24;3756:13;3745:24;;;;:::i;:::-;3738:32;;:2;:32;:::i;:::-;3726:44;;:9;:44;:::i;:::-;3725:91;;;;:::i;3071:371::-;3207:17;3236:14;3253:19;3265:6;3253:11;:19::i;:::-;3236:36;;3282:13;3298:16;3307:6;3298:8;:16::i;:::-;3282:32;-1:-1:-1;3410:24:1;3421:13;3410:8;:24;:::i;:::-;3403:32;;:2;:32;:::i;:::-;3368:18;1177:1;3368:2;:18;:::i;:::-;3350:14;3359:5;3350:6;:14;:::i;:::-;:37;;;;:::i;1938:106:11:-;1655:4;1678:7;;;1996:41;;;;-1:-1:-1;;;1996:41:11;;22986:2:15;1996:41:11;;;22968:21:15;23025:2;23005:18;;;22998:30;-1:-1:-1;;;23044:18:15;;;23037:50;23104:18;;1996:41:11;22784:344:15;1185:111:1;1248:5;1272:6;-1:-1:-1;;;;;1272:15:1;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;1302:401::-;1362:7;1395:14;1423:12;1463:17;1494:22;1529:6;-1:-1:-1;;;;;1529:22:1;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1381:172;;;;;;;;;1590:7;1571:26;;:15;:26;;;;1563:47;;;;-1:-1:-1;;;1563:47:1;;23997:2:15;1563:47:1;;;23979:21:15;24036:1;24016:18;;;24009:29;-1:-1:-1;;;24054:18:15;;;24047:38;24102:18;;1563:47:1;23795:331:15;1563:47:1;1640:1;1628:9;:13;1620:44;;;;-1:-1:-1;;;1620:44:1;;24333:2:15;1620:44:1;;;24315:21:15;24372:2;24352:18;;;24345:30;-1:-1:-1;;;24391:18:15;;;24384:48;24449:18;;1620:44:1;24131:342:15;1620:44:1;-1:-1:-1;1690:5:1;;1302:401;-1:-1:-1;;;;1302:401:1:o;14:248:15:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:15;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:15:o;267:250::-;352:1;362:113;376:6;373:1;370:13;362:113;;;452:11;;;446:18;433:11;;;426:39;398:2;391:10;362:113;;;-1:-1:-1;;509:1:15;491:16;;484:27;267:250::o;522:271::-;564:3;602:5;596:12;629:6;624:3;617:19;645:76;714:6;707:4;702:3;698:14;691:4;684:5;680:16;645:76;:::i;:::-;775:2;754:15;-1:-1:-1;;750:29:15;741:39;;;;782:4;737:50;;522:271;-1:-1:-1;;522:271:15:o;798:220::-;947:2;936:9;929:21;910:4;967:45;1008:2;997:9;993:18;985:6;967:45;:::i;1394:180::-;1453:6;1506:2;1494:9;1485:7;1481:23;1477:32;1474:52;;;1522:1;1519;1512:12;1474:52;-1:-1:-1;1545:23:15;;1394:180;-1:-1:-1;1394:180:15:o;3177:316::-;3254:6;3262;3270;3323:2;3311:9;3302:7;3298:23;3294:32;3291:52;;;3339:1;3336;3329:12;3291:52;-1:-1:-1;;3362:23:15;;;3432:2;3417:18;;3404:32;;-1:-1:-1;3483:2:15;3468:18;;;3455:32;;3177:316;-1:-1:-1;3177:316:15:o;4113:118::-;4199:5;4192:13;4185:21;4178:5;4175:32;4165:60;;4221:1;4218;4211:12;4236:348;4288:8;4298:6;4352:3;4345:4;4337:6;4333:17;4329:27;4319:55;;4370:1;4367;4360:12;4319:55;-1:-1:-1;4393:20:15;;4436:18;4425:30;;4422:50;;;4468:1;4465;4458:12;4422:50;4505:4;4497:6;4493:17;4481:29;;4557:3;4550:4;4541:6;4533;4529:19;4525:30;4522:39;4519:59;;;4574:1;4571;4564:12;4519:59;4236:348;;;;;:::o;4589:1227::-;4742:6;4750;4758;4766;4774;4782;4790;4798;4806;4814;4822:7;4831;4885:3;4873:9;4864:7;4860:23;4856:33;4853:53;;;4902:1;4899;4892:12;4853:53;4938:9;4925:23;4915:33;;4995:2;4984:9;4980:18;4967:32;4957:42;;5046:2;5035:9;5031:18;5018:32;5008:42;;5097:2;5086:9;5082:18;5069:32;5059:42;;5148:3;5137:9;5133:19;5120:33;5110:43;;5200:3;5189:9;5185:19;5172:33;5162:43;;5252:3;5241:9;5237:19;5224:33;5214:43;;5304:3;5293:9;5289:19;5276:33;5266:43;;5318:56;5368:3;5357:9;5353:19;5340:33;5318:56;:::i;:::-;5421:3;5410:9;5406:19;5393:33;5383:43;;5435:56;5485:3;5474:9;5470:19;5457:33;5435:56;:::i;:::-;5538:3;5527:9;5523:19;5510:33;5500:43;;5593:18;5586:3;5575:9;5571:19;5558:33;5555:57;5552:77;;;5625:1;5622;5615:12;5552:77;5666:86;5744:7;5736:3;5725:9;5721:19;5708:33;5697:9;5693:49;5666:86;:::i;:::-;5772:9;5761:20;;5801:9;5790:20;;;;4589:1227;;;;;;;;;;;;;;:::o;5821:131::-;-1:-1:-1;;;;;5896:31:15;;5886:42;;5876:70;;5942:1;5939;5932:12;5957:315;6025:6;6033;6086:2;6074:9;6065:7;6061:23;6057:32;6054:52;;;6102:1;6099;6092:12;6054:52;6141:9;6128:23;6160:31;6185:5;6160:31;:::i;:::-;6210:5;6262:2;6247:18;;;;6234:32;;-1:-1:-1;;;5957:315:15:o;6508:127::-;6569:10;6564:3;6560:20;6557:1;6550:31;6600:4;6597:1;6590:15;6624:4;6621:1;6614:15;6640:754;6734:6;6787:3;6775:9;6766:7;6762:23;6758:33;6755:53;;;6804:1;6801;6794:12;6755:53;6837:2;6831:9;6879:3;6871:6;6867:16;6949:6;6937:10;6934:22;6913:18;6901:10;6898:34;6895:62;6892:88;;;6960:18;;:::i;:::-;7000:10;6996:2;6989:22;;7041:9;7035:16;7027:6;7020:32;7106:2;7095:9;7091:18;7085:25;7080:2;7072:6;7068:15;7061:50;7154:2;7143:9;7139:18;7133:25;7167:28;7189:5;7167:28;:::i;:::-;7223:2;7211:15;;7204:30;7279:2;7264:18;;7258:25;7292:30;7258:25;7292:30;:::i;:::-;7350:2;7338:15;;7331:32;7342:6;6640:754;-1:-1:-1;;;6640:754:15:o;7399:127::-;7460:10;7455:3;7451:20;7448:1;7441:31;7491:4;7488:1;7481:15;7515:4;7512:1;7505:15;7531:128;7598:9;;;7619:11;;;7616:37;;;7633:18;;:::i;7664:168::-;7737:9;;;7768;;7785:15;;;7779:22;;7765:37;7755:71;;7806:18;;:::i;7837:184::-;7907:6;7960:2;7948:9;7939:7;7935:23;7931:32;7928:52;;;7976:1;7973;7966:12;7928:52;-1:-1:-1;7999:16:15;;7837:184;-1:-1:-1;7837:184:15:o;8026:127::-;8087:10;8082:3;8078:20;8075:1;8068:31;8118:4;8115:1;8108:15;8142:4;8139:1;8132:15;8158:120;8198:1;8224;8214:35;;8229:18;;:::i;:::-;-1:-1:-1;8263:9:15;;8158:120::o;8283:125::-;8348:9;;;8369:10;;;8366:36;;;8382:18;;:::i;8413:273::-;8481:6;8534:2;8522:9;8513:7;8509:23;8505:32;8502:52;;;8550:1;8547;8540:12;8502:52;8582:9;8576:16;8632:4;8625:5;8621:16;8614:5;8611:27;8601:55;;8652:1;8649;8642:12;8691:422;8780:1;8823:5;8780:1;8837:270;8858:7;8848:8;8845:21;8837:270;;;8917:4;8913:1;8909:6;8905:17;8899:4;8896:27;8893:53;;;8926:18;;:::i;:::-;8976:7;8966:8;8962:22;8959:55;;;8996:16;;;;8959:55;9075:22;;;;9035:15;;;;8837:270;;;8841:3;8691:422;;;;;:::o;9118:806::-;9167:5;9197:8;9187:80;;-1:-1:-1;9238:1:15;9252:5;;9187:80;9286:4;9276:76;;-1:-1:-1;9323:1:15;9337:5;;9276:76;9368:4;9386:1;9381:59;;;;9454:1;9449:130;;;;9361:218;;9381:59;9411:1;9402:10;;9425:5;;;9449:130;9486:3;9476:8;9473:17;9470:43;;;9493:18;;:::i;:::-;-1:-1:-1;;9549:1:15;9535:16;;9564:5;;9361:218;;9663:2;9653:8;9650:16;9644:3;9638:4;9635:13;9631:36;9625:2;9615:8;9612:16;9607:2;9601:4;9598:12;9594:35;9591:77;9588:159;;;-1:-1:-1;9700:19:15;;;9732:5;;9588:159;9779:34;9804:8;9798:4;9779:34;:::i;:::-;9849:6;9845:1;9841:6;9837:19;9828:7;9825:32;9822:58;;;9860:18;;:::i;:::-;9898:20;;9118:806;-1:-1:-1;;;9118:806:15:o;9929:140::-;9987:5;10016:47;10057:4;10047:8;10043:19;10037:4;10016:47;:::i;10074:380::-;10153:1;10149:12;;;;10196;;;10217:61;;10271:4;10263:6;10259:17;10249:27;;10217:61;10324:2;10316:6;10313:14;10293:18;10290:38;10287:161;;10370:10;10365:3;10361:20;10358:1;10351:31;10405:4;10402:1;10395:15;10433:4;10430:1;10423:15;10287:161;;10074:380;;;:::o;10459:251::-;10529:6;10582:2;10570:9;10561:7;10557:23;10553:32;10550:52;;;10598:1;10595;10588:12;10550:52;10630:9;10624:16;10649:31;10674:5;10649:31;:::i;10715:245::-;10782:6;10835:2;10823:9;10814:7;10810:23;10806:32;10803:52;;;10851:1;10848;10841:12;10803:52;10883:9;10877:16;10902:28;10924:5;10902:28;:::i;11218:200::-;11284:9;;;11257:4;11312:9;;11340:10;;11352:12;;;11336:29;11375:12;;;11367:21;;11333:56;11330:82;;;11392:18;;:::i;:::-;11330:82;11218:200;;;;:::o;11423:127::-;11484:10;11479:3;11475:20;11472:1;11465:31;11515:4;11512:1;11505:15;11539:4;11536:1;11529:15;11555:127;11616:10;11611:3;11607:20;11604:1;11597:31;11647:4;11644:1;11637:15;11671:4;11668:1;11661:15;11687:435;11740:3;11778:5;11772:12;11805:6;11800:3;11793:19;11831:4;11860:2;11855:3;11851:12;11844:19;;11897:2;11890:5;11886:14;11918:1;11928:169;11942:6;11939:1;11936:13;11928:169;;;12003:13;;11991:26;;12037:12;;;;12072:15;;;;11964:1;11957:9;11928:169;;;-1:-1:-1;12113:3:15;;11687:435;-1:-1:-1;;;;;11687:435:15:o;12127:470::-;12336:4;12376:1;12368:6;12365:13;12355:47;;12382:18;;:::i;:::-;12429:6;12418:9;12411:25;12472:2;12467;12456:9;12452:18;12445:30;12492:56;12544:2;12533:9;12529:18;12521:6;12492:56;:::i;:::-;12484:64;;12584:6;12579:2;12568:9;12564:18;12557:34;12127:470;;;;;;:::o;12602:1070::-;12733:12;;12699:4;12754:17;;;12820:19;;12690:14;;;12848:20;;;12660:3;;12918:4;;12945:21;;;;12895:3;12886:13;;;12660:3;12994:201;13008:6;13005:1;13002:13;12994:201;;;13075:13;;-1:-1:-1;;;;;13071:39:15;13057:54;;13170:15;;;;13133:14;;;;13107:1;13023:9;12994:201;;;12998:3;;13243:2;13236:5;13232:14;13226:21;13204:43;;13288:3;13281:5;13277:15;13272:2;13267:3;13263:12;13256:37;13316:51;13361:5;13345:14;13316:51;:::i;:::-;13302:65;;;;13415:4;13408:5;13404:16;13398:23;13465:3;13457:6;13453:16;13446:4;13441:3;13437:14;13430:40;13493:41;13527:6;13511:14;13493:41;:::i;:::-;13479:55;;;13582:4;13575:5;13571:16;13565:23;13597:47;13638:4;13633:3;13629:14;13613;2102:13;2095:21;2083:34;;2032:91;13597:47;-1:-1:-1;13660:6:15;12602:1070;-1:-1:-1;;;12602:1070:15:o;13677:553::-;13938:25;;;-1:-1:-1;;;;;14037:15:15;;;14032:2;14017:18;;14010:43;14089:15;;14084:2;14069:18;;14062:43;14141:3;14136:2;14121:18;;14114:31;;;13919:4;;14162:62;;14204:19;;14196:6;14162:62;:::i;14235:139::-;14315:1;14308:5;14305:12;14295:46;;14321:18;;:::i;:::-;14350;;14235:139::o;14379:361::-;14579:43;14612:9;14604:6;14579:43;:::i;:::-;14658:2;14653;14642:9;14638:18;14631:30;14560:4;14678:56;14730:2;14719:9;14715:18;14707:6;14678:56;:::i;:::-;14670:64;14379:361;-1:-1:-1;;;;14379:361:15:o;15303:225::-;15407:4;15386:12;;;15400;;;15382:31;15433:22;;;;15474:24;;;15464:58;;15502:18;;:::i;15659:545::-;15761:2;15756:3;15753:11;15750:448;;;15797:1;15822:5;15818:2;15811:17;15867:4;15863:2;15853:19;15937:2;15925:10;15921:19;15918:1;15914:27;15908:4;15904:38;15973:4;15961:10;15958:20;15955:47;;;-1:-1:-1;15996:4:15;15955:47;16051:2;16046:3;16042:12;16039:1;16035:20;16029:4;16025:31;16015:41;;16106:82;16124:2;16117:5;16114:13;16106:82;;;16169:17;;;16150:1;16139:13;16106:82;;16380:1206;16504:18;16499:3;16496:27;16493:53;;;16526:18;;:::i;:::-;16555:94;16645:3;16605:38;16637:4;16631:11;16605:38;:::i;:::-;16599:4;16555:94;:::i;:::-;16675:1;16700:2;16695:3;16692:11;16717:1;16712:616;;;;17372:1;17389:3;17386:93;;;-1:-1:-1;17445:19:15;;;17432:33;17386:93;-1:-1:-1;;16337:1:15;16333:11;;;16329:24;16325:29;16315:40;16361:1;16357:11;;;16312:57;17492:78;;16685:895;;16712:616;15606:1;15599:14;;;15643:4;15630:18;;-1:-1:-1;;16748:17:15;;;16849:9;16871:229;16885:7;16882:1;16879:14;16871:229;;;16974:19;;;16961:33;16946:49;;17081:4;17066:20;;;;17034:1;17022:14;;;;16901:12;16871:229;;;16875:3;17128;17119:7;17116:16;17113:159;;;17252:1;17248:6;17242:3;17236;17233:1;17229:11;17225:21;17221:34;17217:39;17204:9;17199:3;17195:19;17182:33;17178:79;17170:6;17163:95;17113:159;;;17315:1;17309:3;17306:1;17302:11;17298:19;17292:4;17285:33;16685:895;;16380:1206;;;:::o;17591:1025::-;17923:4;17952:3;17982:6;17971:9;17964:25;18025:6;18020:2;18009:9;18005:18;17998:34;18068:6;18063:2;18052:9;18048:18;18041:34;18111:6;18106:2;18095:9;18091:18;18084:34;18155:6;18149:3;18138:9;18134:19;18127:35;18199:6;18193:3;18182:9;18178:19;18171:35;18257:6;18250:14;18243:22;18237:3;18226:9;18222:19;18215:51;18317:6;18310:14;18303:22;18297:3;18286:9;18282:19;18275:51;18363:2;18357:3;18346:9;18342:19;18335:31;18402:6;18397:2;18386:9;18382:18;18375:34;;18428:3;18481:6;18473;18468:2;18457:9;18453:18;18440:48;18537:1;18508:22;;;18504:31;;18497:42;18600:2;18579:15;;;-1:-1:-1;;18575:29:15;18560:45;;;18556:54;;;;17591:1025;-1:-1:-1;;;;;;;;;;17591:1025:15:o;19361:287::-;19490:3;19528:6;19522:13;19544:66;19603:6;19598:3;19591:4;19583:6;19579:17;19544:66;:::i;:::-;19626:16;;;;;19361:287;-1:-1:-1;;19361:287:15:o;20593:432::-;20821:43;20854:9;20846:6;20821:43;:::i;:::-;20900:2;20895;20884:9;20880:18;20873:30;20802:4;20920:56;20972:2;20961:9;20957:18;20949:6;20920:56;:::i;22055:237::-;22127:9;;;22094:7;22152:9;;-1:-1:-1;;;22163:18:15;;22148:34;22145:60;;;22185:18;;:::i;:::-;22258:1;22249:7;22244:16;22241:1;22238:23;22234:1;22227:9;22224:38;22214:72;;22266:18;;:::i;22297:193::-;22336:1;22362;22352:35;;22367:18;;:::i;:::-;-1:-1:-1;;;22403:18:15;;-1:-1:-1;;22423:13:15;;22399:38;22396:64;;;22440:18;;:::i;:::-;-1:-1:-1;22474:10:15;;22297:193::o;22495:131::-;22555:5;22584:36;22611:8;22605:4;22584:36;:::i;22631:148::-;22719:4;22698:12;;;22712;;;22694:31;;22737:13;;22734:39;;;22753:18;;:::i;23133:179::-;23211:13;;23264:22;23253:34;;23243:45;;23233:73;;23302:1;23299;23292:12;23233:73;23133:179;;;:::o;23317:473::-;23420:6;23428;23436;23444;23452;23505:3;23493:9;23484:7;23480:23;23476:33;23473:53;;;23522:1;23519;23512:12;23473:53;23545:39;23574:9;23545:39;:::i;:::-;23535:49;;23624:2;23613:9;23609:18;23603:25;23593:35;;23668:2;23657:9;23653:18;23647:25;23637:35;;23712:2;23701:9;23697:18;23691:25;23681:35;;23735:49;23779:3;23768:9;23764:19;23735:49;:::i;:::-;23725:59;;23317:473;;;;;;;;:::o
Swarm Source
ipfs://36dd9e7470219475513bedd465d9c9f75f829a107aff554b6ceb88bfc00acf74
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.