Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 42 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Queue Withdraw | 20776848 | 29 hrs ago | IN | 0 ETH | 0.0010399 | ||||
Intialize Stale ... | 20773905 | 39 hrs ago | IN | 0 ETH | 0.00022264 | ||||
Intialize Stale ... | 20773763 | 40 hrs ago | IN | 0 ETH | 0.0004611 | ||||
Queue Withdraw | 20739475 | 6 days ago | IN | 0 ETH | 0.00025833 | ||||
Cumulative Swap | 20732008 | 7 days ago | IN | 0 ETH | 0.0027038 | ||||
Cumulative Swap | 20726047 | 8 days ago | IN | 0 ETH | 0.00210861 | ||||
Intialize Stale ... | 20724052 | 8 days ago | IN | 0 ETH | 0.00011551 | ||||
Intialize Stale ... | 20724022 | 8 days ago | IN | 0 ETH | 0.00013593 | ||||
Intialize Stale ... | 20723962 | 8 days ago | IN | 0 ETH | 0.00011583 | ||||
Intialize Stale ... | 20723955 | 8 days ago | IN | 0 ETH | 0.00012106 | ||||
Intialize Stale ... | 20723930 | 8 days ago | IN | 0 ETH | 0.00011924 | ||||
Intialize Stale ... | 20723652 | 8 days ago | IN | 0 ETH | 0.00031162 | ||||
Set Delay Module | 20713299 | 10 days ago | IN | 0 ETH | 0.00041247 | ||||
Transfer Ownersh... | 20713078 | 10 days ago | IN | 0 ETH | 0.00018032 | ||||
Unstaking Profit... | 20712572 | 10 days ago | IN | 0 ETH | 0.00032521 | ||||
Redeem | 20711719 | 10 days ago | IN | 0 ETH | 0.00026843 | ||||
Redeem | 20711716 | 10 days ago | IN | 0 ETH | 0.00032538 | ||||
Pause Unpause Qu... | 20711710 | 10 days ago | IN | 0 ETH | 0.00004034 | ||||
Unstake For Queu... | 20711708 | 10 days ago | IN | 0 ETH | 0.00292201 | ||||
Pause Unpause Qu... | 20711687 | 10 days ago | IN | 0 ETH | 0.00008063 | ||||
Queue Withdraw | 20711460 | 10 days ago | IN | 0 ETH | 0.00025816 | ||||
Redeem | 20707907 | 10 days ago | IN | 0 ETH | 0.00020135 | ||||
Redeem | 20704257 | 11 days ago | IN | 0 ETH | 0.00012139 | ||||
Cumulative Swap | 20704242 | 11 days ago | IN | 0 ETH | 0.00114121 | ||||
Pause Unpause Qu... | 20704114 | 11 days ago | IN | 0 ETH | 0.00002956 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
AFiOracle
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "./IUniswapV3Factory.sol"; import "./OracleLibrary.sol"; import "./IAFi.sol"; import {SafeCast} from "./SafeCast.sol"; import {SafeERC20} from "./SafeERC20.sol"; import {OwnableDelayModule} from "./OwnableDelayModule.sol"; import {AggregatorV3Interface} from "./AggregatorV3Interface.sol"; import {ReentrancyGuard} from "./ReentrancyGuard.sol"; import {ISwapRouter} from "./ISwapRouter.sol"; import "./IPassiveRebal.sol"; struct RewardOwed { address token; uint owed; } interface ICompRewardV3 { function getRewardOwed( address comet, address account ) external returns (RewardOwed memory); function claim(address comet, address src, bool shouldAccrue) external; } contract AFiOracle is ReentrancyGuard, OwnableDelayModule { using SafeCast for uint256; using SafeERC20 for IERC20; IAFiStorage internal aFiStorage; mapping(address => mapping(address => uint24)) public _fee; uint32 internal secondsAgo = 900; uint256 internal csFee = 5e20; uint256 internal csFeeUpperLimit = 5e21; address internal rebal; uint256 internal stalePricewindowLimit = 1 hours; uint internal daoProfit = 6; uint internal totalProfit = 10; bool public paused; address[] internal token; address[] internal uTokens; address internal afiManager; mapping(address => address) internal cumulativeSwapControllers; mapping(address => address) internal unstakingController; address internal constant UNISWAP_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984; address private constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address private constant USDC_ORACLE = 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6; address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; ICompRewardV3 internal constant COMPV3_REWARD = ICompRewardV3(0x1B0e765F6224C21223AeA2af16c1C46E38885a40); struct TokenInfo { address[] tokens; address[] uTokens; uint256[] uTokenProportions; uint256[] defaultProportion; } struct WithdrawQueueDetails { mapping(address => mapping(address => mapping(uint256 => uint256))) queuedShares; } struct WithdrawQueueNAVDetail { mapping(address => mapping(address => mapping(uint256 => uint256))) queuedNAV; } mapping(address => WithdrawQueueDetails) internal userOtokenLiability; mapping(address => WithdrawQueueNAVDetail) internal userQueuedNAV; mapping(address => uint) internal stalePriceDelay; mapping(address => uint256) internal lastSwapTime; mapping(address => uint) internal swapPeriod; mapping(address => address) internal underlyingUniPoolToken; mapping(address => mapping(address => mapping(uint => uint))) public totalShares; mapping(address => mapping(address => mapping(uint => uint))) public outputTokenUnits; mapping(address => uint256) public batchWithdrawCounter; mapping(address => mapping(uint => uint)) public totalQueuedShares; mapping(address => mapping(address => uint)) internal teamWalletsProfit; mapping(address => bool) public queuePausedStatus; event ProfitShareUpdated(uint daoProfit, uint totalProfit); event ProfitShareDistributed( address indexed aFiContract, address indexed teamWallet, uint256 amount ); event WithdrawQueue( address indexed user, uint256 shares, address indexed oToken, uint256 withdrawCounter ); event WithdrawDeQueue(address indexed user, uint256 shares, uint256 withdrawCounter); /** * @notice To initialize/deploy the AFIOracle contract. * @param passiveRebalContract Address of AFiPassiveRebalStrategies contract. */ constructor(address passiveRebalContract) { addressZero(passiveRebalContract); rebal = passiveRebalContract; } /** * @param account Address of the account that paused the contract. */ event Paused(address account); /** * @param account Address of the account that unpaused the contract. */ event Unpaused(address account); function getMidToken(address tok) external view returns (address) { return underlyingUniPoolToken[tok]; } function addressZero(address add1) internal pure { require(add1 != address(0), "AF03"); } function updateAFiManager(address _afiManager) external onlyOwner { addressZero(_afiManager); afiManager = _afiManager; } function getTotalProfit() external view returns (uint256) { return totalProfit; } function getDaoProfit() external view returns (uint256) { return daoProfit; } function updateMidToken(address[] memory tok, address[] memory midTok) external { require( msg.sender == owner() || msg.sender == afiManager || msg.sender == IAFiManager(afiManager).rebalanceController(), "NA" ); for (uint i; i < tok.length; i++) { addressZero(tok[i]); addressZero(midTok[i]); underlyingUniPoolToken[tok[i]] = midTok[i]; } } modifier contractUnpaused() { checkStatus(!paused); _; } modifier contractPaused() { checkStatus(paused); _; } function checkStatus(bool status) internal view { require(status, "AFO08"); } function greaterComparison(uint256 valA, uint256 valB) internal pure { require(valA >= valB, "AO24"); } /** * @notice To pause the contract. * @dev Requirements: It can only be invoked by owner. */ function pause() external contractUnpaused onlyOwner { paused = true; emit Paused(msg.sender); } /** * @notice To resume/unpause the contract. * @dev Requirements: It can only be invoked by the owner. */ function unPause() external contractPaused onlyOwner { paused = false; emit Unpaused(msg.sender); } function setAFiStorage(address _storage) external onlyOwner { addressZero(_storage); aFiStorage = IAFiStorage(_storage); } /** * @notice Updates the address of the cumulative swap wallet for aFi Vault. * @dev Only the contract owner can call this function. * @param afiContract Vault address * @param _cumulativeSwapController New address for the cumulative swap wallet for afiContract vault. * @param _unstakingController New address for the unstaking controller wallet for afiContract vault. */ function updateVaultControllers( address afiContract, address _cumulativeSwapController, address _unstakingController ) external onlyOwner { cumulativeSwapControllers[afiContract] = _cumulativeSwapController; unstakingController[afiContract] = _unstakingController; } function getControllers( address afiContract ) external view returns (address, address) { return (cumulativeSwapControllers[afiContract], unstakingController[afiContract]); } /** * @notice Executes cumulative token swaps and updates staking for underlying tokens. * @param params The struct containing swap parameters. */ function cumulativeSwap(IAFi.SwapParameters memory params) external { require( msg.sender == cumulativeSwapControllers[params.afiContract] || msg.sender == afiManager, "NA" ); require( block.timestamp - lastSwapTime[params.afiContract] >= swapPeriod[params.afiContract], "Swap period not elapsed" ); // Check if deposit is paused (bool depositPaused, ) = IAFi(params.afiContract).isPaused(); checkStatus(depositPaused); TokenInfo memory tokenInfo; (params.depositTokens, ) = IAFi(params.afiContract).getInputToken(); params.cSwapCounter = IAFi(params.afiContract).getcSwapCounter(); tokenInfo.uTokens = IAFi(params.afiContract).getUTokens(); require(tokenInfo.uTokens.length > 0, "Reinitialize the vault"); if (params.cometRewardTokens.length > 0) claimCompV3Rewards( params.afiContract, params.cometToClaim, params.cometRewardTokens, params.rewardTokenMinReturnAmounts, params.oToken, params._deadline ); uint256 totalProp = IAFi(params.afiContract).underlyingTokensStaking( params.depositTokens ); (tokenInfo.uTokenProportions, tokenInfo.defaultProportion) = IAFi( params.afiContract ).getProportions(); performTokenSwaps(params, tokenInfo, totalProp); aFiStorage.rearrange( params.afiContract, params.underlyingTokens, params.newProviders ); // Update last swap time after all operations are complete lastSwapTime[params.afiContract] = block.timestamp; IAFi(params.afiContract).pauseUnpauseDeposit(false); IAFiManager(afiManager).pauseQueueWithdrawUnstaking(params.afiContract, false); } function claimCompV3Rewards( address afiContract, address[] memory cometToClaim, address[] memory cometRewardTokens, uint256[] memory rewardTokenMinReturnAmounts, address oToken, uint256 _deadline ) internal { uint256 balToSwap; address tok; for (uint8 i = 0; i < uint8(cometToClaim.length); i++) { tok = cometRewardTokens[i]; balToSwap = IERC20(tok).balanceOf(afiContract); COMPV3_REWARD.claim(cometToClaim[i], afiContract, true); if (IERC20(tok).balanceOf(afiContract) > balToSwap) { balToSwap = IERC20(tok).balanceOf(afiContract) - balToSwap; doSwap( afiContract, tok, oToken, balToSwap, _deadline, WETH, rewardTokenMinReturnAmounts[i] ); } } } function performTokenSwaps( IAFi.SwapParameters memory params, TokenInfo memory tokenInfo, uint256 totalProp ) internal { uint256 temp; for (uint256 j = 0; j < params.depositTokens.length; j++) { (temp) = aFiStorage.getPreSwapDepositsTokens( params.afiContract, params.cSwapCounter, params.depositTokens[j] ); if (params.depositTokens[j] != params.oToken && temp > 0) { doSwap( params.afiContract, params.depositTokens[j], params.oToken, temp, params._deadline, WETH, params.iMinimumReturnAmount[j] ); } } // Assuming `redeemTxFee` and `csFee` are defined and handled elsewhere require( redeemTxFee(params.afiContract, params.oToken, params.cSwapFee) <= csFee, "AFO01" ); swapIntoUnderlying(params, tokenInfo, totalProp); } function swapIntoUnderlying( IAFi.SwapParameters memory params, TokenInfo memory tokenInfo, uint256 _totalProp ) internal { uint256 tempBalance; uint256[] memory tokenProportions = tokenInfo.uTokenProportions; // Check for passive rebalance status and adjust token proportions if necessary if ( IPassiveRebal(rebal).getRebalStrategyNumber(params.afiContract) == 0 ) { tokenProportions = tokenInfo.defaultProportion; _totalProp = 0; for (uint i = 0; i < tokenProportions.length; i++) { _totalProp += tokenProportions[i]; } } tempBalance = IERC20(params.oToken).balanceOf(params.afiContract); for (uint i = 0; i < tokenInfo.uTokens.length; i++) { // Perform swap if conditions are met if (tokenProportions[i] >= 1 && tempBalance > 0) { doSwap( params.afiContract, params.oToken, tokenInfo.uTokens[i], (tempBalance * tokenProportions[i]) / _totalProp, params._deadline, address(0), // Assuming this is intended as the recipient or a swap parameter params.minimumReturnAmount[i] ); } } } /** * @notice Computes the redemption fee for a transaction. * @dev This function is internal and computes the redemption fee based on the provided parameters. * @param afiContract The address of the AFi contract. * @param _inputToken The address of the input token for the transaction. * @param cSwapFee The cumulative swap fee to calculate the redemption fee from. * @return redFee The computed redemption fee. */ function redeemTxFee( address afiContract, address _inputToken, uint256 cSwapFee ) internal returns (uint256 redFee) { if (cSwapFee > 0) { (uint256 price, uint256 decimal) = getPriceInUSDC(_inputToken); uint iTokenDecimal = 18 - IERC20(_inputToken).decimals(); redFee = (((cSwapFee) * price * (10 ** iTokenDecimal)) / (decimal)); IERC20(_inputToken).safeTransferFrom( afiContract, cumulativeSwapControllers[afiContract], cSwapFee ); } } /** * @notice Queues a withdrawal for a user. * @param afiContract The address of the AFi contract. * @param _shares The amount of shares to withdraw. * @param oToken The address of the output token. */ function queueWithdraw( address afiContract, uint _shares, address oToken ) external nonReentrant { checkStatus(!(queuePausedStatus[afiContract])); IAFi(afiContract).validateWithdraw(msg.sender, oToken, _shares); uint256 userOtokenLiabilityOld = userOtokenLiability[msg.sender].queuedShares[ afiContract ][oToken][batchWithdrawCounter[afiContract]]; uint256 userNAV = IAFi(afiContract).depositUserNav(msg.sender); userOtokenLiability[msg.sender].queuedShares[afiContract][oToken][ batchWithdrawCounter[afiContract] ] = userOtokenLiabilityOld + _shares; uint256 userQNAV = userQueuedNAV[msg.sender].queuedNAV[afiContract][oToken][batchWithdrawCounter[afiContract]]; userQueuedNAV[msg.sender].queuedNAV[afiContract][oToken][batchWithdrawCounter[afiContract]] = ((userQNAV * userOtokenLiabilityOld) + ((userNAV * _shares)))/ (userOtokenLiabilityOld + _shares); totalShares[afiContract][oToken][batchWithdrawCounter[afiContract]] += _shares; //in AFi Token totalQueuedShares[afiContract][batchWithdrawCounter[afiContract]] += _shares; updateLockedTokensInVault(afiContract, _shares, false, true, false, 0); emit WithdrawQueue(msg.sender, _shares, oToken, batchWithdrawCounter[afiContract]); } function updateLockedTokensInVault( address afiContract, uint256 _shares, bool status, bool _queue, bool _unqueue, uint256 newNAV ) internal { IAFi(afiContract).updateLockedTokens( msg.sender, _shares, status, _queue, _unqueue, newNAV ); } /** * @notice Retrieves the queued shares for a user. * @param user The address of the user. * @param afiContract The address of the AFi contract. * @param oToken The address of the output token. * @return The number of queued shares for the user. */ function getUserQueuedShares( address user, address afiContract, address oToken, uint256 bCounter ) external view returns (uint256) { return userOtokenLiability[user].queuedShares[afiContract][oToken][bCounter]; } function getUserQueuedNAV( address user, address afiContract, address oToken, uint256 bCounter ) external view returns (uint256) { return userQueuedNAV[user].queuedNAV[afiContract][oToken][bCounter]; } function getTotalShares( address aFicontract, address tok, uint256 batchWithCounter ) internal returns (uint256) { return totalShares[aFicontract][tok][batchWithCounter]; } /** * @notice Removes queued withdrawal for a users. * @param afiContract The address of the AFi contract. * @param oToken The address of the output token. */ function unqueueWithdraw(address afiContract, address oToken) external nonReentrant { checkStatus(!(queuePausedStatus[afiContract])); uint256 userShares = userOtokenLiability[msg.sender].queuedShares[afiContract][ oToken ][batchWithdrawCounter[afiContract]]; require(userShares > 0, "Zero Queued"); totalShares[afiContract][oToken][batchWithdrawCounter[afiContract]] -= userShares; //in AFi Token deleteUserOTokenLiability(afiContract, oToken, batchWithdrawCounter[afiContract]); totalQueuedShares[afiContract][batchWithdrawCounter[afiContract]] -= userShares; uint256 qQuant = userShares; uint256 userQNAV = userQueuedNAV[msg.sender].queuedNAV[afiContract][oToken][batchWithdrawCounter[afiContract]]; delete userQueuedNAV[msg.sender].queuedNAV[afiContract][oToken][batchWithdrawCounter[afiContract]]; uint256 NAVToUpdate = ((userQNAV* qQuant) + IAFi(afiContract).depositUserNav(msg.sender) * IERC20(afiContract).balanceOf(msg.sender)) / ((qQuant) + IERC20(afiContract).balanceOf(msg.sender)); updateLockedTokensInVault(afiContract, userShares, false, false, true, NAVToUpdate); emit WithdrawDeQueue(msg.sender, userShares, batchWithdrawCounter[afiContract]); } function deleteUserOTokenLiability( address afiContract, address _oToken, uint256 bCounter ) internal { delete userOtokenLiability[msg.sender].queuedShares[afiContract][_oToken][bCounter]; } // call updateTVL before this function /** * @notice Performs unstaking for queued withdrawals. * @param afiContract The address of the AFi contract. * @param oToken The address of the output token. * @param deadline The deadline for the transaction. * @param minimumReturnAmount An array of minimum return amounts. * @param minOutForiToken An array of minimum output amounts for iToken. */ function unstakeForQueuedWithdrawals( address afiContract, address oToken, uint256 deadline, uint[] memory minimumReturnAmount, uint256[] memory minOutForiToken, bool _updateTVL ) external { addressEqual(msg.sender, unstakingController[afiContract]); checkStatus(queuePausedStatus[afiContract]); checkStatus(IAFi(afiContract).isOTokenWhitelisted(oToken)); require( !IAFiManager(afiManager).isQueueWithdrawUnstakingPaused(afiContract), "Call CS first" ); IAFi(afiContract).checkTVL(_updateTVL); uint256 pool; uint256 _totalSupply; (token, uTokens, pool, _totalSupply) = IAFi(afiContract).setUnstakeData( totalQueuedShares[afiContract][batchWithdrawCounter[afiContract]] ); uint toSwap; if (totalQueuedShares[afiContract][batchWithdrawCounter[afiContract]] > 0) { toSwap = (pool * (totalQueuedShares[afiContract][batchWithdrawCounter[afiContract]])) / (_totalSupply); toSwap = aFiStorage.swapForOtherProduct( afiContract, toSwap, oToken, deadline, minimumReturnAmount, uTokens ); } swapAndTransfer(afiContract, oToken, toSwap, minOutForiToken, deadline); delete totalQueuedShares[afiContract][batchWithdrawCounter[afiContract]]; batchWithdrawCounter[afiContract]++; } function swapAndTransfer( address afiContract, address oToken, uint256 toSwap, uint256[] memory minOutForiToken, uint256 deadline ) internal { uint256 depositTokensToSwap; uint256 toDeduct; for (uint i; i < token.length; i++) { if ( token[i] != oToken && getTotalShares(afiContract, token[i], batchWithdrawCounter[afiContract]) > 0 ) { depositTokensToSwap = (toSwap * ( getTotalShares(afiContract, token[i], batchWithdrawCounter[afiContract]) )) / (totalQueuedShares[afiContract][batchWithdrawCounter[afiContract]]); if (depositTokensToSwap > 0) { toDeduct += depositTokensToSwap; depositTokensToSwap = doSwap( afiContract, oToken, token[i], depositTokensToSwap, deadline, WETH, minOutForiToken[i] ); } if (IERC20(token[i]).balanceOf(afiContract) > 0) { IERC20(token[i]).safeTransferFrom( afiContract, address(this), depositTokensToSwap ); } outputTokenUnits[afiContract][token[i]][ batchWithdrawCounter[afiContract] ] = depositTokensToSwap; } } for (uint j; j < token.length; j++) { if ( token[j] == oToken && totalShares[afiContract][token[j]][batchWithdrawCounter[afiContract]] > 0 ) { depositTokensToSwap = toSwap - toDeduct; IERC20(token[j]).safeTransferFrom( afiContract, address(this), depositTokensToSwap ); outputTokenUnits[afiContract][oToken][ batchWithdrawCounter[afiContract] ] = depositTokensToSwap; break; } } } function doSwap( address afiContract, address tokenIn, address tokenOut, uint amt, uint deadline, address middleTok, uint256 minOut ) internal returns (uint256) { return IAFi(afiContract).swap(tokenIn, tokenOut, amt, deadline, middleTok, minOut); } /** * @notice Redeems tokens for a user based on their queued shares and batch withdrawal index. * @param aFiContract The address of the AFi contract. * @param _iTokens An array of token addresses to redeem. * @param batchWithdrawIndex The batch withdrawal index. */ function redeem( IAFi aFiContract, address[] memory _iTokens, uint256 batchWithdrawIndex ) external { require(batchWithdrawIndex < batchWithdrawCounter[address(aFiContract)], "AO01"); uint redemptionValue; uint256 userDepositedAFiInOToken; uint256 userShares; uint256 userDepositNav; //Calculation for the deposit token value for (uint i = 0; i < _iTokens.length; i++) { userShares = userOtokenLiability[msg.sender].queuedShares[address(aFiContract)][ _iTokens[i] ][batchWithdrawIndex]; userDepositNav = userQueuedNAV[msg.sender].queuedNAV[address(aFiContract)][_iTokens[i]][batchWithdrawIndex]; if (userShares > 0) { redemptionValue = ((userShares * (outputTokenUnits[address(aFiContract)][_iTokens[i]][batchWithdrawIndex])) / (totalShares[address(aFiContract)][_iTokens[i]][batchWithdrawIndex])); (uint256 price, uint256 multiplier) = getPriceInUSDC(_iTokens[i]); uint8 decimals = 18 - IERC20(_iTokens[i]).decimals(); userDepositedAFiInOToken = (userDepositNav * (userShares) * (multiplier)) / (price * (10 ** decimals) * 10000); if (redemptionValue > userDepositedAFiInOToken) { teamWalletsProfit[address(aFiContract)][_iTokens[i]] += ((redemptionValue - userDepositedAFiInOToken) * (totalProfit)) / (100); redemptionValue -= ((redemptionValue - userDepositedAFiInOToken) * (totalProfit)) / (100); } deleteUserOTokenLiability( address(aFiContract), _iTokens[i], batchWithdrawIndex ); IERC20(_iTokens[i]).safeTransfer(msg.sender, redemptionValue); } } } /** * @notice Returns the Swap Period for a specific aFi contract. * @param afiContract Address of the aFi contract. * @return uint256 Swap Period in seconds. */ function getSwapPeriod(address afiContract) external view returns (uint) { return swapPeriod[afiContract]; } /** * @notice Updates the Swap Period for a specific aFi contract. * @dev Only the contract owner can call this function. * @param afiContract Address of the aFi contract. * @param _newSwapPeiod New Swap Period in seconds. */ function updateSwapPeriod( address afiContract, uint _newSwapPeiod ) external onlyOwner { swapPeriod[afiContract] = _newSwapPeiod; } /** * @notice Returns the timestamp of the last cumulative swap execution. * @param afiContract Address of the aFi contract. * @return uint256 Timestamp of the last cumulative swap. */ function getLastSwapTime(address afiContract) external view returns (uint256) { return lastSwapTime[afiContract]; } /** * @notice Sets the cumulative swap fee upper limit. * @dev Only the contract owner can call this function. * @param _csFeeUpperLimit New cumulative swap fee maximum limit. */ function setcsFeeUpperLimit(uint256 _csFeeUpperLimit) external onlyOwner { csFeeUpperLimit = _csFeeUpperLimit; } function getFeeDetails() external view returns (uint256, uint256) { return (csFee, csFeeUpperLimit); } /** * @notice Sets the cumulative swap fee. * @dev Only the contract owner can call this function. * @param _csFee New cumulative swap fee. */ function setcsFee(uint256 _csFee) external onlyOwner { require(_csFee <= csFeeUpperLimit, "AFO111"); csFee = _csFee; } /** * @notice To get the number of USDC tokens for aFi vault. * @param tokenIn Address of underlying token from set. * @param amountIn Amount of underlying token * @param tokenOut Address of the underlying token for aFi contract(USDC). */ function estimateAmountOut( address tokenIn, uint128 amountIn, address tokenOut ) public view returns (uint amountOut) { address _pool = IUniswapV3Factory(UNISWAP_FACTORY).getPool( tokenOut, tokenIn, _fee[tokenIn][tokenOut] ); addressZero(_pool); amountOut = getAmountOutMin(tokenIn, amountIn, tokenOut, _pool); } function estimateAmountOutMin( address tokenIn, uint128 amountIn, address tokenOut, address poolToConsider ) public view returns (uint amountOut) { addressZero(poolToConsider); amountOut = getAmountOutMin(tokenIn, amountIn, tokenOut, poolToConsider); } function getAmountOutMin( address tokenIn, uint128 amountIn, address tokenOut, address poolToConsider ) internal view returns (uint amountOut) { uint32[] memory secondsAgos = new uint32[](2); secondsAgos[0] = secondsAgo; secondsAgos[1] = 0; // int56 since tick * time = int24 * uint32 // 56 = 24 + 32 (int56[] memory tickCumulatives, ) = IUniswapV3Pool(poolToConsider).observe( secondsAgos ); int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0]; // int56 / uint32 = int24 // int24 tick = int24(tickCumulativesDelta / secondsAgo); int24 tick = int24(tickCumulativesDelta / int56(int32(secondsAgo))); // Always round to negative infinity /* int doesn't round down when it is negative int56 a = -3 -3 / 10 = -3.3333... so round down to -4 but we get a / 10 = -3 so if tickCumulativeDelta < 0 and division has remainder, then round down */ if ( tickCumulativesDelta < 0 && (tickCumulativesDelta % int56(int32(secondsAgo)) != 0) ) { tick--; } amountOut = OracleLibrary.getQuoteAtTick(tick, amountIn, tokenIn, tokenOut); } /** * @notice Increases the observation cardinality for a Uniswap V3 pool. * @dev This function is used to adjust the observation cardinality for improved price accuracy. * @param _pool Address of the Uniswap V3 pool. * @param observationCardinalityNext New observation cardinality to set. */ function increaseObservation( address _pool, uint16 observationCardinalityNext ) external { IUniswapV3Pool(_pool).increaseObservationCardinalityNext( observationCardinalityNext ); } /** * @notice Updates the time interval in seconds for retrieving historical prices. * @dev Only the contract owner can call this function. * @param sec New time interval in seconds. */ function updateSecAgo(uint32 sec) external onlyOwner { secondsAgo = sec; } function getSecAgo() external view returns (uint256) { return secondsAgo; } /** * @notice Updates the global fees for Uniswap V3 pool operations. * @dev Only the contract owner can call this function. * @param fees New fee value to set for the token pair. */ function updateGlobalFees( address[] memory tokenA, address[] memory tokenB, uint24[] memory fees ) external onlyOwner { for (uint i; i < fees.length; i++) { _fee[tokenA[i]][tokenB[i]] = fees[i]; } } /** * @notice Initializes the stale price delay for multiple underlying tokens. * @dev Only the contract owner can call this function. * @param underlyingTokens Array of underlying tokens. * @param _stalePriceDelay Array of stale price delays corresponding to each underlying token. */ function intializeStalePriceDelay( address[] memory underlyingTokens, uint256[] memory _stalePriceDelay ) external { require( msg.sender == owner() || msg.sender == IAFiManager(afiManager).rebalanceController(), "NA" ); require(underlyingTokens.length == _stalePriceDelay.length, "AFO011"); for (uint i = 0; i < underlyingTokens.length; i++) { setSPDelay(underlyingTokens[i], _stalePriceDelay[i]); } } /** * @notice Sets the stale price delay for a specific underlying token. * @dev Only the contract owner can call this function, and the current delay must be greater than 1 hour. * @param uToken Address of the underlying token. * @param _stalePriceDelay New stale price delay to set. */ function setStalePriceDelay( address uToken, uint256 _stalePriceDelay ) external onlyOwner { setSPDelay(uToken, _stalePriceDelay); } function setSPDelay(address uToken, uint256 _stalePriceDelay) internal { require(_stalePriceDelay > stalePricewindowLimit, "AFO01"); stalePriceDelay[uToken] = _stalePriceDelay; } function setstalepriceWindowLimit(uint256 _stalePWindow) external onlyOwner { stalePricewindowLimit = _stalePWindow; } function getstalepriceWindowLimit() external view returns (uint256) { return stalePricewindowLimit; } /** * @notice Gets the stale price delay for a specific underlying token. * @param uToken Address of the underlying token. * @return The stale price delay for the specified underlying token. */ function getStalePriceDelay(address uToken) external view returns (uint256) { return stalePriceDelay[uToken]; } /** * @notice Gets the price and decimals of a specified token from a price feed. * @param uToken Address of the underlying token. * @param feed Address of the price feed. * @return The price and decimals of the specified token. */ function getPriceAndDecimals( address uToken, address feed ) public view returns (int256, uint8) { (, int256 inPrice, , uint256 updatedAt, ) = AggregatorV3Interface(feed) .latestRoundData(); address currentPhaseAggregator = AggregatorV3Interface(feed).aggregator(); uint256 minPrice = AggregatorV3Interface(currentPhaseAggregator).minAnswer(); uint256 maxPrice = AggregatorV3Interface(currentPhaseAggregator).maxAnswer(); if (uint(inPrice) >= maxPrice || uint(inPrice) <= minPrice) revert("AFOOO"); uint8 decimals = AggregatorV3Interface(feed).decimals(); greaterComparison(updatedAt, block.timestamp - stalePriceDelay[uToken]); greaterComparison(uint(inPrice), 0); return (inPrice, decimals); } function getPriceOracleRebal(address tok) internal view returns (address) { return IPassiveRebal(rebal).getPriceOracle(tok); } /** * @notice Checks if the given token is USDC and retrieves its price and multiplier. * @param tok Address of the token to check price . * @return The token's price and multiplier. */ function getPriceInUSDC(address tok) public view returns (uint256, uint256) { uint256 multiplier = 1e6; uint256 price; // Transfer Aarna Token to investor if (tok != USDC) { address oracle = getPriceOracleRebal(tok); if (oracle != address(0)) { (int256 tokPrice, ) = getPriceAndDecimals(tok, oracle); (int256 usdcPrice, ) = getPriceAndDecimals(USDC, USDC_ORACLE); price = ((SafeCast.toUint256(tokPrice) * (10 ** 6)) / SafeCast.toUint256((usdcPrice))); } else { uint256 uTokensDecimal = IERC20(tok).decimals(); uint256 amountIn = 10 ** uTokensDecimal; price = getMinimumAmountOut(tok, amountIn, USDC, address(0)); } } else { price = 1; multiplier = 1; } return (price, multiplier); } function updateRebalContract(address _rebal) external onlyOwner { addressZero(_rebal); rebal = _rebal; } function getUniPool(address tok, address poolToken) internal view returns (address) { return IPassiveRebal(rebal).getPool(tok, poolToken); } function getMinimumAmountOut( address _tokenIn, uint256 _amountIn, address _tokenOut, address _uniPool ) internal view returns (uint256 amountOut) { address uniPool; if (_tokenIn == (WETH) || _tokenOut == (WETH)) { amountOut = estimateAmountOut(_tokenIn, uint128(_amountIn), _tokenOut); } else if ( _tokenIn == underlyingUniPoolToken[_tokenIn] || _tokenOut == underlyingUniPoolToken[_tokenIn] ) { uniPool = getUniPool(_tokenIn, underlyingUniPoolToken[_tokenIn]); if (_uniPool != address(0)) { uniPool = _uniPool; } amountOut = estimateAmounts( _tokenIn, _amountIn, underlyingUniPoolToken[_tokenIn], uniPool ); } else { uniPool = getUniPool(_tokenIn, underlyingUniPoolToken[_tokenIn]); address unipoolOut = getUniPool(_tokenOut, underlyingUniPoolToken[_tokenIn]); amountOut = estimateAmounts( _tokenIn, _amountIn, underlyingUniPoolToken[_tokenIn], uniPool ); amountOut = estimateAmounts( underlyingUniPoolToken[_tokenIn], amountOut, _tokenOut, unipoolOut ); } } function estimateAmounts( address intok, uint256 amt, address outTok, address uniPool ) internal view returns (uint256) { uint256 _amountOut = estimateAmountOutMin(intok, uint128(amt), outTok, uniPool); return _amountOut; } /** * @notice Updates the profit share parameters. * @dev Only the contract owner can call this function, and the contract must be unpaused. * @param _totalProfit Total profit percentage (<= 10). * @param _daoProfit DAO profit percentage (< _totalProfit). */ function updateProfitShare( uint _totalProfit, uint _daoProfit ) external onlyOwner contractUnpaused { require(_daoProfit <= _totalProfit && _totalProfit <= 10, "AM02"); daoProfit = _daoProfit; totalProfit = _totalProfit; emit ProfitShareUpdated(daoProfit, totalProfit); // Emit relevant event } function teamProfitshares( address _aFiStorage, address aFiContract, uint profitShare ) internal view returns (uint teamProfitShare) { uint totalActive = IAFiStorage(_aFiStorage).getTotalActiveWallets(aFiContract); if (totalActive > 1) { teamProfitShare = (profitShare * (totalProfit - daoProfit)) / ((totalActive - 1) * (totalProfit)); } } /** * @notice Distributes profit shares among team wallets for aFiContract. * @param aFiContract The address of the AFi contract. * @param _aFiStorage The address of the AFiStorage contract. * @param iToken An array of iToken addresses. * @return totalProfitShare The total profit share distributed. */ function unstakingProfitDistribution( address aFiContract, address _aFiStorage, address[] memory iToken ) external onlyOwner returns (uint totalProfitShare) { // Investor has made a profit, let us distribute the profit share amongst team wallet address[] memory _teamWallets = IAFiStorage(_aFiStorage).getTeamWalletsOfAFi( aFiContract ); uint256 teamProfitShare; uint256 profitShare; // Alpha Creator gets 4% of gain for (uint j; j < iToken.length; j++) { profitShare = teamWalletsProfit[aFiContract][iToken[j]]; if (profitShare > 0) { teamProfitShare = teamProfitshares(_aFiStorage, aFiContract, profitShare); { uint256 daoProfitShare; bool isActive; for (uint i = 0; i < _teamWallets.length; i++) { (isActive, ) = IAFiStorage(_aFiStorage).getTeamWalletDetails( aFiContract, _teamWallets[i] ); if (isActive) { if (i == 0) { // /** // Always at i==0 address must be of Aarna Dao // Aarna DAO gets 6% of gain // */ daoProfitShare = (profitShare * (daoProfit)) / (totalProfit); profitShare = daoProfitShare; } else { profitShare = teamProfitShare; } totalProfitShare = totalProfitShare + (profitShare); IERC20(iToken[j]).safeTransfer(_teamWallets[i], profitShare); emit ProfitShareDistributed(aFiContract, _teamWallets[i], profitShare); } } } } teamWalletsProfit[aFiContract][iToken[j]] = 0; } } function getAFiContracts() external view returns (IAFiStorage, address, address) { return (aFiStorage, rebal, afiManager); } function addressEqual(address add1, address add2) internal pure { require(add1 == add2, "AB30"); } /** * @notice Pauses / unpause deposits in the contract. * @dev Requirements: Can only be invoked by the Owner wallet. */ function pauseUnpauseQueue(address afiContract, bool status) external { addressEqual(msg.sender, cumulativeSwapControllers[afiContract]); queuePausedStatus[afiContract]= status; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorInterface { 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); event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); } interface AggregatorV2V3Interface is AggregatorInterface { } interface AggregatorV3Interface { struct Phase { uint16 id; AggregatorV2V3Interface aggregator; } 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 ); /** * @notice returns the current phase's aggregator address. */ function aggregator() external view returns (address); function minAnswer() external view returns(uint); function maxAnswer() external view returns(uint); }
// 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: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDiv( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then 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(a, b, not(0)) prod0 := mul(a, b) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { require(denominator > 0); assembly { result := div(prod0, denominator) } return result; } // 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] // Compute remainder using mulmod uint256 remainder; assembly { remainder := mulmod(a, b, denominator) } // Subtract 256 bit number from 512 bit number assembly { prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. uint256 twos = (0 - denominator) & denominator; // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } 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 // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use 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. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // 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 precoditions 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 * inv; return result; } } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { unchecked { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } } }
// SPDX-License-Identifier: Unlicensed pragma solidity ^0.8.0; import {IERC20Extended as IERC20} from "./IERC20Extended.sol"; import "./IAFiStorage.sol"; import "./IPassiveRebal.sol"; /** * @title PassiveRebal. * @notice Interface of the Passive Rebalance contract. */ interface PassiveRebal { function applyRebalForProportions( address _aFiContract, address _aFiManager, address _aFiStorage, address[] memory _tokens, uint256 strategy ) external returns (uint[] memory proportions, uint256); function getPauseStatus() external returns (bool); function getRebalStrategyNumber(address aFiContract) external returns (uint); } interface IAFiOracle { function uniswapV3Oracle( address afiContract, address _tokenIn, address _tokenOut, uint _amountIn, uint _maxTime, address middleToken, uint256 minimumReturnAmount ) external returns (bytes memory swapParams); } interface IAFiManager { function updateUTokenProportion( address aFiContract, address aFiStorage ) external returns (uint256[] memory); function inputTokenUSD( IAFi aFiContract, uint256 cSwapCounter, IAFiStorage _aFiStorage ) external view returns (uint256 totalPreDepositInUSD); function rebalanceController() external view returns(address); function pauseQueueWithdrawUnstaking(address afiContract,bool status) external; function isQueueWithdrawUnstakingPaused(address afiContract) external view returns(bool); } /** * @title IAFi. * @notice Interface of the AToken. */ interface IAFi { struct UnderlyingData { address[] _underlyingTokens; //uTokens address[] _underlyingUniPoolToken; //uToken - MiddleToken } struct PoolsData { address[] _depositStableCoin; address[] _depositCoinOracle; bytes underlyingData; address[] _compound; address[] _aaveToken; address[] _priceOracles; uint[] _underlyingTokensProportion; address[] compoundV3Comet; uint _typeOfProduct; } struct SwapParameters { address afiContract; address oToken; uint256 cSwapFee; uint256 cSwapCounter; address[] depositTokens; uint256[] minimumReturnAmount; uint256[] iMinimumReturnAmount; // minimum amount out expcted after swaps For deposit tokens address[] underlyingTokens; uint256[] newProviders; uint _deadline; address[] cometToClaim; address[] cometRewardTokens; uint256[] rewardTokenMinReturnAmounts; } /** * @notice Function to initialize the data, owner and afi token related data. * @dev the function should be called once only by factory * @param newOwner indicates the owner of the created afi product. * @param _name indicates the name of the afi Token * @param _symbol indicates symbol of the the afi Token. * @param data indicates the encoded data that follows the PoolsData struct format. * @param _isActiveRebalanced indicates the active rebalance status of the afi contract. * @param _aFiStorage indicates the afi storage contract address. */ function initialize( address newOwner, string memory _name, string memory _symbol, bytes memory data, bool _isActiveRebalanced, IAFiStorage _aFiStorage, address[] memory _commonInputTokens ) external; /** * @notice Function to initialize accepted tokens in deposit and withdraw functions. * @dev the function should be called once only by factory * @param iToken indicates the array of the accepted token addressess. */ function initializeToken( address[] memory iToken, address[] memory _teamWallets, IPassiveRebal _rebalContract, address _aFiManager ) external; function getcSwapCounter() external view returns(uint256); /** * @notice Returns the array of underlying tokens. * @return uTokensArray Array of underlying tokens. */ function getUTokens() external view returns (address[] memory uTokensArray); function swapViaStorageOrManager( address from, address to, uint amount, uint deadline, address midTok, uint minimumReturnAmount ) external returns (uint256); /** * @notice Returns the paused status of the contract. */ function isPaused() external view returns (bool, bool); function getProportions() external view returns (uint[] memory, uint[] memory); /** * @notice Updates the pool data during Active Rebalance. * @param data that follows PoolsData format indicates the data of the token being rebalanced in Active Rebalance. */ function updatePoolData(bytes memory data) external; function sendProfitOrFeeToManager( address wallet, uint profitShare, address oToken ) external; function _supplyCompV3(address tok, uint amount) external; function _supplyAave(address tok, uint amount) external; function _supplyCompound(address tok, uint amount) external; function _withdrawAave(address tok, uint amount) external; function _withdrawCompoundV3(address tok, uint amount) external; function _withdrawCompound(address tok, uint amount) external; function getTVLandRebalContractandType() external view returns (uint256, address, uint256); function getInputToken() external view returns (address[] memory, address[] memory); function swap( address inputToken, address uTok, uint256 amountAsPerProportion, uint _deadline, address middleToken, uint256 minimumReturnAmount ) external returns (uint256); function updateDp( uint256[] memory _defaultProportion, uint256[] memory _uTokensProportion ) external; function updateuTokAndProp( address[] memory _uTokens ) external; function underlyingTokensStaking(address[] memory _depositTokens) external returns(uint256 _totalProp); function depositUserNav(address user) external view returns (uint256); function setUnstakeData(uint256 totalQueuedShares) external returns (address[] memory, address[] memory, uint256, uint256); function isOTokenWhitelisted(address oToken) external view returns (bool); function validateWithdraw(address user, address oToken, uint256 _shares) external; function updateLockedTokens( address user, uint256 amount, bool lock, bool queue, bool unqueue, uint256 newNAV ) external; function checkTVL(bool _updateTVL) external; function updateInputTokens(address[] memory _inputTokens) external; function reinitializeHappened(bool status) external; function getPreSwapDepositLimit() external view returns(uint256); function pauseUnpauseDeposit(bool status) external; }
// SPDX-License-Identifier: Unlicensed pragma solidity ^0.8.0; /** * @title IAFiStorage. * @notice Interface of the AFiStorage. */ interface IIEarnManager { function recommend( address _token, address afiBase, address afiStorage ) external view returns (string memory choice, uint capr, uint aapr, uint dapr); } interface IAFiStorage { /** * @notice Struct representing investor details. * @param isPresent Boolean indicating whether an investor exists. * @param uTokenBalance Investor underlying token balance. * @param investedAmount Amount of StableCoin invested in the underlying token */ struct Investor { bool isPresent; uint depositNAV; uint redemptionNAV; } struct RedemptionParams { address baseContract; uint r; address oToken; uint256 cSwapCounter; address[] uTokens; address[] iTokens; uint256 deadline; uint256[] minimumReturnAmount; uint256 _pool; uint256 tSupply; uint256 depositNAV; } /** * @notice Struct representing TeamWallet details. * @param isPresent Boolean indicating whether a wallet exists. * @param isActive Boolean indicating whether a wallet is active. * @param walletAddress Wallet address. */ struct TeamWallet { bool isPresent; bool isActive; address walletAddress; } /** * @notice Struct representing Rebalance details. * @param scenario Scenario can be either of 0, 1 or 2. * @param rebalancedUToken Address of the underlying token that is rebalanced. * @param rebalancedToUTokens Array of addresses of underlying tokens to which the uToken has been rebalanced. */ struct RebalanceDetails { uint8 scenario; address rebalancedUToken; address[] rebalancedToUTokens; } /** * @param walletAddress Address of the wallet. * @param isActive Boolean indicating wallet active status. */ event TeamWalletActive(address indexed walletAddress, bool isActive); /** * @param walletAddress Address of the wallet. * @param isActive Boolean indicating wallet active status. */ event TeamWalletAdd(address indexed walletAddress, bool isActive); /** * @notice Returns the team wallet details. * @param aFiContract Address of the AFi contract. * @param _wallet Wallet address * @return isPresent Boolean indicating the present status of the wallet. * @return isActive Boolean indicating whether to set the wallet to either active/inactive. */ function getTeamWalletDetails( address aFiContract, address _wallet ) external view returns (bool isPresent, bool isActive); function handleRedemption(RedemptionParams memory params, uint _shares, uint swapMethod) external returns (uint256 redemptionFromContract); /** * @notice To add a new team wallet. * @param aFiContract Address of the AFi contract. * @param _wallet Wallet address that has to be added in the `teamWallets` array. * @param isActive Boolean indicating whether to set the wallet to either active/inactive. * @param isPresent Boolean indicating the present status of the wallet. */ function addTeamWallet( address aFiContract, address _wallet, bool isActive, bool isPresent ) external; /** * @notice Returns the team wallets for an AFi. * @param aFiContract Address of the AFi contract. * @return _teamWallets Array of teamWallets. */ function getTeamWalletsOfAFi( address aFiContract ) external view returns (address[] memory _teamWallets); /** * @notice Sets the address for team wallets. * @param aFiContract Address of the AFi contract. * @param _teamWallets Array of addresses for the team wallets. */ function setTeamWallets(address aFiContract, address[] memory _teamWallets) external; /** * @notice Sets the status for the AFi in the storage contract. * @param aFiContract Address of the AFi contract. * @param active status for afiContracts. */ function setAFiActive(address aFiContract, bool active) external; /** * @notice Sets Active Rebalance status of an AFi. * @param aFiContract Address of the AFi contract. * @param status indicating active rebalance status of the AFi contract. */ function setActiveRebalancedStatus(address aFiContract, bool status) external; /** * @notice gets Active Rebalance status of an AFi. * @param aFiContract Address of the AFi contract. * @return _isActiveRebalanced bool indicating active rebalance status of the AFi contract. */ function isAFiActiveRebalanced( address aFiContract ) external view returns (bool _isActiveRebalanced); function getTotalActiveWallets(address aFiContract) external view returns (uint); function calcPoolValue( address tok, address afiContract ) external view returns (uint); function calculateBalanceOfUnderlying( address tok, address afiContract ) external view returns (uint); function calculatePoolInUsd(address afiContract) external view returns (uint); function afiSync( address afiContract, address tok, address aaveTok, address compV3Comet, address compTok ) external; function getPriceInUSDC( address tok ) external view returns (uint256, uint256); function validateAndGetDecimals(address tok) external view returns (uint256); function getStakedStatus( address aFiContract, address uToken ) external view returns (bool); function rearrange(address aFiContract,address[] memory underlyingTokens, uint256[] memory newProviders) external; function swapForOtherProduct( address afiContract, uint r, address oToken, uint deadline, uint[] memory minimumReturnAmount, address[] memory uToken ) external returns (uint256); function _withdrawAll(address afiContract, address tok) external returns(bool); function getAFiOracle() external view returns(address); function calculateRedemptionFromContract( address afiContract, address tok, uint256 r ) external view returns (uint256, bool, uint256, uint256, uint256); function tvlRead( address tok, address afiContract ) external view returns (uint, uint256); function getPreSwapDepositsTokens( address aFiContract, uint256 _cSwapCounter, address stableToken ) external view returns (uint256); function setPreDepositedInputToken(uint256 _cSwapCounter, uint256 _amount,address _oToken) external; function setPreDepositedInputTokenInRebalance( address aficontract, uint256 _cSwapCounter, uint256 _amount, address _oToken ) external; function convertInUSDAndTok( address tok, uint256 amt, bool usd ) external view returns (uint256); function calculateShares( address afiContract, uint256 amount, uint256 prevPool, uint256 _totalSupply, address iToken, uint256 currentDepositNAV, uint256 prevBalance ) external view returns (uint256 shares, uint256 newDepositNAV); function deletePreDepositedInputToken( address aFiContract, address oToken, uint256 currentCounter )external; function doSwapForThewhiteListRemoval( address tok, uint256 _cSwapCounter, address swapToken, uint256 deadline, uint256 minAmountOut ) external; function isSwapMethodPaused(address afiContract,uint swapMethod) external view returns (bool); }
// 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: Unlicensed pragma solidity ^0.8.0; import "./IERC20.sol"; interface IERC20Extended is IERC20 { function decimals() external view returns (uint8); }
// SPDX-License-Identifier: Unlicensed pragma solidity ^0.8.0; interface IPassiveRebal { function applyRebalForProportions( address _aFiContract, address _aFiManager, address _aFiStorage, address[] memory _tokens, uint256 strategy ) external returns (uint[] memory proportions, uint256 totalProp); function getPauseStatus() external returns (bool); function getRebalStrategyNumber(address aFiContract) external returns (uint); function uniswapV3Oracle( address afiContract, address _tokenIn, address _tokenOut, uint _amountIn, uint _maxTime, address middleToken, uint256 minimumReturnAmount ) external returns (bytes memory swapParams); function getPool(address tok, address midTok) external view returns (address); function upDateInputTokPool(address[] memory iToken, bytes memory uniData) external; function getPriceOracle(address tok) external view returns (address); function updateOracleData( address _uToken, address _oracleAddress ) external; function removeToken( address[] memory _nonOverlappingITokens, address token ) external pure returns (address[] memory); function initUniStructure( address[] memory inputTokens, bytes memory _poolData ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; } /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title The interface for the Uniswap V3 Factory /// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees interface IUniswapV3Factory { /// @notice Emitted when the owner of the factory is changed /// @param oldOwner The owner before the owner was changed /// @param newOwner The owner after the owner was changed event OwnerChanged(address indexed oldOwner, address indexed newOwner); /// @notice Emitted when a pool is created /// @param token0 The first token of the pool by address sort order /// @param token1 The second token of the pool by address sort order /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip /// @param tickSpacing The minimum number of ticks between initialized ticks /// @param pool The address of the created pool event PoolCreated( address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool ); /// @notice Emitted when a new fee amount is enabled for pool creation via the factory /// @param fee The enabled fee, denominated in hundredths of a bip /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing); /// @notice Returns the current owner of the factory /// @dev Can be changed by the current owner via setOwner /// @return The address of the factory owner function owner() external view returns (address); /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee /// @return The tick spacing function feeAmountTickSpacing(uint24 fee) external view returns (int24); /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order /// @param tokenA The contract address of either token0 or token1 /// @param tokenB The contract address of the other token /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip /// @return pool The pool address function getPool( address tokenA, address tokenB, uint24 fee ) external view returns (address pool); /// @notice Creates a pool for the given two tokens and fee /// @param tokenA One of the two tokens in the desired pool /// @param tokenB The other of the two tokens in the desired pool /// @param fee The desired fee for the pool /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments /// are invalid. /// @return pool The address of the newly created pool function createPool( address tokenA, address tokenB, uint24 fee ) external returns (address pool); /// @notice Updates the owner of the factory /// @dev Must be called by the current owner /// @param _owner The new owner of the factory function setOwner(address _owner) external; /// @notice Enables a fee amount with the given tickSpacing /// @dev Fee amounts may never be removed once enabled /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6) /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount function enableFeeAmount(uint24 fee, int24 tickSpacing) external; } interface IUniswapV3Pool { function observe( uint32[] calldata secondsAgos ) external view returns ( int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s ); function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external; function fee() external returns(uint24); }
// SPDX-License-Identifier: Unlicensed pragma solidity ^0.8.0; import "./TickMath.sol"; import "./FullMath.sol"; library OracleLibrary { /// @notice Given a tick and a token amount, calculates the amount of token received in exchange /// @param tick Tick value used to calculate the quote /// @param baseAmount Amount of token to be converted /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken function getQuoteAtTick( int24 tick, uint128 baseAmount, address baseToken, address quoteToken ) internal pure returns (uint256 quoteAmount) { uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick); // Calculate quoteAmount with better precision if it doesn't overflow when multiplied by itself if (sqrtRatioX96 <= type(uint128).max) { uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96; quoteAmount = baseToken < quoteToken ? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192) : FullMath.mulDiv(1 << 192, baseAmount, ratioX192); } else { uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64); quoteAmount = baseToken < quoteToken ? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128) : FullMath.mulDiv(1 << 128, baseAmount, ratioX128); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address internal _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } // /** // * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. // * Can only be called by the current owner. // */ // function transferOwnership(address newOwner) public virtual override onlyOwner { // _pendingOwner = newOwner; // emit OwnershipTransferStarted(owner(), newOwner); // } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() external { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Ownable2Step} from "./Ownable2Step.sol"; contract OwnableDelayModule is Ownable2Step { address internal delayModule; constructor() { delayModule = msg.sender; } function isDelayModule() internal view { require(msg.sender == delayModule, "NA"); } function setDelayModule(address _delayModule) external { isDelayModule(); require(_delayModule != address(0), "ODZ"); delayModule = _delayModule; } function getDelayModule() external view returns (address) { return delayModule; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public override { isDelayModule(); _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } }
// 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: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./draft-IERC20Permit.sol"; import "./Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; /// @title Math library for computing sqrt prices from ticks and vice versa /// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports /// prices between 2**-128 and 2**128 library TickMath { error T(); error R(); /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 int24 internal constant MIN_TICK = -887272; /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 int24 internal constant MAX_TICK = -MIN_TICK; /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK) uint160 internal constant MIN_SQRT_RATIO = 4295128739; /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK) uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; /// @notice Calculates sqrt(1.0001^tick) * 2^96 /// @dev Throws if |tick| > max tick /// @param tick The input tick for the above formula /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0) /// at the given tick function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) { unchecked { uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick)); if (absTick > uint256(int256(MAX_TICK))) revert T(); uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000; if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128; if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; if (tick > 0) ratio = type(uint256).max / ratio; // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. // we then downcast because we know the result always fits within 160 bits due to our tick input constraint // we round up in the division so getTickAtSqrtRatio of the output price is always consistent sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); } } /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may /// ever return. /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96 /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) { unchecked { // second inequality must be < because the price can never reach the price at the max tick if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R(); uint256 ratio = uint256(sqrtPriceX96) << 32; uint256 r = ratio; uint256 msb = 0; assembly { let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(5, gt(r, 0xFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(4, gt(r, 0xFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(3, gt(r, 0xFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(2, gt(r, 0xF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(1, gt(r, 0x3)) msb := or(msb, f) r := shr(f, r) } assembly { let f := gt(r, 0x1) msb := or(msb, f) } if (msb >= 128) r = ratio >> (msb - 127); else r = ratio << (127 - msb); int256 log_2 = (int256(msb) - 128) << 64; assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(63, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(62, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(61, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(60, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(59, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(58, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(57, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(56, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(55, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(54, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(53, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(52, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(51, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(50, f)) } int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"passiveRebalContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"T","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"aFiContract","type":"address"},{"indexed":true,"internalType":"address","name":"teamWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProfitShareDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"daoProfit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalProfit","type":"uint256"}],"name":"ProfitShareUpdated","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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawCounter","type":"uint256"}],"name":"WithdrawDeQueue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"address","name":"oToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawCounter","type":"uint256"}],"name":"WithdrawQueue","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"_fee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"batchWithdrawCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"address","name":"oToken","type":"address"},{"internalType":"uint256","name":"cSwapFee","type":"uint256"},{"internalType":"uint256","name":"cSwapCounter","type":"uint256"},{"internalType":"address[]","name":"depositTokens","type":"address[]"},{"internalType":"uint256[]","name":"minimumReturnAmount","type":"uint256[]"},{"internalType":"uint256[]","name":"iMinimumReturnAmount","type":"uint256[]"},{"internalType":"address[]","name":"underlyingTokens","type":"address[]"},{"internalType":"uint256[]","name":"newProviders","type":"uint256[]"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"address[]","name":"cometToClaim","type":"address[]"},{"internalType":"address[]","name":"cometRewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardTokenMinReturnAmounts","type":"uint256[]"}],"internalType":"struct IAFi.SwapParameters","name":"params","type":"tuple"}],"name":"cumulativeSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"estimateAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint128","name":"amountIn","type":"uint128"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"address","name":"poolToConsider","type":"address"}],"name":"estimateAmountOutMin","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAFiContracts","outputs":[{"internalType":"contract IAFiStorage","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"}],"name":"getControllers","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDaoProfit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDelayModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeDetails","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"}],"name":"getLastSwapTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tok","type":"address"}],"name":"getMidToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"uToken","type":"address"},{"internalType":"address","name":"feed","type":"address"}],"name":"getPriceAndDecimals","outputs":[{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tok","type":"address"}],"name":"getPriceInUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSecAgo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"uToken","type":"address"}],"name":"getStalePriceDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"}],"name":"getSwapPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalProfit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"address","name":"oToken","type":"address"},{"internalType":"uint256","name":"bCounter","type":"uint256"}],"name":"getUserQueuedNAV","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"address","name":"oToken","type":"address"},{"internalType":"uint256","name":"bCounter","type":"uint256"}],"name":"getUserQueuedShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getstalepriceWindowLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"uint16","name":"observationCardinalityNext","type":"uint16"}],"name":"increaseObservation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"underlyingTokens","type":"address[]"},{"internalType":"uint256[]","name":"_stalePriceDelay","type":"uint256[]"}],"name":"intializeStalePriceDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"outputTokenUnits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"pauseUnpauseQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"queuePausedStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"address","name":"oToken","type":"address"}],"name":"queueWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IAFi","name":"aFiContract","type":"address"},{"internalType":"address[]","name":"_iTokens","type":"address[]"},{"internalType":"uint256","name":"batchWithdrawIndex","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_storage","type":"address"}],"name":"setAFiStorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delayModule","type":"address"}],"name":"setDelayModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"uToken","type":"address"},{"internalType":"uint256","name":"_stalePriceDelay","type":"uint256"}],"name":"setStalePriceDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_csFee","type":"uint256"}],"name":"setcsFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_csFeeUpperLimit","type":"uint256"}],"name":"setcsFeeUpperLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stalePWindow","type":"uint256"}],"name":"setstalepriceWindowLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalQueuedShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"address","name":"oToken","type":"address"}],"name":"unqueueWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"address","name":"oToken","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256[]","name":"minimumReturnAmount","type":"uint256[]"},{"internalType":"uint256[]","name":"minOutForiToken","type":"uint256[]"},{"internalType":"bool","name":"_updateTVL","type":"bool"}],"name":"unstakeForQueuedWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"aFiContract","type":"address"},{"internalType":"address","name":"_aFiStorage","type":"address"},{"internalType":"address[]","name":"iToken","type":"address[]"}],"name":"unstakingProfitDistribution","outputs":[{"internalType":"uint256","name":"totalProfitShare","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_afiManager","type":"address"}],"name":"updateAFiManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenA","type":"address[]"},{"internalType":"address[]","name":"tokenB","type":"address[]"},{"internalType":"uint24[]","name":"fees","type":"uint24[]"}],"name":"updateGlobalFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tok","type":"address[]"},{"internalType":"address[]","name":"midTok","type":"address[]"}],"name":"updateMidToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalProfit","type":"uint256"},{"internalType":"uint256","name":"_daoProfit","type":"uint256"}],"name":"updateProfitShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rebal","type":"address"}],"name":"updateRebalContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"sec","type":"uint32"}],"name":"updateSecAgo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"uint256","name":"_newSwapPeiod","type":"uint256"}],"name":"updateSwapPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"afiContract","type":"address"},{"internalType":"address","name":"_cumulativeSwapController","type":"address"},{"internalType":"address","name":"_unstakingController","type":"address"}],"name":"updateVaultControllers","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526006805463ffffffff1916610384178155681b1ae4d6e2ef50000060075569010f0cf064dd59200000600855610e10600a908155600b91909155600c5534801561004c575f80fd5b50604051615cb4380380615cb483398101604081905261006b9161016d565b60015f55610078336100b8565b600380546001600160a01b03191633179055610093816100d4565b600980546001600160a01b0319166001600160a01b039290921691909117905561019a565b600280546001600160a01b03191690556100d18161011c565b50565b6001600160a01b0381166100d15760405162461bcd60e51b8152600401610113906020808252600490820152634146303360e01b604082015260600190565b60405180910390fd5b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f6020828403121561017d575f80fd5b81516001600160a01b0381168114610193575f80fd5b9392505050565b615b0d806101a75f395ff3fe608060405234801561000f575f80fd5b506004361061034b575f3560e01c80638456cb59116101c9578063ca60d67e116100fe578063ef1306c41161009e578063f7b188a511610079578063f7b188a51461084d578063fcee4f0114610855578063fd6046d714610885578063ff166c06146108e1575f80fd5b8063ef1306c414610814578063f2fde38b14610827578063f3c073da1461083a575f80fd5b8063df588dc4116100d9578063df588dc414610785578063e30c397814610798578063e8eec12c146107a9578063ec4b4985146107c8575f80fd5b8063ca60d67e1461074e578063d7f5870314610761578063da540ca014610772575f80fd5b8063b52a9e4911610169578063bf817c2111610144578063bf817c211461070d578063c20713fe14610715578063c253301314610728578063c4aa09d31461073b575f80fd5b8063b52a9e49146106ae578063b810c636146106c1578063bbeed008146106dd575f80fd5b806396722061116101a457806396722061146106555780639e8d371014610668578063a9a4cbcc14610693578063ae1f64891461069b575f80fd5b80638456cb59146106005780638da5cb5b146106085780638ede7b6e1461062d575f80fd5b806348a3e9131161029f5780636a40c2c31161023f578063715018a61161021a578063715018a6146105ca578063728be284146105d257806379ba5097146105e5578063813fb457146105ed575f80fd5b80636a40c2c3146105825780636d1a95d3146105955780636f52213a146105b7575f80fd5b80634fc9135c1161027a5780634fc9135c14610511578063502f7a86146105445780635190b08c146105525780635c975abb14610565575f80fd5b806348a3e913146104ce57806349e71eab146104d65780634ab2c028146104fe575f80fd5b80631ea75b411161030a5780632ccea637116102e55780632ccea6371461043b5780632efd3ee71461044e5780633c460b0b1461049157806347155a0e146104a4575f80fd5b80631ea75b4114610402578063255c3e8f14610415578063291217d114610428575f80fd5b8062acf0bc1461034f578062cc39b81461036457806301b8acd3146103775780630727e4e41461038a5780630b917d121461039d5780631d8b0fa5146103da575b5f80fd5b61036261035d366004614af6565b6108f4565b005b610362610372366004614cdd565b610e5a565b610362610385366004614d80565b61122b565b610362610398366004614e74565b6112ed565b6103c76103ab366004614ed7565b601c60209081525f928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6103c76103e8366004614f01565b6001600160a01b03165f9081526017602052604090205490565b610362610410366004614f1c565b611434565b610362610423366004614f1c565b61147c565b610362610436366004614f33565b611489565b610362610449366004614f72565b611794565b61047d61045c366004614faf565b600560209081525f928352604080842090915290825290205462ffffff1681565b60405162ffffff90911681526020016103d1565b61036261049f366004614ed7565b6117df565b6104b76104b2366004614faf565b611802565b6040805192835260ff9091166020830152016103d1565b600b546103c7565b6103c76104e4366004614f01565b6001600160a01b03165f9081526016602052604090205490565b61036261050c366004614fe6565b611a85565b600454600954601054604080516001600160a01b03948516815292841660208401529216918101919091526060016103d1565b60065463ffffffff166103c7565b6103c761056036600461502e565b611ae1565b600d546105729060ff1681565b60405190151581526020016103d1565b610362610590366004614faf565b611bb3565b6105726105a3366004614f01565b601e6020525f908152604090205460ff1681565b6103c76105c5366004615059565b611f2b565b610362611f41565b6103626105e0366004614ed7565b611f54565b610362611f66565b6103626105fb366004614f01565b611fe0565b610362612013565b6001546001600160a01b03165b6040516001600160a01b0390911681526020016103d1565b6103c761063b366004614f01565b6001600160a01b03165f9081526015602052604090205490565b6103c76106633660046150b0565b61206e565b610615610676366004614f01565b6001600160a01b039081165f908152601860205260409020541690565b600c546103c7565b6103626106a93660046150fe565b6120ae565b6103626106bc366004614f01565b612230565b6007546008545b604080519283526020830191909152016103d1565b6103c76106eb366004615157565b601960209081525f938452604080852082529284528284209052825290205481565b600a546103c7565b610362610723366004615195565b612263565b610362610736366004614f01565b6126a1565b610362610749366004614f01565b6126d4565b61036261075c3660046151ea565b61273a565b6003546001600160a01b0316610615565b6106c8610780366004614f01565b61275e565b61036261079336600461520d565b6128c9565b6002546001600160a01b0316610615565b6103c76107b7366004614f01565b601b6020525f908152604090205481565b6103c76107d63660046150b0565b6001600160a01b039384165f908152601360209081526040808320958716835294815284822093909516815291845282822090825290925290205490565b610362610822366004614f1c565b612918565b610362610835366004614f01565b612925565b610362610848366004615239565b612996565b610362612a3b565b6103c7610863366004615157565b601a60209081525f938452604080852082529284528284209052825290205481565b6108c1610893366004614f01565b6001600160a01b039081165f9081526011602090815260408083205460129092529091205490821692911690565b604080516001600160a01b039384168152929091166020830152016103d1565b6103c76108ef366004615259565b612a8c565b80516001600160a01b039081165f908152601160205260409020541633148061092757506010546001600160a01b031633145b61094c5760405162461bcd60e51b8152600401610943906152b6565b60405180910390fd5b80516001600160a01b039081165f9081526017602090815260408083205485519094168352601690915290205461098390426152e6565b10156109d15760405162461bcd60e51b815260206004820152601760248201527f5377617020706572696f64206e6f7420656c61707365640000000000000000006044820152606401610943565b5f815f01516001600160a01b031663b187bd266040518163ffffffff1660e01b81526004016040805180830381865afa158015610a10573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a3491906152f9565b509050610a4081612d6f565b610a6b6040518060800160405280606081526020016060815260200160608152602001606081525090565b825f01516001600160a01b031663e52e43da6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610aa9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ad0919081019061538a565b508360800181905250825f01516001600160a01b031663d61daa616040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3c91906153e3565b836060018181525050825f01516001600160a01b031663292252886040518163ffffffff1660e01b81526004015f60405180830381865afa158015610b83573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610baa91908101906153fa565b6020820181905251610bf75760405162461bcd60e51b815260206004820152601660248201527514995a5b9a5d1a585b1a5e99481d1a19481d985d5b1d60521b6044820152606401610943565b6101608301515115610c2c57610c2c835f01518461014001518561016001518661018001518760200151886101200151612da4565b8251608084015160405163e353d30360e01b81525f926001600160a01b03169163e353d30391610c5f919060040161546e565b6020604051808303815f875af1158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f91906153e3565b9050835f01516001600160a01b031663cdc7fcc26040518163ffffffff1660e01b81526004015f60405180830381865afa158015610cdf573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d0691908101906154db565b60608401526040830152610d1b848383613026565b60048054855160e087015161010088015160405163e899317560e01b81526001600160a01b039094169463e899317594610d589493929101615564565b5f604051808303815f87803b158015610d6f575f80fd5b505af1158015610d81573d5f803e3d5ffd5b505085516001600160a01b039081165f90815260166020526040808220429055885190516386a0da7360e01b8152600481019290925290911692506386a0da7391506024015f604051808303815f87803b158015610ddd575f80fd5b505af1158015610def573d5f803e3d5ffd5b5050601054865160405163c4d2958b60e01b81526001600160a01b0391821660048201525f60248201529116925063c4d2958b91506044015f604051808303815f87803b158015610e3e575f80fd5b505af1158015610e50573d5f803e3d5ffd5b5050505050505050565b6001600160a01b038087165f90815260126020526040902054610e7f913391166131f9565b6001600160a01b0386165f908152601e6020526040902054610ea39060ff16612d6f565b60405163acc8860760e01b81526001600160a01b038681166004830152610f15919088169063acc8860790602401602060405180830381865afa158015610eec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f109190615599565b612d6f565b601054604051632eaabf7760e21b81526001600160a01b0388811660048301529091169063baaafddc90602401602060405180830381865afa158015610f5d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f819190615599565b15610fbe5760405162461bcd60e51b815260206004820152600d60248201526c10d85b1b0810d4c8199a5c9cdd609a1b6044820152606401610943565b604051637b77ba2f60e01b815281151560048201526001600160a01b03871690637b77ba2f906024015f604051808303815f87803b158015610ffe575f80fd5b505af1158015611010573d5f803e3d5ffd5b505050506001600160a01b0386165f818152601c60209081526040808320601b835281842054845290915280822054905160016267399760e01b0319815260048101919091529091829163ff98c669906024015f604051808303815f875af115801561107e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526110a591908101906155b4565b8251919550935084908490600e905f906110c690600f906020880190614907565b505084516110d991906020870190614907565b505050506001600160a01b0389165f908152601c60209081526040808320601b8352818420548452909152812054909150156111cd576001600160a01b0389165f908152601c60209081526040808320601b835281842054845290915290205482906111459085615626565b61114f9190615651565b60048054604051630c18192560e21b81529293506001600160a01b03169163306064949161118a918d9186918e918e918e91600f9101615664565b6020604051808303815f875af11580156111a6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ca91906153e3565b90505b6111da898983888b613243565b6001600160a01b0389165f818152601c60209081526040808320601b8084528285208054865291845291842084905593835290528154919061121b836156ef565b9190505550505050505050505050565b61123361361b565b5f5b81518110156112e75781818151811061125057611250615707565b602002602001015160055f86848151811061126d5761126d615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8584815181106112a7576112a7615707565b6020908102919091018101516001600160a01b031682528101919091526040015f20805462ffffff191662ffffff92909216919091179055600101611235565b50505050565b6001546001600160a01b031633148061138a575060105f9054906101000a90046001600160a01b03166001600160a01b0316633495100a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611351573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611375919061571b565b6001600160a01b0316336001600160a01b0316145b6113a65760405162461bcd60e51b8152600401610943906152b6565b80518251146113e05760405162461bcd60e51b815260206004820152600660248201526541464f30313160d01b6044820152606401610943565b5f5b825181101561142f5761142783828151811061140057611400615707565b602002602001015183838151811061141a5761141a615707565b6020026020010151613675565b6001016113e2565b505050565b61143c61361b565b6008548111156114775760405162461bcd60e51b815260206004820152600660248201526541464f31313160d01b6044820152606401610943565b600755565b61148461361b565b600a55565b6114916136c9565b6001600160a01b0383165f908152601e60205260409020546114b69060ff1615612d6f565b60405163badd069b60e01b81523360048201526001600160a01b0382811660248301526044820184905284169063badd069b906064015f604051808303815f87803b158015611503575f80fd5b505af1158015611515573d5f803e3d5ffd5b5050335f8181526013602090815260408083206001600160a01b038a811680865291845282852090891685528352818420818552601b8452828520548552909252808320549051633ad3951560e21b8152600481019490945294509092509063eb4e545490602401602060405180830381865afa158015611598573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115bc91906153e3565b90506115c88483615736565b335f8181526013602090815260408083206001600160a01b038b8116808652918452828520908a16808652908452828520828652601b8552838620805487529085528386209790975594845260148352818420908452825280832093835292815282822093548252929092529020546116418584615736565b61164b8684615626565b6116558584615626565b61165f9190615736565b6116699190615651565b335f9081526014602090815260408083206001600160a01b038b8116808652918452828520908a16808652908452828520828652601b855283862080548752908552838620969096559084526019835281842090845282528083209354835292905290812080548792906116de908490615736565b90915550506001600160a01b0386165f908152601c60209081526040808320601b83528184205484529091528120805487929061171c908490615736565b90915550611731905086865f60018180613720565b6001600160a01b038681165f908152601b6020908152604091829020548251898152918201529186169133917fdd17a24176e09db37c0a70c6b1eb4522a450c150c57ce1a80bbf07c03b6b0cdd910160405180910390a350505061142f60015f55565b61179c61361b565b6001600160a01b039283165f90815260116020908152604080832080549587166001600160a01b0319968716179055601290915290208054919093169116179055565b6117e761361b565b6001600160a01b039091165f90815260176020526040902055565b5f805f80846001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611842573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118669190615762565b509350509250505f856001600160a01b031663245a7bfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce919061571b565b90505f816001600160a01b03166322adbc786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561190d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061193191906153e3565b90505f826001600160a01b03166370da2f676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611970573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199491906153e3565b905080851015806119a55750818511155b156119da5760405162461bcd60e51b815260206004820152600560248201526441464f4f4f60d81b6044820152606401610943565b5f886001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3b91906157b0565b6001600160a01b038b165f90815260156020526040902054909150611a6b908690611a6690426152e6565b6137a2565b611a75865f6137a2565b9499949850939650505050505050565b6040516332148f6760e01b815261ffff821660048201526001600160a01b038316906332148f67906024015f604051808303815f87803b158015611ac7575f80fd5b505af1158015611ad9573d5f803e3d5ffd5b505050505050565b6001600160a01b038381165f81815260056020908152604080832094861680845294909152808220549051630b4c774160e11b81526004810194909452602484019290925262ffffff9091166044830152908190731f98431c8ad98523631ae4a59f267346ea31f98490631698ee8290606401602060405180830381865afa158015611b6f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b93919061571b565b9050611b9e816137db565b611baa8585858461381a565b95945050505050565b611bbb6136c9565b6001600160a01b0382165f908152601e6020526040902054611be09060ff1615612d6f565b335f9081526013602090815260408083206001600160a01b0386811680865291845282852090861685528352818420908452601b835281842054845290915290205480611c5d5760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8145d595d595960aa1b6044820152606401610943565b6001600160a01b038084165f8181526019602090815260408083209487168352938152838220928252601b8152838220548252919091529081208054839290611ca79084906152e6565b90915550506001600160a01b0383165f908152601b6020526040902054611cd190849084906139c1565b6001600160a01b0383165f908152601c60209081526040808320601b835281842054845290915281208054839290611d0a9084906152e6565b9091555050335f8181526014602090815260408083206001600160a01b0388811680865291845282852090881685528352818420818552601b845282852054855290925280832080549084905590516370a0823160e01b815260048101949094528493909291906370a0823190602401602060405180830381865afa158015611d95573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611db991906153e3565b611dc39084615736565b6040516370a0823160e01b81523360048201526001600160a01b038816906370a0823190602401602060405180830381865afa158015611e05573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e2991906153e3565b604051633ad3951560e21b81523360048201526001600160a01b0389169063eb4e545490602401602060405180830381865afa158015611e6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e8f91906153e3565b611e999190615626565b611ea38585615626565b611ead9190615736565b611eb79190615651565b9050611ec886855f80600186613720565b6001600160a01b0386165f908152601b60209081526040918290205482518781529182015233917fa53a6125e3124d0deab3f226519dcdaaaee34541890e292ba99f3af26d0622f2910160405180910390a250505050611f2760015f55565b5050565b5f611f35826137db565b611baa8585858561381a565b611f4961361b565b611f525f6139fb565b565b611f5c61361b565b611f278282613675565b60025433906001600160a01b03168114611fd45760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610943565b611fdd816139fb565b50565b611fe861361b565b611ff1816137db565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b600d546120239060ff1615612d6f565b61202b61361b565b600d805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020015b60405180910390a1565b6001600160a01b038085165f908152601460209081526040808320878516845282528083209386168352928152828220848352905220545b949350505050565b6001546001600160a01b03163314806120d157506010546001600160a01b031633145b80612160575060105f9054906101000a90046001600160a01b03166001600160a01b0316633495100a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612127573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214b919061571b565b6001600160a01b0316336001600160a01b0316145b61217c5760405162461bcd60e51b8152600401610943906152b6565b5f5b825181101561142f576121a983828151811061219c5761219c615707565b60200260200101516137db565b6121be82828151811061219c5761219c615707565b8181815181106121d0576121d0615707565b602002602001015160185f8584815181106121ed576121ed615707565b6020908102919091018101516001600160a01b039081168352908201929092526040015f2080546001600160a01b0319169290911691909117905560010161217e565b61223861361b565b612241816137db565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383165f908152601b602052604090205481106122b25760405162461bcd60e51b815260040161094390602080825260049082015263414f303160e01b604082015260600190565b5f805f805f5b8651811015610e5057335f9081526013602090815260408083206001600160a01b038c168452909152812088519091908990849081106122fa576122fa615707565b6020908102919091018101516001600160a01b0390811683528282019390935260409182015f9081208a825282528281205433825260148352838220948d1682529390915290812089519295509189908490811061235a5761235a615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8781526020019081526020015f205491505f831115612699576001600160a01b0388165f90815260196020526040812088519091908990849081106123c9576123c9615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8781526020019081526020015f2054601a5f8a6001600160a01b03166001600160a01b031681526020019081526020015f205f89848151811061243657612436615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8881526020019081526020015f2054846124789190615626565b6124829190615651565b94505f806124a889848151811061249b5761249b615707565b602002602001015161275e565b915091505f8984815181106124bf576124bf615707565b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612502573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061252691906157b0565b6125319060126157d0565b905061253e81600a6158cc565b6125489084615626565b61255490612710615626565b8261255f8888615626565b6125699190615626565b6125739190615651565b96508688111561263a57600c5460649061258d898b6152e6565b6125979190615626565b6125a19190615651565b6001600160a01b038c165f908152601d602052604081208c519091908d90889081106125cf576125cf615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8282546126049190615736565b9091555050600c54606490612619898b6152e6565b6126239190615626565b61262d9190615651565b61263790896152e6565b97505b61265e8b8b868151811061265057612650615707565b60200260200101518b6139c1565b61269533898c878151811061267557612675615707565b60200260200101516001600160a01b0316613a149092919063ffffffff16565b5050505b6001016122b8565b6126a961361b565b6126b2816137db565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6126dc613a77565b6001600160a01b0381166127185760405162461bcd60e51b815260206004820152600360248201526227a22d60e91b6044820152606401610943565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61274261361b565b6006805463ffffffff191663ffffffff92909216919091179055565b5f80620f4240816001600160a01b03851673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48146128b9575f61279386613aa1565b90506001600160a01b0381161561281a575f6127af8783611802565b5090505f6127e573a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48738fffffd4afb6115b954bd326cbe7b4ba576818f6611802565b5090506127f181613b13565b6127fa83613b13565b61280790620f4240615626565b6128119190615651565b935050506128b3565b5f866001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612857573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061287b91906157b0565b60ff1690505f61288c82600a6158da565b90506128ae888273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485f613b68565b935050505b506128c0565b5060019050805b94909350915050565b6001600160a01b038083165f908152601160205260409020546128ee913391166131f9565b6001600160a01b03919091165f908152601e60205260409020805460ff1916911515919091179055565b61292061361b565b600855565b61292d613a77565b600280546001600160a01b0383166001600160a01b0319909116811790915561295e6001546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61299e61361b565b600d546129ae9060ff1615612d6f565b8181111580156129bf5750600a8211155b6129f45760405162461bcd60e51b81526004016109439060208082526004908201526320a6981960e11b604082015260600190565b600b819055600c82905560408051828152602081018490527fd2c1ad765e23a2310d15fab4c801a9baf192020787d20bca01731f76c03c5b4c910160405180910390a15050565b600d54612a4a9060ff16612d6f565b612a5261361b565b600d805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602001612064565b5f612a9561361b565b604051633450705160e11b81526001600160a01b0385811660048301525f91908516906368a0e0a2906024015f60405180830381865afa158015612adb573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612b0291908101906153fa565b90505f805f5b8551811015612d64576001600160a01b0388165f908152601d602052604081208751909190889084908110612b3f57612b3f615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205491505f821115612d0c57612b7c878984613d20565b92505f805f5b8651811015612d0857896001600160a01b0316637fd3086b8c898481518110612bad57612bad615707565b60200260200101516040518363ffffffff1660e01b8152600401612be79291906001600160a01b0392831681529116602082015260400190565b6040805180830381865afa158015612c01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c2591906152f9565b5091508115612d0057805f03612c5957600c54600b54612c459087615626565b612c4f9190615651565b9250829450612c5d565b8594505b612c678589615736565b9750612c99878281518110612c7e57612c7e615707565b6020026020010151868b878151811061267557612675615707565b868181518110612cab57612cab615707565b60200260200101516001600160a01b03168b6001600160a01b03167fde542754cbe64e85d7631fd8696b87e68cc3cc5521243efb5cb15687287ba4fa87604051612cf791815260200190565b60405180910390a35b600101612b82565b5050505b6001600160a01b0388165f908152601d6020526040812087518290899085908110612d3957612d39615707565b6020908102919091018101516001600160a01b031682528101919091526040015f2055600101612b08565b505050509392505050565b80611fdd5760405162461bcd60e51b81526020600482015260056024820152640828c9e60760db1b6044820152606401610943565b5f805f5b875160ff168160ff16101561301b57868160ff1681518110612dcc57612dcc615707565b60209081029190910101516040516370a0823160e01b81526001600160a01b038b81166004830152919350908316906370a0823190602401602060405180830381865afa158015612e1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e4391906153e3565b9250731b0e765f6224c21223aea2af16c1c46e38885a406001600160a01b031663b7034f7e898360ff1681518110612e7d57612e7d615707565b60209081029190910101516040516001600160e01b031960e084901b1681526001600160a01b039182166004820152908c166024820152600160448201526064015f604051808303815f87803b158015612ed5575f80fd5b505af1158015612ee7573d5f803e3d5ffd5b50506040516370a0823160e01b81526001600160a01b038c81166004830152869350851691506370a0823190602401602060405180830381865afa158015612f31573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f5591906153e3565b1115613013576040516370a0823160e01b81526001600160a01b038a811660048301528491908416906370a0823190602401602060405180830381865afa158015612fa2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fc691906153e3565b612fd091906152e6565b9250613011898387868873c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28c8860ff168151811061300457613004615707565b6020026020010151613ddb565b505b600101612da8565b505050505050505050565b5f805b84608001515181101561319e5760045485516060870151608088015180516001600160a01b03909416936327f746d7939291908690811061306c5761306c615707565b60200260200101516040518463ffffffff1660e01b81526004016130b0939291906001600160a01b0393841681526020810192909252909116604082015260600190565b602060405180830381865afa1580156130cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ef91906153e3565b915084602001516001600160a01b03168560800151828151811061311557613115615707565b60200260200101516001600160a01b03161415801561313357505f82115b1561319657613194855f01518660800151838151811061315557613155615707565b602002602001015187602001518589610120015173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b60c00151888151811061300457613004615707565b505b600101613029565b506007546131b8855f015186602001518760400151613e78565b11156131ee5760405162461bcd60e51b815260206004820152600560248201526441464f303160d81b6044820152606401610943565b6112e7848484613f61565b806001600160a01b0316826001600160a01b031614611f275760405162461bcd60e51b8152600401610943906020808252600490820152630414233360e41b604082015260600190565b5f805f5b600e548110156134f557866001600160a01b0316600e828154811061326e5761326e615707565b5f918252602090912001546001600160a01b0316148015906132ec57505f6132ea89600e84815481106132a3576132a3615707565b5f918252602080832091909101546001600160a01b038e81168452601b83526040808520549582168552601984528085209190921684528252808320938352929052205490565b115b156134ed576001600160a01b0388165f908152601c60209081526040808320601b8352818420548452909152902054600e8054613335918b91859081106132a3576132a3615707565b61333f9088615626565b6133499190615651565b925082156133bc5761335b8383615736565b91506133b98888600e848154811061337557613375615707565b905f5260205f20015f9054906101000a90046001600160a01b0316868873c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b888151811061300457613004615707565b92505b5f600e82815481106133d0576133d0615707565b5f918252602090912001546040516370a0823160e01b81526001600160a01b038b81166004830152909116906370a0823190602401602060405180830381865afa158015613420573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061344491906153e3565b111561347f5761347f883085600e858154811061346357613463615707565b5f918252602090912001546001600160a01b0316929190614151565b6001600160a01b0388165f908152601a60205260408120600e805486939190859081106134ae576134ae615707565b5f9182526020808320909101546001600160a01b0390811684528382019490945260409283018220938d168252601b8152828220548252929092529020555b600101613247565b505f5b600e54811015610e5057866001600160a01b0316600e828154811061351f5761351f615707565b5f918252602090912001546001600160a01b03161480156135a957506001600160a01b0388165f908152601960205260408120600e80548391908590811061356957613569615707565b5f9182526020808320909101546001600160a01b0390811684528382019490945260409283018220938d168252601b815282822054825292909252902054115b15613613576135b882876152e6565b92506135d3883085600e858154811061346357613463615707565b6001600160a01b038089165f818152601a60209081526040808320948c168352938152838220928252601b81528382205482529190915220839055610e50565b6001016134f8565b6001546001600160a01b03163314611f525760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610943565b600a5481116136ae5760405162461bcd60e51b815260206004820152600560248201526441464f303160d81b6044820152606401610943565b6001600160a01b039091165f90815260156020526040902055565b60025f540361371a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610943565b60025f55565b604051634b49628160e01b81523360048201526024810186905284151560448201528315156064820152821515608482015260a481018290526001600160a01b03871690634b4962819060c4015f604051808303815f87803b158015613784575f80fd5b505af1158015613796573d5f803e3d5ffd5b50505050505050505050565b80821015611f275760405162461bcd60e51b8152600401610943906020808252600490820152631053cc8d60e21b604082015260600190565b6001600160a01b038116611fdd5760405162461bcd60e51b8152600401610943906020808252600490820152634146303360e01b604082015260600190565b6040805160028082526060820183525f92839291906020830190803683375050600654825192935063ffffffff16918391505f9061385a5761385a615707565b602002602001019063ffffffff16908163ffffffff16815250505f8160018151811061388857613888615707565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81525f906001600160a01b0385169063883bdbfd906138cb9085906004016158e5565b5f60405180830381865afa1580156138e5573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261390c919081019061592d565b5090505f815f8151811061392257613922615707565b60200260200101518260018151811061393d5761393d615707565b602002602001015161394f91906159e1565b6006549091505f9061396a9063ffffffff1660030b83615a0e565b90505f8260060b128015613995575060065461398f9063ffffffff1660030b83615a4a565b60060b15155b156139a857806139a481615a6b565b9150505b6139b481898b8a614189565b9998505050505050505050565b335f9081526013602090815260408083206001600160a01b0396871684528252808320949095168252928352838120918152915290812055565b600280546001600160a01b0319169055611fdd81614287565b6040516001600160a01b03831660248201526044810182905261142f90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526142d8565b6003546001600160a01b03163314611f525760405162461bcd60e51b8152600401610943906152b6565b600954604051632b7746f160e01b81526001600160a01b0383811660048301525f921690632b7746f190602401602060405180830381865afa158015613ae9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b0d919061571b565b92915050565b5f80821215613b645760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610943565b5090565b5f806001600160a01b03861673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21480613bb157506001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2145b15613bc857613bc1868686611ae1565b9150613d17565b6001600160a01b038087165f818152601860205260409020549091161480613c0b57506001600160a01b038087165f908152601860205260409020548582169116145b15613c71576001600160a01b038087165f90815260186020526040902054613c35918891166143a9565b90506001600160a01b03831615613c495750815b6001600160a01b038087165f90815260186020526040902054613bc19188918891168461441d565b6001600160a01b038087165f90815260186020526040902054613c96918891166143a9565b6001600160a01b038088165f9081526018602052604081205492935091613cbf918791166143a9565b6001600160a01b038089165f90815260186020526040902054919250613cea9189918991168561441d565b6001600160a01b038089165f90815260186020526040902054919450613d13911684878461441d565b9250505b50949350505050565b60405163a4c69f3560e01b81526001600160a01b0383811660048301525f91829186169063a4c69f3590602401602060405180830381865afa158015613d68573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d8c91906153e3565b90506001811115613dd357600c54613da56001836152e6565b613daf9190615626565b600b54600c54613dbf91906152e6565b613dc99085615626565b611baa9190615651565b509392505050565b604051639908fc8b60e01b81526001600160a01b03878116600483015286811660248301526044820186905260648201859052838116608483015260a482018390525f9190891690639908fc8b9060c4016020604051808303815f875af1158015613e48573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e6c91906153e3565b98975050505050505050565b5f8115613f5a575f80613e8a8561275e565b915091505f856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ecb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613eef91906157b0565b613efa9060126157d0565b60ff16905081613f0b82600a6158da565b613f158588615626565b613f1f9190615626565b613f299190615651565b6001600160a01b038089165f90815260116020526040902054919550613f5691888216918a911688614151565b5050505b9392505050565b60408281015160095485519251630bf6f34d60e01b81526001600160a01b0393841660048201525f9390911690630bf6f34d906024016020604051808303815f875af1158015613fb3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fd791906153e3565b5f03614022575060608301515f9250825b81518110156140205781818151811061400357614003615707565b6020026020010151846140169190615736565b9350600101613fe8565b505b602085015185516040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561406d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061409191906153e3565b91505f5b846020015151811015611ad95760018282815181106140b6576140b6615707565b6020026020010151101580156140cb57505f83115b1561414957614147865f01518760200151876020015184815181106140f2576140f2615707565b60200260200101518786868151811061410d5761410d615707565b6020026020010151886141209190615626565b61412a9190615651565b8a61012001515f8c60a00151888151811061300457613004615707565b505b600101614095565b6040516001600160a01b03808516602483015283166044820152606481018290526112e79085906323b872dd60e01b90608401613a40565b5f8061419486614435565b90506001600160801b036001600160a01b03821611614219575f6141c16001600160a01b03831680615626565b9050836001600160a01b0316856001600160a01b0316106141f9576141f4600160c01b876001600160801b031683614750565b614211565b61421181876001600160801b0316600160c01b614750565b925050613d17565b5f6142376001600160a01b0383168068010000000000000000614750565b9050836001600160a01b0316856001600160a01b03161061426f5761426a600160801b876001600160801b031683614750565b613d13565b613d1381876001600160801b0316600160801b614750565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f61432c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166147fa9092919063ffffffff16565b80519091501561142f578080602001905181019061434a9190615599565b61142f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610943565b60095460405163298d501f60e11b81526001600160a01b03848116600483015283811660248301525f92169063531aa03e90604401602060405180830381865afa1580156143f9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f5a919061571b565b5f8061442b86868686611f2b565b9695505050505050565b5f805f8360020b1261444a578260020b614451565b8260020b5f035b9050620d89e8811115614477576040516315e4079d60e11b815260040160405180910390fd5b5f816001165f0361448c57600160801b61449e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff16905060028216156144d2576ffff97272373d413259a46990580e213a0260801c5b60048216156144f1576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615614510576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b601082161561452f576fffcb9843d60f6159c9db58835c9266440260801c5b602082161561454e576fff973b41fa98c081472e6896dfb254c00260801c5b604082161561456d576fff2ea16466c96a3843ec78b326b528610260801c5b608082161561458c576ffe5dee046a99a2a811c461f1969c30530260801c5b6101008216156145ac576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b6102008216156145cc576ff987a7253ac413176f2b074cf7815e540260801c5b6104008216156145ec576ff3392b0822b70005940c7a398e4b70f30260801c5b61080082161561460c576fe7159475a2c29b7443b29c7fa6e889d90260801c5b61100082161561462c576fd097f3bdfd2022b8845ad8f792aa58250260801c5b61200082161561464c576fa9f746462d870fdf8a65dc1f90e061e50260801c5b61400082161561466c576f70d869a156d2a1b890bb3df62baf32f70260801c5b61800082161561468c576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156146ad576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156146cd576e5d6af8dedb81196699c329225ee6040260801c5b620400008216156146ec576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615614709576b048a170391f7dc42444e8fa20260801c5b5f8460020b131561472857805f19816147245761472461563d565b0490505b64010000000081061561473c57600161473e565b5f5b60ff16602082901c0192505050919050565b5f80805f19858709858702925082811083820303915050805f03614784575f8411614779575f80fd5b508290049050613f5a565b80841161478f575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b60606120a684845f85855f80866001600160a01b0316858760405161481f9190615a8c565b5f6040518083038185875af1925050503d805f8114614859576040519150601f19603f3d011682016040523d82523d5f602084013e61485e565b606091505b5091509150613d1387838387606083156148d85782515f036148d1576001600160a01b0385163b6148d15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b50816120a6565b6120a683838151156148ed5781518083602001fd5b8060405162461bcd60e51b81526004016109439190615aa2565b828054828255905f5260205f2090810192821561495a579160200282015b8281111561495a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614925565b50613b649291505b80821115613b64575f8155600101614962565b634e487b7160e01b5f52604160045260245ffd5b6040516101a081016001600160401b03811182821017156149ac576149ac614975565b60405290565b604051601f8201601f191681016001600160401b03811182821017156149da576149da614975565b604052919050565b6001600160a01b0381168114611fdd575f80fd5b8035614a01816149e2565b919050565b5f6001600160401b03821115614a1e57614a1e614975565b5060051b60200190565b5f82601f830112614a37575f80fd5b8135614a4a614a4582614a06565b6149b2565b8082825260208201915060208360051b860101925085831115614a6b575f80fd5b602085015b83811015614a91578035614a83816149e2565b835260209283019201614a70565b5095945050505050565b5f82601f830112614aaa575f80fd5b8135614ab8614a4582614a06565b8082825260208201915060208360051b860101925085831115614ad9575f80fd5b602085015b83811015614a91578035835260209283019201614ade565b5f60208284031215614b06575f80fd5b81356001600160401b03811115614b1b575f80fd5b82016101a08185031215614b2d575f80fd5b614b35614989565b614b3e826149f6565b8152614b4c602083016149f6565b6020820152604082810135908201526060808301359082015260808201356001600160401b03811115614b7d575f80fd5b614b8986828501614a28565b60808301525060a08201356001600160401b03811115614ba7575f80fd5b614bb386828501614a9b565b60a08301525060c08201356001600160401b03811115614bd1575f80fd5b614bdd86828501614a9b565b60c08301525060e08201356001600160401b03811115614bfb575f80fd5b614c0786828501614a28565b60e0830152506101008201356001600160401b03811115614c26575f80fd5b614c3286828501614a9b565b6101008301525061012082810135908201526101408201356001600160401b03811115614c5d575f80fd5b614c6986828501614a28565b610140830152506101608201356001600160401b03811115614c89575f80fd5b614c9586828501614a28565b610160830152506101808201356001600160401b03811115614cb5575f80fd5b614cc186828501614a9b565b61018083015250949350505050565b8015158114611fdd575f80fd5b5f805f805f8060c08789031215614cf2575f80fd5b8635614cfd816149e2565b95506020870135614d0d816149e2565b94506040870135935060608701356001600160401b03811115614d2e575f80fd5b614d3a89828a01614a9b565b93505060808701356001600160401b03811115614d55575f80fd5b614d6189828a01614a9b565b92505060a0870135614d7281614cd0565b809150509295509295509295565b5f805f60608486031215614d92575f80fd5b83356001600160401b03811115614da7575f80fd5b614db386828701614a28565b93505060208401356001600160401b03811115614dce575f80fd5b614dda86828701614a28565b92505060408401356001600160401b03811115614df5575f80fd5b8401601f81018613614e05575f80fd5b8035614e13614a4582614a06565b8082825260208201915060208360051b850101925088831115614e34575f80fd5b6020840193505b82841015614e6657833562ffffff81168114614e55575f80fd5b825260209384019390910190614e3b565b809450505050509250925092565b5f8060408385031215614e85575f80fd5b82356001600160401b03811115614e9a575f80fd5b614ea685828601614a28565b92505060208301356001600160401b03811115614ec1575f80fd5b614ecd85828601614a9b565b9150509250929050565b5f8060408385031215614ee8575f80fd5b8235614ef3816149e2565b946020939093013593505050565b5f60208284031215614f11575f80fd5b8135613f5a816149e2565b5f60208284031215614f2c575f80fd5b5035919050565b5f805f60608486031215614f45575f80fd5b8335614f50816149e2565b9250602084013591506040840135614f67816149e2565b809150509250925092565b5f805f60608486031215614f84575f80fd5b8335614f8f816149e2565b92506020840135614f9f816149e2565b91506040840135614f67816149e2565b5f8060408385031215614fc0575f80fd5b8235614fcb816149e2565b91506020830135614fdb816149e2565b809150509250929050565b5f8060408385031215614ff7575f80fd5b8235615002816149e2565b9150602083013561ffff81168114614fdb575f80fd5b80356001600160801b0381168114614a01575f80fd5b5f805f60608486031215615040575f80fd5b833561504b816149e2565b9250614f9f60208501615018565b5f805f806080858703121561506c575f80fd5b8435615077816149e2565b935061508560208601615018565b92506040850135615095816149e2565b915060608501356150a5816149e2565b939692955090935050565b5f805f80608085870312156150c3575f80fd5b84356150ce816149e2565b935060208501356150de816149e2565b925060408501356150ee816149e2565b9396929550929360600135925050565b5f806040838503121561510f575f80fd5b82356001600160401b03811115615124575f80fd5b61513085828601614a28565b92505060208301356001600160401b0381111561514b575f80fd5b614ecd85828601614a28565b5f805f60608486031215615169575f80fd5b8335615174816149e2565b92506020840135615184816149e2565b929592945050506040919091013590565b5f805f606084860312156151a7575f80fd5b83356151b2816149e2565b925060208401356001600160401b038111156151cc575f80fd5b6151d886828701614a28565b93969395505050506040919091013590565b5f602082840312156151fa575f80fd5b813563ffffffff81168114613f5a575f80fd5b5f806040838503121561521e575f80fd5b8235615229816149e2565b91506020830135614fdb81614cd0565b5f806040838503121561524a575f80fd5b50508035926020909101359150565b5f805f6060848603121561526b575f80fd5b8335615276816149e2565b92506020840135615286816149e2565b915060408401356001600160401b038111156152a0575f80fd5b6152ac86828701614a28565b9150509250925092565b6020808252600290820152614e4160f01b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115613b0d57613b0d6152d2565b5f806040838503121561530a575f80fd5b825161531581614cd0565b6020840151909250614fdb81614cd0565b5f82601f830112615335575f80fd5b8151615343614a4582614a06565b8082825260208201915060208360051b860101925085831115615364575f80fd5b602085015b83811015614a9157805161537c816149e2565b835260209283019201615369565b5f806040838503121561539b575f80fd5b82516001600160401b038111156153b0575f80fd5b6153bc85828601615326565b92505060208301516001600160401b038111156153d7575f80fd5b614ecd85828601615326565b5f602082840312156153f3575f80fd5b5051919050565b5f6020828403121561540a575f80fd5b81516001600160401b0381111561541f575f80fd5b6120a684828501615326565b5f8151808452602084019350602083015f5b828110156154645781516001600160a01b031686526020958601959091019060010161543d565b5093949350505050565b602081525f613f5a602083018461542b565b5f82601f83011261548f575f80fd5b815161549d614a4582614a06565b8082825260208201915060208360051b8601019250858311156154be575f80fd5b602085015b83811015614a915780518352602092830192016154c3565b5f80604083850312156154ec575f80fd5b82516001600160401b03811115615501575f80fd5b61550d85828601615480565b92505060208301516001600160401b03811115615528575f80fd5b614ecd85828601615480565b5f8151808452602084019350602083015f5b82811015615464578151865260209586019590910190600101615546565b6001600160a01b03841681526060602082018190525f906155879083018561542b565b828103604084015261442b8185615534565b5f602082840312156155a9575f80fd5b8151613f5a81614cd0565b5f805f80608085870312156155c7575f80fd5b84516001600160401b038111156155dc575f80fd5b6155e887828801615326565b94505060208501516001600160401b03811115615603575f80fd5b61560f87828801615326565b604087015160609097015195989097509350505050565b8082028115828204841417613b0d57613b0d6152d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261565f5761565f61563d565b500490565b6001600160a01b03878116825260208201879052851660408201526060810184905260c0608082018190525f9061569d90830185615534565b82810360a084015283548082525f8581526020808220930191905b818110156156df5783546001600160a01b03168352600193840193602090930192016156b8565b50909a9950505050505050505050565b5f60018201615700576157006152d2565b5060010190565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561572b575f80fd5b8151613f5a816149e2565b80820180821115613b0d57613b0d6152d2565b805169ffffffffffffffffffff81168114614a01575f80fd5b5f805f805f60a08688031215615776575f80fd5b61577f86615749565b602087015160408801516060890151929750909550935091506157a460808701615749565b90509295509295909350565b5f602082840312156157c0575f80fd5b815160ff81168114613f5a575f80fd5b60ff8281168282160390811115613b0d57613b0d6152d2565b6001815b600184111561582457808504811115615808576158086152d2565b600184161561581657908102905b60019390931c9280026157ed565b935093915050565b5f8261583a57506001613b0d565b8161584657505f613b0d565b816001811461585c576002811461586657615882565b6001915050613b0d565b60ff841115615877576158776152d2565b50506001821b613b0d565b5060208310610133831016604e8410600b84101617156158a5575081810a613b0d565b6158b15f1984846157e9565b805f19048211156158c4576158c46152d2565b029392505050565b5f613f5a60ff84168361582c565b5f613f5a838361582c565b602080825282518282018190525f918401906040840190835b8181101561592257835163ffffffff168352602093840193909201916001016158fe565b509095945050505050565b5f806040838503121561593e575f80fd5b82516001600160401b03811115615953575f80fd5b8301601f81018513615963575f80fd5b8051615971614a4582614a06565b8082825260208201915060208360051b850101925087831115615992575f80fd5b6020840193505b828410156159c25783518060060b81146159b1575f80fd5b825260209384019390910190615999565b8095505050505060208301516001600160401b038111156153d7575f80fd5b600682810b9082900b03667fffffffffffff198112667fffffffffffff82131715613b0d57613b0d6152d2565b5f8160060b8360060b80615a2457615a2461563d565b667fffffffffffff1982145f1982141615615a4157615a416152d2565b90059392505050565b5f8260060b80615a5c57615a5c61563d565b808360060b0791505092915050565b5f8160020b627fffff198103615a8357615a836152d2565b5f190192915050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea264697066735822122001f9e8c8499a0143475c950927f11fbab318b326774b32de7e0544fca3944e3364736f6c634300081a003300000000000000000000000025b5720e9b20be18b4d020153ac26d957c83e341
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061034b575f3560e01c80638456cb59116101c9578063ca60d67e116100fe578063ef1306c41161009e578063f7b188a511610079578063f7b188a51461084d578063fcee4f0114610855578063fd6046d714610885578063ff166c06146108e1575f80fd5b8063ef1306c414610814578063f2fde38b14610827578063f3c073da1461083a575f80fd5b8063df588dc4116100d9578063df588dc414610785578063e30c397814610798578063e8eec12c146107a9578063ec4b4985146107c8575f80fd5b8063ca60d67e1461074e578063d7f5870314610761578063da540ca014610772575f80fd5b8063b52a9e4911610169578063bf817c2111610144578063bf817c211461070d578063c20713fe14610715578063c253301314610728578063c4aa09d31461073b575f80fd5b8063b52a9e49146106ae578063b810c636146106c1578063bbeed008146106dd575f80fd5b806396722061116101a457806396722061146106555780639e8d371014610668578063a9a4cbcc14610693578063ae1f64891461069b575f80fd5b80638456cb59146106005780638da5cb5b146106085780638ede7b6e1461062d575f80fd5b806348a3e9131161029f5780636a40c2c31161023f578063715018a61161021a578063715018a6146105ca578063728be284146105d257806379ba5097146105e5578063813fb457146105ed575f80fd5b80636a40c2c3146105825780636d1a95d3146105955780636f52213a146105b7575f80fd5b80634fc9135c1161027a5780634fc9135c14610511578063502f7a86146105445780635190b08c146105525780635c975abb14610565575f80fd5b806348a3e913146104ce57806349e71eab146104d65780634ab2c028146104fe575f80fd5b80631ea75b411161030a5780632ccea637116102e55780632ccea6371461043b5780632efd3ee71461044e5780633c460b0b1461049157806347155a0e146104a4575f80fd5b80631ea75b4114610402578063255c3e8f14610415578063291217d114610428575f80fd5b8062acf0bc1461034f578062cc39b81461036457806301b8acd3146103775780630727e4e41461038a5780630b917d121461039d5780631d8b0fa5146103da575b5f80fd5b61036261035d366004614af6565b6108f4565b005b610362610372366004614cdd565b610e5a565b610362610385366004614d80565b61122b565b610362610398366004614e74565b6112ed565b6103c76103ab366004614ed7565b601c60209081525f928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6103c76103e8366004614f01565b6001600160a01b03165f9081526017602052604090205490565b610362610410366004614f1c565b611434565b610362610423366004614f1c565b61147c565b610362610436366004614f33565b611489565b610362610449366004614f72565b611794565b61047d61045c366004614faf565b600560209081525f928352604080842090915290825290205462ffffff1681565b60405162ffffff90911681526020016103d1565b61036261049f366004614ed7565b6117df565b6104b76104b2366004614faf565b611802565b6040805192835260ff9091166020830152016103d1565b600b546103c7565b6103c76104e4366004614f01565b6001600160a01b03165f9081526016602052604090205490565b61036261050c366004614fe6565b611a85565b600454600954601054604080516001600160a01b03948516815292841660208401529216918101919091526060016103d1565b60065463ffffffff166103c7565b6103c761056036600461502e565b611ae1565b600d546105729060ff1681565b60405190151581526020016103d1565b610362610590366004614faf565b611bb3565b6105726105a3366004614f01565b601e6020525f908152604090205460ff1681565b6103c76105c5366004615059565b611f2b565b610362611f41565b6103626105e0366004614ed7565b611f54565b610362611f66565b6103626105fb366004614f01565b611fe0565b610362612013565b6001546001600160a01b03165b6040516001600160a01b0390911681526020016103d1565b6103c761063b366004614f01565b6001600160a01b03165f9081526015602052604090205490565b6103c76106633660046150b0565b61206e565b610615610676366004614f01565b6001600160a01b039081165f908152601860205260409020541690565b600c546103c7565b6103626106a93660046150fe565b6120ae565b6103626106bc366004614f01565b612230565b6007546008545b604080519283526020830191909152016103d1565b6103c76106eb366004615157565b601960209081525f938452604080852082529284528284209052825290205481565b600a546103c7565b610362610723366004615195565b612263565b610362610736366004614f01565b6126a1565b610362610749366004614f01565b6126d4565b61036261075c3660046151ea565b61273a565b6003546001600160a01b0316610615565b6106c8610780366004614f01565b61275e565b61036261079336600461520d565b6128c9565b6002546001600160a01b0316610615565b6103c76107b7366004614f01565b601b6020525f908152604090205481565b6103c76107d63660046150b0565b6001600160a01b039384165f908152601360209081526040808320958716835294815284822093909516815291845282822090825290925290205490565b610362610822366004614f1c565b612918565b610362610835366004614f01565b612925565b610362610848366004615239565b612996565b610362612a3b565b6103c7610863366004615157565b601a60209081525f938452604080852082529284528284209052825290205481565b6108c1610893366004614f01565b6001600160a01b039081165f9081526011602090815260408083205460129092529091205490821692911690565b604080516001600160a01b039384168152929091166020830152016103d1565b6103c76108ef366004615259565b612a8c565b80516001600160a01b039081165f908152601160205260409020541633148061092757506010546001600160a01b031633145b61094c5760405162461bcd60e51b8152600401610943906152b6565b60405180910390fd5b80516001600160a01b039081165f9081526017602090815260408083205485519094168352601690915290205461098390426152e6565b10156109d15760405162461bcd60e51b815260206004820152601760248201527f5377617020706572696f64206e6f7420656c61707365640000000000000000006044820152606401610943565b5f815f01516001600160a01b031663b187bd266040518163ffffffff1660e01b81526004016040805180830381865afa158015610a10573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a3491906152f9565b509050610a4081612d6f565b610a6b6040518060800160405280606081526020016060815260200160608152602001606081525090565b825f01516001600160a01b031663e52e43da6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610aa9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ad0919081019061538a565b508360800181905250825f01516001600160a01b031663d61daa616040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3c91906153e3565b836060018181525050825f01516001600160a01b031663292252886040518163ffffffff1660e01b81526004015f60405180830381865afa158015610b83573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610baa91908101906153fa565b6020820181905251610bf75760405162461bcd60e51b815260206004820152601660248201527514995a5b9a5d1a585b1a5e99481d1a19481d985d5b1d60521b6044820152606401610943565b6101608301515115610c2c57610c2c835f01518461014001518561016001518661018001518760200151886101200151612da4565b8251608084015160405163e353d30360e01b81525f926001600160a01b03169163e353d30391610c5f919060040161546e565b6020604051808303815f875af1158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f91906153e3565b9050835f01516001600160a01b031663cdc7fcc26040518163ffffffff1660e01b81526004015f60405180830381865afa158015610cdf573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d0691908101906154db565b60608401526040830152610d1b848383613026565b60048054855160e087015161010088015160405163e899317560e01b81526001600160a01b039094169463e899317594610d589493929101615564565b5f604051808303815f87803b158015610d6f575f80fd5b505af1158015610d81573d5f803e3d5ffd5b505085516001600160a01b039081165f90815260166020526040808220429055885190516386a0da7360e01b8152600481019290925290911692506386a0da7391506024015f604051808303815f87803b158015610ddd575f80fd5b505af1158015610def573d5f803e3d5ffd5b5050601054865160405163c4d2958b60e01b81526001600160a01b0391821660048201525f60248201529116925063c4d2958b91506044015f604051808303815f87803b158015610e3e575f80fd5b505af1158015610e50573d5f803e3d5ffd5b5050505050505050565b6001600160a01b038087165f90815260126020526040902054610e7f913391166131f9565b6001600160a01b0386165f908152601e6020526040902054610ea39060ff16612d6f565b60405163acc8860760e01b81526001600160a01b038681166004830152610f15919088169063acc8860790602401602060405180830381865afa158015610eec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f109190615599565b612d6f565b601054604051632eaabf7760e21b81526001600160a01b0388811660048301529091169063baaafddc90602401602060405180830381865afa158015610f5d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f819190615599565b15610fbe5760405162461bcd60e51b815260206004820152600d60248201526c10d85b1b0810d4c8199a5c9cdd609a1b6044820152606401610943565b604051637b77ba2f60e01b815281151560048201526001600160a01b03871690637b77ba2f906024015f604051808303815f87803b158015610ffe575f80fd5b505af1158015611010573d5f803e3d5ffd5b505050506001600160a01b0386165f818152601c60209081526040808320601b835281842054845290915280822054905160016267399760e01b0319815260048101919091529091829163ff98c669906024015f604051808303815f875af115801561107e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526110a591908101906155b4565b8251919550935084908490600e905f906110c690600f906020880190614907565b505084516110d991906020870190614907565b505050506001600160a01b0389165f908152601c60209081526040808320601b8352818420548452909152812054909150156111cd576001600160a01b0389165f908152601c60209081526040808320601b835281842054845290915290205482906111459085615626565b61114f9190615651565b60048054604051630c18192560e21b81529293506001600160a01b03169163306064949161118a918d9186918e918e918e91600f9101615664565b6020604051808303815f875af11580156111a6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ca91906153e3565b90505b6111da898983888b613243565b6001600160a01b0389165f818152601c60209081526040808320601b8084528285208054865291845291842084905593835290528154919061121b836156ef565b9190505550505050505050505050565b61123361361b565b5f5b81518110156112e75781818151811061125057611250615707565b602002602001015160055f86848151811061126d5761126d615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8584815181106112a7576112a7615707565b6020908102919091018101516001600160a01b031682528101919091526040015f20805462ffffff191662ffffff92909216919091179055600101611235565b50505050565b6001546001600160a01b031633148061138a575060105f9054906101000a90046001600160a01b03166001600160a01b0316633495100a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611351573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611375919061571b565b6001600160a01b0316336001600160a01b0316145b6113a65760405162461bcd60e51b8152600401610943906152b6565b80518251146113e05760405162461bcd60e51b815260206004820152600660248201526541464f30313160d01b6044820152606401610943565b5f5b825181101561142f5761142783828151811061140057611400615707565b602002602001015183838151811061141a5761141a615707565b6020026020010151613675565b6001016113e2565b505050565b61143c61361b565b6008548111156114775760405162461bcd60e51b815260206004820152600660248201526541464f31313160d01b6044820152606401610943565b600755565b61148461361b565b600a55565b6114916136c9565b6001600160a01b0383165f908152601e60205260409020546114b69060ff1615612d6f565b60405163badd069b60e01b81523360048201526001600160a01b0382811660248301526044820184905284169063badd069b906064015f604051808303815f87803b158015611503575f80fd5b505af1158015611515573d5f803e3d5ffd5b5050335f8181526013602090815260408083206001600160a01b038a811680865291845282852090891685528352818420818552601b8452828520548552909252808320549051633ad3951560e21b8152600481019490945294509092509063eb4e545490602401602060405180830381865afa158015611598573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115bc91906153e3565b90506115c88483615736565b335f8181526013602090815260408083206001600160a01b038b8116808652918452828520908a16808652908452828520828652601b8552838620805487529085528386209790975594845260148352818420908452825280832093835292815282822093548252929092529020546116418584615736565b61164b8684615626565b6116558584615626565b61165f9190615736565b6116699190615651565b335f9081526014602090815260408083206001600160a01b038b8116808652918452828520908a16808652908452828520828652601b855283862080548752908552838620969096559084526019835281842090845282528083209354835292905290812080548792906116de908490615736565b90915550506001600160a01b0386165f908152601c60209081526040808320601b83528184205484529091528120805487929061171c908490615736565b90915550611731905086865f60018180613720565b6001600160a01b038681165f908152601b6020908152604091829020548251898152918201529186169133917fdd17a24176e09db37c0a70c6b1eb4522a450c150c57ce1a80bbf07c03b6b0cdd910160405180910390a350505061142f60015f55565b61179c61361b565b6001600160a01b039283165f90815260116020908152604080832080549587166001600160a01b0319968716179055601290915290208054919093169116179055565b6117e761361b565b6001600160a01b039091165f90815260176020526040902055565b5f805f80846001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611842573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118669190615762565b509350509250505f856001600160a01b031663245a7bfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118ce919061571b565b90505f816001600160a01b03166322adbc786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561190d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061193191906153e3565b90505f826001600160a01b03166370da2f676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611970573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199491906153e3565b905080851015806119a55750818511155b156119da5760405162461bcd60e51b815260206004820152600560248201526441464f4f4f60d81b6044820152606401610943565b5f886001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3b91906157b0565b6001600160a01b038b165f90815260156020526040902054909150611a6b908690611a6690426152e6565b6137a2565b611a75865f6137a2565b9499949850939650505050505050565b6040516332148f6760e01b815261ffff821660048201526001600160a01b038316906332148f67906024015f604051808303815f87803b158015611ac7575f80fd5b505af1158015611ad9573d5f803e3d5ffd5b505050505050565b6001600160a01b038381165f81815260056020908152604080832094861680845294909152808220549051630b4c774160e11b81526004810194909452602484019290925262ffffff9091166044830152908190731f98431c8ad98523631ae4a59f267346ea31f98490631698ee8290606401602060405180830381865afa158015611b6f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b93919061571b565b9050611b9e816137db565b611baa8585858461381a565b95945050505050565b611bbb6136c9565b6001600160a01b0382165f908152601e6020526040902054611be09060ff1615612d6f565b335f9081526013602090815260408083206001600160a01b0386811680865291845282852090861685528352818420908452601b835281842054845290915290205480611c5d5760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8145d595d595960aa1b6044820152606401610943565b6001600160a01b038084165f8181526019602090815260408083209487168352938152838220928252601b8152838220548252919091529081208054839290611ca79084906152e6565b90915550506001600160a01b0383165f908152601b6020526040902054611cd190849084906139c1565b6001600160a01b0383165f908152601c60209081526040808320601b835281842054845290915281208054839290611d0a9084906152e6565b9091555050335f8181526014602090815260408083206001600160a01b0388811680865291845282852090881685528352818420818552601b845282852054855290925280832080549084905590516370a0823160e01b815260048101949094528493909291906370a0823190602401602060405180830381865afa158015611d95573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611db991906153e3565b611dc39084615736565b6040516370a0823160e01b81523360048201526001600160a01b038816906370a0823190602401602060405180830381865afa158015611e05573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e2991906153e3565b604051633ad3951560e21b81523360048201526001600160a01b0389169063eb4e545490602401602060405180830381865afa158015611e6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e8f91906153e3565b611e999190615626565b611ea38585615626565b611ead9190615736565b611eb79190615651565b9050611ec886855f80600186613720565b6001600160a01b0386165f908152601b60209081526040918290205482518781529182015233917fa53a6125e3124d0deab3f226519dcdaaaee34541890e292ba99f3af26d0622f2910160405180910390a250505050611f2760015f55565b5050565b5f611f35826137db565b611baa8585858561381a565b611f4961361b565b611f525f6139fb565b565b611f5c61361b565b611f278282613675565b60025433906001600160a01b03168114611fd45760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610943565b611fdd816139fb565b50565b611fe861361b565b611ff1816137db565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b600d546120239060ff1615612d6f565b61202b61361b565b600d805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020015b60405180910390a1565b6001600160a01b038085165f908152601460209081526040808320878516845282528083209386168352928152828220848352905220545b949350505050565b6001546001600160a01b03163314806120d157506010546001600160a01b031633145b80612160575060105f9054906101000a90046001600160a01b03166001600160a01b0316633495100a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612127573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214b919061571b565b6001600160a01b0316336001600160a01b0316145b61217c5760405162461bcd60e51b8152600401610943906152b6565b5f5b825181101561142f576121a983828151811061219c5761219c615707565b60200260200101516137db565b6121be82828151811061219c5761219c615707565b8181815181106121d0576121d0615707565b602002602001015160185f8584815181106121ed576121ed615707565b6020908102919091018101516001600160a01b039081168352908201929092526040015f2080546001600160a01b0319169290911691909117905560010161217e565b61223861361b565b612241816137db565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383165f908152601b602052604090205481106122b25760405162461bcd60e51b815260040161094390602080825260049082015263414f303160e01b604082015260600190565b5f805f805f5b8651811015610e5057335f9081526013602090815260408083206001600160a01b038c168452909152812088519091908990849081106122fa576122fa615707565b6020908102919091018101516001600160a01b0390811683528282019390935260409182015f9081208a825282528281205433825260148352838220948d1682529390915290812089519295509189908490811061235a5761235a615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8781526020019081526020015f205491505f831115612699576001600160a01b0388165f90815260196020526040812088519091908990849081106123c9576123c9615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8781526020019081526020015f2054601a5f8a6001600160a01b03166001600160a01b031681526020019081526020015f205f89848151811061243657612436615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8881526020019081526020015f2054846124789190615626565b6124829190615651565b94505f806124a889848151811061249b5761249b615707565b602002602001015161275e565b915091505f8984815181106124bf576124bf615707565b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612502573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061252691906157b0565b6125319060126157d0565b905061253e81600a6158cc565b6125489084615626565b61255490612710615626565b8261255f8888615626565b6125699190615626565b6125739190615651565b96508688111561263a57600c5460649061258d898b6152e6565b6125979190615626565b6125a19190615651565b6001600160a01b038c165f908152601d602052604081208c519091908d90889081106125cf576125cf615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205f8282546126049190615736565b9091555050600c54606490612619898b6152e6565b6126239190615626565b61262d9190615651565b61263790896152e6565b97505b61265e8b8b868151811061265057612650615707565b60200260200101518b6139c1565b61269533898c878151811061267557612675615707565b60200260200101516001600160a01b0316613a149092919063ffffffff16565b5050505b6001016122b8565b6126a961361b565b6126b2816137db565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6126dc613a77565b6001600160a01b0381166127185760405162461bcd60e51b815260206004820152600360248201526227a22d60e91b6044820152606401610943565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61274261361b565b6006805463ffffffff191663ffffffff92909216919091179055565b5f80620f4240816001600160a01b03851673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48146128b9575f61279386613aa1565b90506001600160a01b0381161561281a575f6127af8783611802565b5090505f6127e573a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48738fffffd4afb6115b954bd326cbe7b4ba576818f6611802565b5090506127f181613b13565b6127fa83613b13565b61280790620f4240615626565b6128119190615651565b935050506128b3565b5f866001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612857573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061287b91906157b0565b60ff1690505f61288c82600a6158da565b90506128ae888273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485f613b68565b935050505b506128c0565b5060019050805b94909350915050565b6001600160a01b038083165f908152601160205260409020546128ee913391166131f9565b6001600160a01b03919091165f908152601e60205260409020805460ff1916911515919091179055565b61292061361b565b600855565b61292d613a77565b600280546001600160a01b0383166001600160a01b0319909116811790915561295e6001546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61299e61361b565b600d546129ae9060ff1615612d6f565b8181111580156129bf5750600a8211155b6129f45760405162461bcd60e51b81526004016109439060208082526004908201526320a6981960e11b604082015260600190565b600b819055600c82905560408051828152602081018490527fd2c1ad765e23a2310d15fab4c801a9baf192020787d20bca01731f76c03c5b4c910160405180910390a15050565b600d54612a4a9060ff16612d6f565b612a5261361b565b600d805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602001612064565b5f612a9561361b565b604051633450705160e11b81526001600160a01b0385811660048301525f91908516906368a0e0a2906024015f60405180830381865afa158015612adb573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612b0291908101906153fa565b90505f805f5b8551811015612d64576001600160a01b0388165f908152601d602052604081208751909190889084908110612b3f57612b3f615707565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205491505f821115612d0c57612b7c878984613d20565b92505f805f5b8651811015612d0857896001600160a01b0316637fd3086b8c898481518110612bad57612bad615707565b60200260200101516040518363ffffffff1660e01b8152600401612be79291906001600160a01b0392831681529116602082015260400190565b6040805180830381865afa158015612c01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c2591906152f9565b5091508115612d0057805f03612c5957600c54600b54612c459087615626565b612c4f9190615651565b9250829450612c5d565b8594505b612c678589615736565b9750612c99878281518110612c7e57612c7e615707565b6020026020010151868b878151811061267557612675615707565b868181518110612cab57612cab615707565b60200260200101516001600160a01b03168b6001600160a01b03167fde542754cbe64e85d7631fd8696b87e68cc3cc5521243efb5cb15687287ba4fa87604051612cf791815260200190565b60405180910390a35b600101612b82565b5050505b6001600160a01b0388165f908152601d6020526040812087518290899085908110612d3957612d39615707565b6020908102919091018101516001600160a01b031682528101919091526040015f2055600101612b08565b505050509392505050565b80611fdd5760405162461bcd60e51b81526020600482015260056024820152640828c9e60760db1b6044820152606401610943565b5f805f5b875160ff168160ff16101561301b57868160ff1681518110612dcc57612dcc615707565b60209081029190910101516040516370a0823160e01b81526001600160a01b038b81166004830152919350908316906370a0823190602401602060405180830381865afa158015612e1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e4391906153e3565b9250731b0e765f6224c21223aea2af16c1c46e38885a406001600160a01b031663b7034f7e898360ff1681518110612e7d57612e7d615707565b60209081029190910101516040516001600160e01b031960e084901b1681526001600160a01b039182166004820152908c166024820152600160448201526064015f604051808303815f87803b158015612ed5575f80fd5b505af1158015612ee7573d5f803e3d5ffd5b50506040516370a0823160e01b81526001600160a01b038c81166004830152869350851691506370a0823190602401602060405180830381865afa158015612f31573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f5591906153e3565b1115613013576040516370a0823160e01b81526001600160a01b038a811660048301528491908416906370a0823190602401602060405180830381865afa158015612fa2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fc691906153e3565b612fd091906152e6565b9250613011898387868873c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28c8860ff168151811061300457613004615707565b6020026020010151613ddb565b505b600101612da8565b505050505050505050565b5f805b84608001515181101561319e5760045485516060870151608088015180516001600160a01b03909416936327f746d7939291908690811061306c5761306c615707565b60200260200101516040518463ffffffff1660e01b81526004016130b0939291906001600160a01b0393841681526020810192909252909116604082015260600190565b602060405180830381865afa1580156130cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ef91906153e3565b915084602001516001600160a01b03168560800151828151811061311557613115615707565b60200260200101516001600160a01b03161415801561313357505f82115b1561319657613194855f01518660800151838151811061315557613155615707565b602002602001015187602001518589610120015173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b60c00151888151811061300457613004615707565b505b600101613029565b506007546131b8855f015186602001518760400151613e78565b11156131ee5760405162461bcd60e51b815260206004820152600560248201526441464f303160d81b6044820152606401610943565b6112e7848484613f61565b806001600160a01b0316826001600160a01b031614611f275760405162461bcd60e51b8152600401610943906020808252600490820152630414233360e41b604082015260600190565b5f805f5b600e548110156134f557866001600160a01b0316600e828154811061326e5761326e615707565b5f918252602090912001546001600160a01b0316148015906132ec57505f6132ea89600e84815481106132a3576132a3615707565b5f918252602080832091909101546001600160a01b038e81168452601b83526040808520549582168552601984528085209190921684528252808320938352929052205490565b115b156134ed576001600160a01b0388165f908152601c60209081526040808320601b8352818420548452909152902054600e8054613335918b91859081106132a3576132a3615707565b61333f9088615626565b6133499190615651565b925082156133bc5761335b8383615736565b91506133b98888600e848154811061337557613375615707565b905f5260205f20015f9054906101000a90046001600160a01b0316868873c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b888151811061300457613004615707565b92505b5f600e82815481106133d0576133d0615707565b5f918252602090912001546040516370a0823160e01b81526001600160a01b038b81166004830152909116906370a0823190602401602060405180830381865afa158015613420573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061344491906153e3565b111561347f5761347f883085600e858154811061346357613463615707565b5f918252602090912001546001600160a01b0316929190614151565b6001600160a01b0388165f908152601a60205260408120600e805486939190859081106134ae576134ae615707565b5f9182526020808320909101546001600160a01b0390811684528382019490945260409283018220938d168252601b8152828220548252929092529020555b600101613247565b505f5b600e54811015610e5057866001600160a01b0316600e828154811061351f5761351f615707565b5f918252602090912001546001600160a01b03161480156135a957506001600160a01b0388165f908152601960205260408120600e80548391908590811061356957613569615707565b5f9182526020808320909101546001600160a01b0390811684528382019490945260409283018220938d168252601b815282822054825292909252902054115b15613613576135b882876152e6565b92506135d3883085600e858154811061346357613463615707565b6001600160a01b038089165f818152601a60209081526040808320948c168352938152838220928252601b81528382205482529190915220839055610e50565b6001016134f8565b6001546001600160a01b03163314611f525760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610943565b600a5481116136ae5760405162461bcd60e51b815260206004820152600560248201526441464f303160d81b6044820152606401610943565b6001600160a01b039091165f90815260156020526040902055565b60025f540361371a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610943565b60025f55565b604051634b49628160e01b81523360048201526024810186905284151560448201528315156064820152821515608482015260a481018290526001600160a01b03871690634b4962819060c4015f604051808303815f87803b158015613784575f80fd5b505af1158015613796573d5f803e3d5ffd5b50505050505050505050565b80821015611f275760405162461bcd60e51b8152600401610943906020808252600490820152631053cc8d60e21b604082015260600190565b6001600160a01b038116611fdd5760405162461bcd60e51b8152600401610943906020808252600490820152634146303360e01b604082015260600190565b6040805160028082526060820183525f92839291906020830190803683375050600654825192935063ffffffff16918391505f9061385a5761385a615707565b602002602001019063ffffffff16908163ffffffff16815250505f8160018151811061388857613888615707565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81525f906001600160a01b0385169063883bdbfd906138cb9085906004016158e5565b5f60405180830381865afa1580156138e5573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261390c919081019061592d565b5090505f815f8151811061392257613922615707565b60200260200101518260018151811061393d5761393d615707565b602002602001015161394f91906159e1565b6006549091505f9061396a9063ffffffff1660030b83615a0e565b90505f8260060b128015613995575060065461398f9063ffffffff1660030b83615a4a565b60060b15155b156139a857806139a481615a6b565b9150505b6139b481898b8a614189565b9998505050505050505050565b335f9081526013602090815260408083206001600160a01b0396871684528252808320949095168252928352838120918152915290812055565b600280546001600160a01b0319169055611fdd81614287565b6040516001600160a01b03831660248201526044810182905261142f90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526142d8565b6003546001600160a01b03163314611f525760405162461bcd60e51b8152600401610943906152b6565b600954604051632b7746f160e01b81526001600160a01b0383811660048301525f921690632b7746f190602401602060405180830381865afa158015613ae9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b0d919061571b565b92915050565b5f80821215613b645760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610943565b5090565b5f806001600160a01b03861673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21480613bb157506001600160a01b03841673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2145b15613bc857613bc1868686611ae1565b9150613d17565b6001600160a01b038087165f818152601860205260409020549091161480613c0b57506001600160a01b038087165f908152601860205260409020548582169116145b15613c71576001600160a01b038087165f90815260186020526040902054613c35918891166143a9565b90506001600160a01b03831615613c495750815b6001600160a01b038087165f90815260186020526040902054613bc19188918891168461441d565b6001600160a01b038087165f90815260186020526040902054613c96918891166143a9565b6001600160a01b038088165f9081526018602052604081205492935091613cbf918791166143a9565b6001600160a01b038089165f90815260186020526040902054919250613cea9189918991168561441d565b6001600160a01b038089165f90815260186020526040902054919450613d13911684878461441d565b9250505b50949350505050565b60405163a4c69f3560e01b81526001600160a01b0383811660048301525f91829186169063a4c69f3590602401602060405180830381865afa158015613d68573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d8c91906153e3565b90506001811115613dd357600c54613da56001836152e6565b613daf9190615626565b600b54600c54613dbf91906152e6565b613dc99085615626565b611baa9190615651565b509392505050565b604051639908fc8b60e01b81526001600160a01b03878116600483015286811660248301526044820186905260648201859052838116608483015260a482018390525f9190891690639908fc8b9060c4016020604051808303815f875af1158015613e48573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e6c91906153e3565b98975050505050505050565b5f8115613f5a575f80613e8a8561275e565b915091505f856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ecb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613eef91906157b0565b613efa9060126157d0565b60ff16905081613f0b82600a6158da565b613f158588615626565b613f1f9190615626565b613f299190615651565b6001600160a01b038089165f90815260116020526040902054919550613f5691888216918a911688614151565b5050505b9392505050565b60408281015160095485519251630bf6f34d60e01b81526001600160a01b0393841660048201525f9390911690630bf6f34d906024016020604051808303815f875af1158015613fb3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fd791906153e3565b5f03614022575060608301515f9250825b81518110156140205781818151811061400357614003615707565b6020026020010151846140169190615736565b9350600101613fe8565b505b602085015185516040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561406d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061409191906153e3565b91505f5b846020015151811015611ad95760018282815181106140b6576140b6615707565b6020026020010151101580156140cb57505f83115b1561414957614147865f01518760200151876020015184815181106140f2576140f2615707565b60200260200101518786868151811061410d5761410d615707565b6020026020010151886141209190615626565b61412a9190615651565b8a61012001515f8c60a00151888151811061300457613004615707565b505b600101614095565b6040516001600160a01b03808516602483015283166044820152606481018290526112e79085906323b872dd60e01b90608401613a40565b5f8061419486614435565b90506001600160801b036001600160a01b03821611614219575f6141c16001600160a01b03831680615626565b9050836001600160a01b0316856001600160a01b0316106141f9576141f4600160c01b876001600160801b031683614750565b614211565b61421181876001600160801b0316600160c01b614750565b925050613d17565b5f6142376001600160a01b0383168068010000000000000000614750565b9050836001600160a01b0316856001600160a01b03161061426f5761426a600160801b876001600160801b031683614750565b613d13565b613d1381876001600160801b0316600160801b614750565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f61432c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166147fa9092919063ffffffff16565b80519091501561142f578080602001905181019061434a9190615599565b61142f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610943565b60095460405163298d501f60e11b81526001600160a01b03848116600483015283811660248301525f92169063531aa03e90604401602060405180830381865afa1580156143f9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f5a919061571b565b5f8061442b86868686611f2b565b9695505050505050565b5f805f8360020b1261444a578260020b614451565b8260020b5f035b9050620d89e8811115614477576040516315e4079d60e11b815260040160405180910390fd5b5f816001165f0361448c57600160801b61449e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff16905060028216156144d2576ffff97272373d413259a46990580e213a0260801c5b60048216156144f1576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615614510576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b601082161561452f576fffcb9843d60f6159c9db58835c9266440260801c5b602082161561454e576fff973b41fa98c081472e6896dfb254c00260801c5b604082161561456d576fff2ea16466c96a3843ec78b326b528610260801c5b608082161561458c576ffe5dee046a99a2a811c461f1969c30530260801c5b6101008216156145ac576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b6102008216156145cc576ff987a7253ac413176f2b074cf7815e540260801c5b6104008216156145ec576ff3392b0822b70005940c7a398e4b70f30260801c5b61080082161561460c576fe7159475a2c29b7443b29c7fa6e889d90260801c5b61100082161561462c576fd097f3bdfd2022b8845ad8f792aa58250260801c5b61200082161561464c576fa9f746462d870fdf8a65dc1f90e061e50260801c5b61400082161561466c576f70d869a156d2a1b890bb3df62baf32f70260801c5b61800082161561468c576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156146ad576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156146cd576e5d6af8dedb81196699c329225ee6040260801c5b620400008216156146ec576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615614709576b048a170391f7dc42444e8fa20260801c5b5f8460020b131561472857805f19816147245761472461563d565b0490505b64010000000081061561473c57600161473e565b5f5b60ff16602082901c0192505050919050565b5f80805f19858709858702925082811083820303915050805f03614784575f8411614779575f80fd5b508290049050613f5a565b80841161478f575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b60606120a684845f85855f80866001600160a01b0316858760405161481f9190615a8c565b5f6040518083038185875af1925050503d805f8114614859576040519150601f19603f3d011682016040523d82523d5f602084013e61485e565b606091505b5091509150613d1387838387606083156148d85782515f036148d1576001600160a01b0385163b6148d15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610943565b50816120a6565b6120a683838151156148ed5781518083602001fd5b8060405162461bcd60e51b81526004016109439190615aa2565b828054828255905f5260205f2090810192821561495a579160200282015b8281111561495a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614925565b50613b649291505b80821115613b64575f8155600101614962565b634e487b7160e01b5f52604160045260245ffd5b6040516101a081016001600160401b03811182821017156149ac576149ac614975565b60405290565b604051601f8201601f191681016001600160401b03811182821017156149da576149da614975565b604052919050565b6001600160a01b0381168114611fdd575f80fd5b8035614a01816149e2565b919050565b5f6001600160401b03821115614a1e57614a1e614975565b5060051b60200190565b5f82601f830112614a37575f80fd5b8135614a4a614a4582614a06565b6149b2565b8082825260208201915060208360051b860101925085831115614a6b575f80fd5b602085015b83811015614a91578035614a83816149e2565b835260209283019201614a70565b5095945050505050565b5f82601f830112614aaa575f80fd5b8135614ab8614a4582614a06565b8082825260208201915060208360051b860101925085831115614ad9575f80fd5b602085015b83811015614a91578035835260209283019201614ade565b5f60208284031215614b06575f80fd5b81356001600160401b03811115614b1b575f80fd5b82016101a08185031215614b2d575f80fd5b614b35614989565b614b3e826149f6565b8152614b4c602083016149f6565b6020820152604082810135908201526060808301359082015260808201356001600160401b03811115614b7d575f80fd5b614b8986828501614a28565b60808301525060a08201356001600160401b03811115614ba7575f80fd5b614bb386828501614a9b565b60a08301525060c08201356001600160401b03811115614bd1575f80fd5b614bdd86828501614a9b565b60c08301525060e08201356001600160401b03811115614bfb575f80fd5b614c0786828501614a28565b60e0830152506101008201356001600160401b03811115614c26575f80fd5b614c3286828501614a9b565b6101008301525061012082810135908201526101408201356001600160401b03811115614c5d575f80fd5b614c6986828501614a28565b610140830152506101608201356001600160401b03811115614c89575f80fd5b614c9586828501614a28565b610160830152506101808201356001600160401b03811115614cb5575f80fd5b614cc186828501614a9b565b61018083015250949350505050565b8015158114611fdd575f80fd5b5f805f805f8060c08789031215614cf2575f80fd5b8635614cfd816149e2565b95506020870135614d0d816149e2565b94506040870135935060608701356001600160401b03811115614d2e575f80fd5b614d3a89828a01614a9b565b93505060808701356001600160401b03811115614d55575f80fd5b614d6189828a01614a9b565b92505060a0870135614d7281614cd0565b809150509295509295509295565b5f805f60608486031215614d92575f80fd5b83356001600160401b03811115614da7575f80fd5b614db386828701614a28565b93505060208401356001600160401b03811115614dce575f80fd5b614dda86828701614a28565b92505060408401356001600160401b03811115614df5575f80fd5b8401601f81018613614e05575f80fd5b8035614e13614a4582614a06565b8082825260208201915060208360051b850101925088831115614e34575f80fd5b6020840193505b82841015614e6657833562ffffff81168114614e55575f80fd5b825260209384019390910190614e3b565b809450505050509250925092565b5f8060408385031215614e85575f80fd5b82356001600160401b03811115614e9a575f80fd5b614ea685828601614a28565b92505060208301356001600160401b03811115614ec1575f80fd5b614ecd85828601614a9b565b9150509250929050565b5f8060408385031215614ee8575f80fd5b8235614ef3816149e2565b946020939093013593505050565b5f60208284031215614f11575f80fd5b8135613f5a816149e2565b5f60208284031215614f2c575f80fd5b5035919050565b5f805f60608486031215614f45575f80fd5b8335614f50816149e2565b9250602084013591506040840135614f67816149e2565b809150509250925092565b5f805f60608486031215614f84575f80fd5b8335614f8f816149e2565b92506020840135614f9f816149e2565b91506040840135614f67816149e2565b5f8060408385031215614fc0575f80fd5b8235614fcb816149e2565b91506020830135614fdb816149e2565b809150509250929050565b5f8060408385031215614ff7575f80fd5b8235615002816149e2565b9150602083013561ffff81168114614fdb575f80fd5b80356001600160801b0381168114614a01575f80fd5b5f805f60608486031215615040575f80fd5b833561504b816149e2565b9250614f9f60208501615018565b5f805f806080858703121561506c575f80fd5b8435615077816149e2565b935061508560208601615018565b92506040850135615095816149e2565b915060608501356150a5816149e2565b939692955090935050565b5f805f80608085870312156150c3575f80fd5b84356150ce816149e2565b935060208501356150de816149e2565b925060408501356150ee816149e2565b9396929550929360600135925050565b5f806040838503121561510f575f80fd5b82356001600160401b03811115615124575f80fd5b61513085828601614a28565b92505060208301356001600160401b0381111561514b575f80fd5b614ecd85828601614a28565b5f805f60608486031215615169575f80fd5b8335615174816149e2565b92506020840135615184816149e2565b929592945050506040919091013590565b5f805f606084860312156151a7575f80fd5b83356151b2816149e2565b925060208401356001600160401b038111156151cc575f80fd5b6151d886828701614a28565b93969395505050506040919091013590565b5f602082840312156151fa575f80fd5b813563ffffffff81168114613f5a575f80fd5b5f806040838503121561521e575f80fd5b8235615229816149e2565b91506020830135614fdb81614cd0565b5f806040838503121561524a575f80fd5b50508035926020909101359150565b5f805f6060848603121561526b575f80fd5b8335615276816149e2565b92506020840135615286816149e2565b915060408401356001600160401b038111156152a0575f80fd5b6152ac86828701614a28565b9150509250925092565b6020808252600290820152614e4160f01b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115613b0d57613b0d6152d2565b5f806040838503121561530a575f80fd5b825161531581614cd0565b6020840151909250614fdb81614cd0565b5f82601f830112615335575f80fd5b8151615343614a4582614a06565b8082825260208201915060208360051b860101925085831115615364575f80fd5b602085015b83811015614a9157805161537c816149e2565b835260209283019201615369565b5f806040838503121561539b575f80fd5b82516001600160401b038111156153b0575f80fd5b6153bc85828601615326565b92505060208301516001600160401b038111156153d7575f80fd5b614ecd85828601615326565b5f602082840312156153f3575f80fd5b5051919050565b5f6020828403121561540a575f80fd5b81516001600160401b0381111561541f575f80fd5b6120a684828501615326565b5f8151808452602084019350602083015f5b828110156154645781516001600160a01b031686526020958601959091019060010161543d565b5093949350505050565b602081525f613f5a602083018461542b565b5f82601f83011261548f575f80fd5b815161549d614a4582614a06565b8082825260208201915060208360051b8601019250858311156154be575f80fd5b602085015b83811015614a915780518352602092830192016154c3565b5f80604083850312156154ec575f80fd5b82516001600160401b03811115615501575f80fd5b61550d85828601615480565b92505060208301516001600160401b03811115615528575f80fd5b614ecd85828601615480565b5f8151808452602084019350602083015f5b82811015615464578151865260209586019590910190600101615546565b6001600160a01b03841681526060602082018190525f906155879083018561542b565b828103604084015261442b8185615534565b5f602082840312156155a9575f80fd5b8151613f5a81614cd0565b5f805f80608085870312156155c7575f80fd5b84516001600160401b038111156155dc575f80fd5b6155e887828801615326565b94505060208501516001600160401b03811115615603575f80fd5b61560f87828801615326565b604087015160609097015195989097509350505050565b8082028115828204841417613b0d57613b0d6152d2565b634e487b7160e01b5f52601260045260245ffd5b5f8261565f5761565f61563d565b500490565b6001600160a01b03878116825260208201879052851660408201526060810184905260c0608082018190525f9061569d90830185615534565b82810360a084015283548082525f8581526020808220930191905b818110156156df5783546001600160a01b03168352600193840193602090930192016156b8565b50909a9950505050505050505050565b5f60018201615700576157006152d2565b5060010190565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561572b575f80fd5b8151613f5a816149e2565b80820180821115613b0d57613b0d6152d2565b805169ffffffffffffffffffff81168114614a01575f80fd5b5f805f805f60a08688031215615776575f80fd5b61577f86615749565b602087015160408801516060890151929750909550935091506157a460808701615749565b90509295509295909350565b5f602082840312156157c0575f80fd5b815160ff81168114613f5a575f80fd5b60ff8281168282160390811115613b0d57613b0d6152d2565b6001815b600184111561582457808504811115615808576158086152d2565b600184161561581657908102905b60019390931c9280026157ed565b935093915050565b5f8261583a57506001613b0d565b8161584657505f613b0d565b816001811461585c576002811461586657615882565b6001915050613b0d565b60ff841115615877576158776152d2565b50506001821b613b0d565b5060208310610133831016604e8410600b84101617156158a5575081810a613b0d565b6158b15f1984846157e9565b805f19048211156158c4576158c46152d2565b029392505050565b5f613f5a60ff84168361582c565b5f613f5a838361582c565b602080825282518282018190525f918401906040840190835b8181101561592257835163ffffffff168352602093840193909201916001016158fe565b509095945050505050565b5f806040838503121561593e575f80fd5b82516001600160401b03811115615953575f80fd5b8301601f81018513615963575f80fd5b8051615971614a4582614a06565b8082825260208201915060208360051b850101925087831115615992575f80fd5b6020840193505b828410156159c25783518060060b81146159b1575f80fd5b825260209384019390910190615999565b8095505050505060208301516001600160401b038111156153d7575f80fd5b600682810b9082900b03667fffffffffffff198112667fffffffffffff82131715613b0d57613b0d6152d2565b5f8160060b8360060b80615a2457615a2461563d565b667fffffffffffff1982145f1982141615615a4157615a416152d2565b90059392505050565b5f8260060b80615a5c57615a5c61563d565b808360060b0791505092915050565b5f8160020b627fffff198103615a8357615a836152d2565b5f190192915050565b5f82518060208501845e5f920191825250919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f8301168401019150509291505056fea264697066735822122001f9e8c8499a0143475c950927f11fbab318b326774b32de7e0544fca3944e3364736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000025b5720e9b20be18b4d020153ac26d957c83e341
-----Decoded View---------------
Arg [0] : passiveRebalContract (address): 0x25B5720E9b20Be18B4D020153ac26D957C83E341
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000025b5720e9b20be18b4d020153ac26d957c83e341
Deployed Bytecode Sourcemap
755:36688:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6896:1722;;;;;;:::i;:::-;;:::i;:::-;;17307:1364;;;;;;:::i;:::-;;:::i;27749:229::-;;;;;;:::i;:::-;;:::i;28285:459::-;;;;;;:::i;:::-;;:::i;2895:66::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;8973:25:21;;;8961:2;8946:18;2895:66:0;;;;;;;;23005:114;;;;;;:::i;:::-;-1:-1:-1;;;;;23091:23:0;23072:4;23091:23;;;:10;:23;;;;;;;23005:114;24426:128;;;;;;:::i;:::-;;:::i;29397:124::-;;;;;;:::i;:::-;;:::i;12720:1281::-;;;;;;:::i;:::-;;:::i;6253:291::-;;;;;;:::i;:::-;;:::i;914:58::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11106:8:21;11094:21;;;11076:40;;11064:2;11049:18;914:58:0;10932:190:21;23366:148:0;;;;;;:::i;:::-;;:::i;30214:754::-;;;;;;:::i;:::-;;:::i;:::-;;;;11295:25:21;;;11368:4;11356:17;;;11351:2;11336:18;;11329:45;11268:18;30214:754:0;11127:253:21;4444:83:0;4513:9;;4444:83;;23717:121;;;;;;:::i;:::-;-1:-1:-1;;;;;23808:25:0;23786:7;23808:25;;;:12;:25;;;;;;;23717:121;26972:207;;;;;;:::i;:::-;;:::i;36877:130::-;36972:10;;36984:5;;36991:10;;36877:130;;;-1:-1:-1;;;;;36972:10:0;;;12027:51:21;;36984:5:0;;;12109:2:21;12094:18;;12087:60;36991:10:0;;12163:18:21;;;12156:60;;;;12015:2;12000:18;36877:130:0;11805:417:21;27467:81:0;27533:10;;;;27467:81;;24814:363;;;;;;:::i;:::-;;:::i;1233:18::-;;;;;;;;;;;;13052:14:21;;13045:22;13027:41;;13015:2;13000:18;1233::0;12887:187:21;15430:1243:0;;;;;;:::i;:::-;;:::i;3041:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;25181:280;;;;;;:::i;:::-;;:::i;1824:101:13:-;;;:::i;29053:148:0:-;;;;;;:::i;:::-;;:::i;1759:206:14:-;;;:::i;4218:131:0:-;;;;;;:::i;:::-;;:::i;5382:106::-;;;:::i;1194:85:13:-;1266:6;;-1:-1:-1;;;;;1266:6:13;1194:85;;;-1:-1:-1;;;;;13852:32:21;;;13834:51;;13822:2;13807:18;1194:85:13;13688:203:21;29844:117:0;;;;;;:::i;:::-;-1:-1:-1;;;;;29933:23:0;29911:7;29933:23;;;:15;:23;;;;;;;29844:117;14832:225;;;;;;:::i;:::-;;:::i;4004:111::-;;;;;;:::i;:::-;-1:-1:-1;;;;;4083:27:0;;;4061:7;4083:27;;;:22;:27;;;;;;;;4004:111;4353:87;4424:11;;4353:87;;4531:405;;;;;;:::i;:::-;;:::i;32118:114::-;;;;;;:::i;:::-;;:::i;24157:108::-;24237:5;;24244:15;;24157:108;;;;15320:25:21;;;15376:2;15361:18;;15354:34;;;;15293:18;24157:108:0;15146:248:21;2663:80:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29525:107;29606:21;;29525:107;;21076:1749;;;;;;:::i;:::-;;:::i;5723:132::-;;;;;;:::i;:::-;;:::i;334:161:15:-;;;;;;:::i;:::-;;:::i;27383:80:0:-;;;;;;:::i;:::-;;:::i;499:87:15:-;570:11;;-1:-1:-1;;;;;570:11:15;499:87;;31308:806:0;;;;;;:::i;:::-;;:::i;37252:189::-;;;;;;:::i;:::-;;:::i;848:99:14:-;927:13;;-1:-1:-1;;;;;927:13:14;848:99;;2836:55:0;;;;;;:::i;:::-;;;;;;;;;;;;;;14591:237;;;;;;:::i;:::-;-1:-1:-1;;;;;14754:25:0;;;14732:7;14754:25;;;:19;:25;;;;;;;;:51;;;;;;;;;;;:59;;;;;;;;;;;;:69;;;;;;;;;;14591:237;24035:118;;;;;;:::i;:::-;;:::i;769:171:15:-;;;;;;:::i;:::-;;:::i;34115:323:0:-;;;;;;:::i;:::-;;:::i;5610:109::-;;;:::i;2747:85::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6548:186;;;;;;:::i;:::-;-1:-1:-1;;;;;6656:38:0;;;6624:7;6656:38;;;:25;:38;;;;;;;;;6696:19;:32;;;;;;;6656:38;;;;6696:32;;;6548:186;;;;;-1:-1:-1;;;;;17744:32:21;;;17726:51;;17813:32;;;;17808:2;17793:18;;17786:60;17699:18;6548:186:0;17552:300:21;35159:1714:0;;;;;;:::i;:::-;;:::i;6896:1722::-;7025:18;;-1:-1:-1;;;;;6999:45:0;;;;;;;:25;:45;;;;;;;6985:10;:59;;:95;;-1:-1:-1;7070:10:0;;-1:-1:-1;;;;;7070:10:0;7056;:24;6985:95;6970:128;;;;-1:-1:-1;;;6970:128:0;;;;;;;:::i;:::-;;;;;;;;;7192:18;;-1:-1:-1;;;;;7181:30:0;;;;;;;:10;:30;;;;;;;;;7150:18;;7137:32;;;;;:12;:32;;;;;;7119:50;;:15;:50;:::i;:::-;:92;;7104:146;;;;-1:-1:-1;;;7104:146:0;;19283:2:21;7104:146:0;;;19265:21:21;19322:2;19302:18;;;19295:30;19361:25;19341:18;;;19334:53;19404:18;;7104:146:0;19081:347:21;7104:146:0;7291:18;7320:6;:18;;;-1:-1:-1;;;;;7315:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7290:60;;;7356:26;7368:13;7356:11;:26::i;:::-;7389;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7389:26:0;7453:6;:18;;;-1:-1:-1;;;;;7448:38:0;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7448:40:0;;;;;;;;;;;;:::i;:::-;7421:67;7422:6;:20;;7421:67;;;;7521:6;:18;;;-1:-1:-1;;;;;7516:40:0;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7494:6;:19;;:64;;;;;7589:6;:18;;;-1:-1:-1;;;;;7584:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7584:37:0;;;;;;;;;;;;:::i;:::-;7564:17;;;:57;;;7635:24;7627:63;;;;-1:-1:-1;;;7627:63:0;;21976:2:21;7627:63:0;;;21958:21:21;22015:2;21995:18;;;21988:30;-1:-1:-1;;;22034:18:21;;;22027:52;22096:18;;7627:63:0;21774:346:21;7627:63:0;7701:24;;;;:31;:35;7697:257;;7744:210;7772:6;:18;;;7800:6;:19;;;7829:6;:24;;;7863:6;:34;;;7907:6;:13;;;7930:6;:16;;;7744:18;:210::i;:::-;7986:18;;8037:20;;;;7981:82;;-1:-1:-1;;;7981:82:0;;7961:17;;-1:-1:-1;;;;;7981:48:0;;;;:82;;8037:20;7981:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7961:102;;8142:6;:18;;;-1:-1:-1;;;;;8130:51:0;;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8130:53:0;;;;;;;;;;;;:::i;:::-;8099:27;;;8069:114;8070:27;;;8069:114;8189:47;8207:6;8070:9;8226;8189:17;:47::i;:::-;8243:10;;;8271:18;;8297:23;;;;8243:10;8328:19;;;8243:110;;-1:-1:-1;;;8243:110:0;;-1:-1:-1;;;;;8243:10:0;;;;:20;;:110;;8271:18;8297:23;8328:19;8243:110;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8435:18:0;;-1:-1:-1;;;;;8422:32:0;;;;;;;:12;:32;;;;;;8457:15;8422:50;;8483:18;;8478:51;;-1:-1:-1;;;8478:51:0;;;;;13027:41:21;;;;8478:44:0;;;;-1:-1:-1;8478:44:0;;-1:-1:-1;13000:18:21;;8478:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8547:10:0;;8587:18;;8535:78;;-1:-1:-1;;;8535:78:0;;-1:-1:-1;;;;;25359:32:21;;;8535:78:0;;;25341:51:21;8547:10:0;25408:18:21;;;25401:50;8547:10:0;;;-1:-1:-1;8535:51:0;;-1:-1:-1;25314:18:21;;8535:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6964:1654;;;6896:1722;:::o;17307:1364::-;-1:-1:-1;;;;;17553:32:0;;;;;;;:19;:32;;;;;;17528:58;;17541:10;;17553:32;17528:12;:58::i;:::-;-1:-1:-1;;;;;17604:30:0;;;;;;:17;:30;;;;;;17592:43;;17604:30;;17592:11;:43::i;:::-;17653:45;;-1:-1:-1;;;17653:45:0;;-1:-1:-1;;;;;13852:32:21;;;17653:45:0;;;13834:51:21;17641:58:0;;17653:37;;;;;;13807:18:21;;17653:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17641:11;:58::i;:::-;17734:10;;17722:67;;-1:-1:-1;;;17722:67:0;;-1:-1:-1;;;;;13852:32:21;;;17722:67:0;;;13834:51:21;17734:10:0;;;;17722:54;;13807:18:21;;17722:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17721:68;17706:112;;;;-1:-1:-1;;;17706:112:0;;25914:2:21;17706:112:0;;;25896:21:21;25953:2;25933:18;;;25926:30;-1:-1:-1;;;25972:18:21;;;25965:43;26025:18;;17706:112:0;25712:337:21;17706:112:0;17824:38;;-1:-1:-1;;;17824:38:0;;13052:14:21;;13045:22;17824:38:0;;;13027:41:21;-1:-1:-1;;;;;17824:26:0;;;;;13000:18:21;;17824:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;17956:32:0;;17873:12;17996:30;;;:17;:30;;;;;;;;18027:20;:33;;;;;;17996:65;;;;;;;;;17956:111;;-1:-1:-1;;;;;;17956:111:0;;;;;8973:25:21;;;;17873:12:0;;;;17956:32;;8946:18:21;;17956:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17956:111:0;;;;;;;;;;;;:::i;:::-;17917:150;;;;-1:-1:-1;17917:150:0;-1:-1:-1;17917:150:0;;;;17918:5;;;;17917:150;;17925:7;;17917:150;;;;;:::i;:::-;-1:-1:-1;;17917:150:0;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;18094:30:0;;18073:11;18094:30;;;:17;:30;;;;;;;;18125:20;:33;;;;;;18094:65;;;;;;;;18073:11;;-1:-1:-1;18094:69:0;18090:380;;-1:-1:-1;;;;;18199:30:0;;;;;;:17;:30;;;;;;;;18230:20;:33;;;;;;18199:65;;;;;;;;18278:12;;18191:74;;:4;:74;:::i;:::-;18190:101;;;;:::i;:::-;18308:10;;;:155;;-1:-1:-1;;;18308:155:0;;18173:118;;-1:-1:-1;;;;;;18308:10:0;;:30;;:155;;18348:11;;18173:118;;18385:6;;18401:8;;18419:19;;18448:7;;18308:155;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18299:164;;18090:380;18476:71;18492:11;18505:6;18513;18521:15;18538:8;18476:15;:71::i;:::-;-1:-1:-1;;;;;18560:30:0;;;;;;:17;:30;;;;;;;;18591:20;:33;;;;;;;;18560:65;;;;;;;;18553:72;;;18631:33;;;;;:35;;;18591:33;18631:35;;;:::i;:::-;;;;;;17522:1149;;;17307:1364;;;;;;:::o;27749:229::-;1087:13:13;:11;:13::i;:::-;27893:6:0::1;27888:86;27905:4;:11;27901:1;:15;27888:86;;;27960:4;27965:1;27960:7;;;;;;;;:::i;:::-;;;;;;;27931:4;:15;27936:6;27943:1;27936:9;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;27931:15:0::1;-1:-1:-1::0;;;;;27931:15:0::1;;;;;;;;;;;;:26;27947:6;27954:1;27947:9;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;27931:26:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;27931:26:0;:36;;-1:-1:-1;;27931:36:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;27918:3:0::1;27888:86;;;;27749:229:::0;;;:::o;28285:459::-;1266:6:13;;-1:-1:-1;;;;;1266:6:13;28431:10:0;:21;;:92;;;28490:10;;;;;;;;;-1:-1:-1;;;;;28490:10:0;-1:-1:-1;;;;;28478:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;28464:59:0;:10;-1:-1:-1;;;;;28464:59:0;;28431:92;28416:125;;;;-1:-1:-1;;;28416:125:0;;;;;;;:::i;:::-;28582:16;:23;28555:16;:23;:50;28547:69;;;;-1:-1:-1;;;28547:69:0;;29226:2:21;28547:69:0;;;29208:21:21;29265:1;29245:18;;;29238:29;-1:-1:-1;;;29283:18:21;;;29276:36;29329:18;;28547:69:0;29024:329:21;28547:69:0;28627:6;28622:118;28643:16;:23;28639:1;:27;28622:118;;;28681:52;28692:16;28709:1;28692:19;;;;;;;;:::i;:::-;;;;;;;28713:16;28730:1;28713:19;;;;;;;;:::i;:::-;;;;;;;28681:10;:52::i;:::-;28668:3;;28622:118;;;;28285:459;;:::o;24426:128::-;1087:13:13;:11;:13::i;:::-;24503:15:0::1;;24493:6;:25;;24485:44;;;::::0;-1:-1:-1;;;24485:44:0;;29560:2:21;24485:44:0::1;::::0;::::1;29542:21:21::0;29599:1;29579:18;;;29572:29;-1:-1:-1;;;29617:18:21;;;29610:36;29663:18;;24485:44:0::1;29358:329:21::0;24485:44:0::1;24535:5;:14:::0;24426:128::o;29397:124::-;1087:13:13;:11;:13::i;:::-;29479:21:0::1;:37:::0;29397:124::o;12720:1281::-;2261:21:16;:19;:21::i;:::-;-1:-1:-1;;;;;12852:30:0;::::1;;::::0;;;:17:::1;:30;::::0;;;;;12838:46:::1;::::0;12852:30:::1;;12850:33;12838:11;:46::i;:::-;12891:63;::::0;-1:-1:-1;;;12891:63:0;;12926:10:::1;12891:63;::::0;::::1;29894:51:21::0;-1:-1:-1;;;;;29981:32:21;;;29961:18;;;29954:60;30030:18;;;30023:34;;;12891::0;::::1;::::0;::::1;::::0;29867:18:21;;12891:63:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;13014:10:0::1;12961:30;12994:31:::0;;;:19:::1;:31;::::0;;;;;;;-1:-1:-1;;;;;12994:69:0;;::::1;::::0;;;;;;;;;:77;;::::1;::::0;;;;;;;13072:33;;;:20:::1;:33:::0;;;;;;12994:112;;;;;;;;;13130:44;;-1:-1:-1;;;13130:44:0;;::::1;::::0;::::1;13834:51:21::0;;;;12994:112:0;-1:-1:-1;12961:30:0;;-1:-1:-1;12994:69:0;13130:32:::1;::::0;13807:18:21;;13130:44:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13112:62:::0;-1:-1:-1;13296:32:0::1;13321:7:::0;13296:22;:32:::1;:::i;:::-;13201:10;13181:31;::::0;;;:19:::1;:31;::::0;;;;;;;-1:-1:-1;;;;;13181:57:0;;::::1;::::0;;;;;;;;;:65;;::::1;::::0;;;;;;;;;13254:33;;;:20:::1;:33:::0;;;;;;;13181:112;;;;;;;;:147;;;;13355:25;;;:13:::1;:25:::0;;;;;:48;;;;;;;;:56;;;;;;;;;13412:33;;13355:91;;;;;;;;;13616:32:::1;13641:7:::0;13616:22;:32:::1;:::i;:::-;13593:17;13603:7:::0;13593;:17:::1;:::i;:::-;13549:33;13560:22:::0;13549:8;:33:::1;:::i;:::-;13548:64;;;;:::i;:::-;13547:102;;;;:::i;:::-;13467:10;13453:25;::::0;;;:13:::1;:25;::::0;;;;;;;-1:-1:-1;;;;;13453:48:0;;::::1;::::0;;;;;;;;;:56;;::::1;::::0;;;;;;;;;13510:33;;;:20:::1;:33:::0;;;;;;;13453:91;;;;;;;;:196;;;;13656:24;;;:11:::1;:24:::0;;;;;:32;;;;;;;;13689:33;;13656:67;;;;;;;;:78;;13727:7;;13453:25;13656:78:::1;::::0;13727:7;;13656:78:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;13755:30:0;::::1;;::::0;;;:17:::1;:30;::::0;;;;;;;13786:20:::1;:33:::0;;;;;;13755:65;;;;;;;:76;;13824:7;;13755:30;:76:::1;::::0;13824:7;;13755:76:::1;:::i;:::-;::::0;;;-1:-1:-1;13838:70:0::1;::::0;-1:-1:-1;13864:11:0;13877:7;13886:5:::1;13893:4;13886:5:::0;;13838:25:::1;:70::i;:::-;-1:-1:-1::0;;;;;13962:33:0;;::::1;;::::0;;;:20:::1;:33;::::0;;;;;;;;;13919:77;;15320:25:21;;;15361:18;;;15354:34;13919:77:0;;::::1;::::0;13933:10:::1;::::0;13919:77:::1;::::0;15293:18:21;13919:77:0::1;;;;;;;12832:1169;;;2303:20:16::0;1716:1;2809:7;:22;2629:209;6253:291:0;1087:13:13;:11;:13::i;:::-;-1:-1:-1;;;;;6412:38:0;;::::1;;::::0;;;:25:::1;:38;::::0;;;;;;;:66;;;;::::1;-1:-1:-1::0;;;;;;6412:66:0;;::::1;;::::0;;6484:19:::1;:32:::0;;;;;:55;;;;;::::1;::::0;::::1;;::::0;;6253:291::o;23366:148::-;1087:13:13;:11;:13::i;:::-;-1:-1:-1;;;;;23470:23:0;;::::1;;::::0;;;:10:::1;:23;::::0;;;;:39;23366:148::o;30214:754::-;30306:6;30314:5;30330:14;30348:17;30393:4;-1:-1:-1;;;;;30371:50:0;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30327:96;;;;;;;30430:30;30485:4;-1:-1:-1;;;;;30463:38:0;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30430:73;;30510:16;30551:22;-1:-1:-1;;;;;30529:55:0;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30510:76;;30593:16;30634:22;-1:-1:-1;;;;;30612:55:0;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30593:76;;30697:8;30685:7;30680:25;;:54;;;;30726:8;30714:7;30709:25;;30680:54;30676:75;;;30736:15;;-1:-1:-1;;;30736:15:0;;31160:2:21;30736:15:0;;;31142:21:21;31199:1;31179:18;;;31172:29;-1:-1:-1;;;31217:18:21;;;31210:35;31262:18;;30736:15:0;30958:328:21;30676:75:0;30758:14;30797:4;-1:-1:-1;;;;;30775:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30866:23:0;;;;;;:15;:23;;;;;;30758:55;;-1:-1:-1;30819:71:0;;30837:9;;30848:41;;:15;:41;:::i;:::-;30819:17;:71::i;:::-;30896:35;30919:7;30929:1;30896:17;:35::i;:::-;30945:7;;;;-1:-1:-1;30214:754:0;;-1:-1:-1;;;;;;;30214:754:0:o;26972:207::-;27078:96;;-1:-1:-1;;;27078:96:0;;31743:6:21;31731:19;;27078:96:0;;;31713:38:21;-1:-1:-1;;;;;27078:56:0;;;;;31686:18:21;;27078:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26972:207;;:::o;24814:363::-;-1:-1:-1;;;;;25050:13:0;;;24931:14;25050:13;;;:4;:13;;;;;;;;:23;;;;;;;;;;;;;;24969:110;;-1:-1:-1;;;24969:110:0;;;;;31962:51:21;;;;32029:18;;;32022:60;;;;25050:23:0;;;;32098:18:21;;;32091:49;24931:14:0;;;1521:42;;24969;;31935:18:21;;24969:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24953:126;;25085:18;25097:5;25085:11;:18::i;:::-;25121:51;25137:7;25146:8;25156;25166:5;25121:15;:51::i;:::-;25109:63;24814:363;-1:-1:-1;;;;;24814:363:0:o;15430:1243::-;2261:21:16;:19;:21::i;:::-;-1:-1:-1;;;;;15534:30:0;::::1;;::::0;;;:17:::1;:30;::::0;;;;;15520:46:::1;::::0;15534:30:::1;;15532:33;15520:11;:46::i;:::-;15614:10;15573:18;15594:31:::0;;;:19:::1;:31;::::0;;;;;;;-1:-1:-1;;;;;15594:57:0;;::::1;::::0;;;;;;;;;:77;;::::1;::::0;;;;;;;15672:33;;;:20:::1;:33:::0;;;;;;15594:112;;;;;;;;15721:14;15713:38:::1;;;::::0;-1:-1:-1;;;15713:38:0;;32353:2:21;15713:38:0::1;::::0;::::1;32335:21:21::0;32392:2;32372:18;;;32365:30;-1:-1:-1;;;32411:18:21;;;32404:41;32462:18;;15713:38:0::1;32151:335:21::0;15713:38:0::1;-1:-1:-1::0;;;;;15758:24:0;;::::1;;::::0;;;:11:::1;:24;::::0;;;;;;;:32;;::::1;::::0;;;;;;;;15791:33;;;:20:::1;:33:::0;;;;;;15758:67;;;;;;;;;:81;;15829:10;;15758:24;:81:::1;::::0;15829:10;;15758:81:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;15907:33:0;::::1;;::::0;;;:20:::1;:33;::::0;;;;;15860:81:::1;::::0;15886:11;;15899:6;;15860:25:::1;:81::i;:::-;-1:-1:-1::0;;;;;15947:30:0;::::1;;::::0;;;:17:::1;:30;::::0;;;;;;;15978:20:::1;:33:::0;;;;;;15947:65;;;;;;;:79;;16016:10;;15947:30;:79:::1;::::0;16016:10;;15947:79:::1;:::i;:::-;::::0;;;-1:-1:-1;;16099:10:0::1;16033:14;16085:25:::0;;;:13:::1;:25;::::0;;;;;;;-1:-1:-1;;;;;16085:48:0;;::::1;::::0;;;;;;;;;:56;;::::1;::::0;;;;;;;16142:33;;;:20:::1;:33:::0;;;;;;16085:91;;;;;;;;;;16182:98;;;;16451:41;;-1:-1:-1;;;16451:41:0;;::::1;::::0;::::1;13834:51:21::0;;;;16050:10:0;;16085:91;;16033:14;16085:48;16451:29:::1;::::0;13807:18:21;;16451:41:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16440:52;::::0;16441:6;16440:52:::1;:::i;:::-;16388:41;::::0;-1:-1:-1;;;16388:41:0;;16418:10:::1;16388:41;::::0;::::1;13834:51:21::0;-1:-1:-1;;;;;16388:29:0;::::1;::::0;::::1;::::0;13807:18:21;;16388:41:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16341:44;::::0;-1:-1:-1;;;16341:44:0;;16374:10:::1;16341:44;::::0;::::1;13834:51:21::0;-1:-1:-1;;;;;16341:32:0;::::1;::::0;::::1;::::0;13807:18:21;;16341:44:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:88;;;;:::i;:::-;16315:16;16325:6:::0;16315:8;:16:::1;:::i;:::-;16314:115;;;;:::i;:::-;16313:180;;;;:::i;:::-;16291:202;;16500:83;16526:11;16539:10;16551:5;16558::::0;16565:4:::1;16571:11;16500:25;:83::i;:::-;-1:-1:-1::0;;;;;16634:33:0;::::1;;::::0;;;:20:::1;:33;::::0;;;;;;;;;16594:74;;15320:25:21;;;15361:18;;;15354:34;16610:10:0::1;::::0;16594:74:::1;::::0;15293:18:21;16594:74:0::1;;;;;;;15514:1159;;;;2303:20:16::0;1716:1;2809:7;:22;2629:209;2303:20;15430:1243:0;;:::o;25181:280::-;25329:14;25351:27;25363:14;25351:11;:27::i;:::-;25396:60;25412:7;25421:8;25431;25441:14;25396:15;:60::i;1824:101:13:-;1087:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;29053:148:0:-;1087:13:13;:11;:13::i;:::-;29160:36:0::1;29171:6;29179:16;29160:10;:36::i;1759:206:14:-:0;927:13;;719:10:3;;-1:-1:-1;;;;;927:13:14;1852:24;;1844:78;;;;-1:-1:-1;;;1844:78:14;;32693:2:21;1844:78:14;;;32675:21:21;32732:2;32712:18;;;32705:30;32771:34;32751:18;;;32744:62;-1:-1:-1;;;32822:18:21;;;32815:39;32871:19;;1844:78:14;32491:405:21;1844:78:14;1932:26;1951:6;1932:18;:26::i;:::-;1795:170;1759:206::o;4218:131:0:-;1087:13:13;:11;:13::i;:::-;4290:24:0::1;4302:11;4290;:24::i;:::-;4320:10;:24:::0;;-1:-1:-1;;;;;;4320:24:0::1;-1:-1:-1::0;;;;;4320:24:0;;;::::1;::::0;;;::::1;::::0;;4218:131::o;5382:106::-;4987:6;;4974:20;;4987:6;;4986:7;4974:11;:20::i;:::-;1087:13:13::1;:11;:13::i;:::-;5441:6:0::2;:13:::0;;-1:-1:-1;;5441:13:0::2;5450:4;5441:13;::::0;;5465:18:::2;::::0;5472:10:::2;13834:51:21::0;;5465:18:0::2;::::0;13822:2:21;13807:18;5465::0::2;;;;;;;;5382:106::o:0;14832:225::-;-1:-1:-1;;;;;14992:19:0;;;14970:7;14992:19;;;:13;:19;;;;;;;;:42;;;;;;;;;;:50;;;;;;;;;;;:60;;;;;;;14832:225;;;;;;;:::o;4531:405::-;1266:6:13;;-1:-1:-1;;;;;1266:6:13;4632:10:0;:21;;:57;;-1:-1:-1;4679:10:0;;-1:-1:-1;;;;;4679:10:0;4665;:24;4632:57;:128;;;;4727:10;;;;;;;;;-1:-1:-1;;;;;4727:10:0;-1:-1:-1;;;;;4715:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;4701:59:0;:10;-1:-1:-1;;;;;4701:59:0;;4632:128;4617:161;;;;-1:-1:-1;;;4617:161:0;;;;;;;:::i;:::-;4789:6;4784:148;4801:3;:10;4797:1;:14;4784:148;;;4826:19;4838:3;4842:1;4838:6;;;;;;;;:::i;:::-;;;;;;;4826:11;:19::i;:::-;4853:22;4865:6;4872:1;4865:9;;;;;;;;:::i;4853:22::-;4916:6;4923:1;4916:9;;;;;;;;:::i;:::-;;;;;;;4883:22;:30;4906:3;4910:1;4906:6;;;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;4883:30:0;;;;;;;;;;;;;;-1:-1:-1;4883:30:0;:42;;-1:-1:-1;;;;;;4883:42:0;;;;;;;;;;;-1:-1:-1;4813:3:0;4784:148;;32118:114;1087:13:13;:11;:13::i;:::-;32188:19:0::1;32200:6;32188:11;:19::i;:::-;32213:5;:14:::0;;-1:-1:-1;;;;;;32213:14:0::1;-1:-1:-1::0;;;;;32213:14:0;;;::::1;::::0;;;::::1;::::0;;32118:114::o;21076:1749::-;-1:-1:-1;;;;;21225:42:0;;;;;;:20;:42;;;;;;21204:63;;21196:80;;;;-1:-1:-1;;;21196:80:0;;;;;;33103:2:21;33085:21;;;33142:1;33122:18;;;33115:29;-1:-1:-1;;;33175:2:21;33160:18;;33153:34;33219:2;33204:18;;32901:327;21196:80:0;21282:20;21308:32;21346:18;21370:22;21445:6;21440:1381;21461:8;:15;21457:1;:19;21440:1381;;;21524:10;21504:31;;;;:19;:31;;;;;;;;-1:-1:-1;;;;;21504:66:0;;;;;;;;;21580:11;;21504:66;;:31;21580:8;;21589:1;;21580:11;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;21504:95:0;;;;;;;;;;;;;;;;-1:-1:-1;21504:95:0;;;:115;;;;;;;;;21658:10;21644:25;;:13;:25;;;;;:57;;;;;;;;;;;;21702:11;;21504:115;;-1:-1:-1;21644:57:0;21702:8;;21711:1;;21702:11;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;21644:70:0;-1:-1:-1;;;;;21644:70:0;;;;;;;;;;;;:90;21715:18;21644:90;;;;;;;;;;;;21627:107;;21759:1;21746:10;:14;21742:1073;;;-1:-1:-1;;;;;21903:33:0;;;;;;:11;:33;;;;;21937:11;;21903:33;;;21937:8;;21946:1;;21937:11;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;21903:46:0;-1:-1:-1;;;;;21903:46:0;;;;;;;;;;;;:66;21950:18;21903:66;;;;;;;;;;;;21816:16;:38;21841:11;-1:-1:-1;;;;;21816:38:0;-1:-1:-1;;;;;21816:38:0;;;;;;;;;;;;:51;21855:8;21864:1;21855:11;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;21816:51:0;-1:-1:-1;;;;;21816:51:0;;;;;;;;;;;;:71;21868:18;21816:71;;;;;;;;;;;;21792:10;:96;;;;:::i;:::-;21791:179;;;;:::i;:::-;21772:199;;21983:13;21998:18;22020:27;22035:8;22044:1;22035:11;;;;;;;;:::i;:::-;;;;;;;22020:14;:27::i;:::-;21982:65;;;;22057:14;22086:8;22095:1;22086:11;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;22079:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22074:35;;:2;:35;:::i;:::-;22057:52;-1:-1:-1;22225:14:0;22057:52;22225:2;:14;:::i;:::-;22216:24;;:5;:24;:::i;:::-;:32;;22243:5;22216:32;:::i;:::-;22190:10;22157:29;22175:10;22157:14;:29;:::i;:::-;:44;;;;:::i;:::-;22156:93;;;;:::i;:::-;22119:130;;22282:24;22264:15;:42;22260:346;;;22437:11;;22466:3;;22390:42;22408:24;22390:15;:42;:::i;:::-;22389:60;;;;:::i;:::-;22388:82;;;;:::i;:::-;-1:-1:-1;;;;;22320:39:0;;;;;;:17;:39;;;;;22360:11;;22320:39;;;22360:8;;22369:1;;22360:11;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;22320:52:0;-1:-1:-1;;;;;22320:52:0;;;;;;;;;;;;;:150;;;;;;;:::i;:::-;;;;-1:-1:-1;;22562:11:0;;22591:3;;22515:42;22533:24;22515:15;:42;:::i;:::-;22514:60;;;;:::i;:::-;22513:82;;;;:::i;:::-;22482:113;;;;:::i;:::-;;;22260:346;22615:120;22660:11;22684:8;22693:1;22684:11;;;;;;;;:::i;:::-;;;;;;;22707:18;22615:25;:120::i;:::-;22745:61;22778:10;22790:15;22752:8;22761:1;22752:11;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;22745:32:0;;;:61;;;;;:::i;:::-;21762:1053;;;21742:1073;21478:3;;21440:1381;;5723:132;1087:13:13;:11;:13::i;:::-;5789:21:0::1;5801:8;5789:11;:21::i;:::-;5816:10;:34:::0;;-1:-1:-1;;;;;;5816:34:0::1;-1:-1:-1::0;;;;;5816:34:0;;;::::1;::::0;;;::::1;::::0;;5723:132::o;334:161:15:-;395:15;:13;:15::i;:::-;-1:-1:-1;;;;;424:26:15;;416:42;;;;-1:-1:-1;;;416:42:15;;35023:2:21;416:42:15;;;35005:21:21;35062:1;35042:18;;;35035:29;-1:-1:-1;;;35080:18:21;;;35073:33;35123:18;;416:42:15;34821:326:21;416:42:15;464:11;:26;;-1:-1:-1;;;;;;464:26:15;-1:-1:-1;;;;;464:26:15;;;;;;;;;;334:161::o;27383:80:0:-;1087:13:13;:11;:13::i;:::-;27442:10:0::1;:16:::0;;-1:-1:-1;;27442:16:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;27383:80::o;31308:806::-;31366:7;;31411:3;31366:7;-1:-1:-1;;;;;31483:11:0;;1599:42;31483:11;31479:599;;31504:14;31521:24;31541:3;31521:19;:24::i;:::-;31504:41;-1:-1:-1;;;;;;31557:20:0;;;31553:467;;31590:15;31611:32;31631:3;31636:6;31611:19;:32::i;:::-;31589:54;;;31654:16;31676:38;1599:42;1684;31676:19;:38::i;:::-;31653:61;;;31788:31;31808:9;31788:18;:31::i;:::-;31734:28;31753:8;31734:18;:28::i;:::-;:40;;31766:7;31734:40;:::i;:::-;31733:86;;;;:::i;:::-;31724:96;;31579:250;;31553:467;;;31845:22;31877:3;-1:-1:-1;;;;;31870:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31845:47;;;-1:-1:-1;31902:16:0;31921:20;31845:47;31921:2;:20;:::i;:::-;31902:39;;31959:52;31979:3;31984:8;1599:42;32008:1;31959:19;:52::i;:::-;31951:60;;31835:185;;31553:467;31496:530;31479:599;;;-1:-1:-1;32048:1:0;;-1:-1:-1;32048:1:0;31479:599;32091:5;32098:10;;-1:-1:-1;31308:806:0;-1:-1:-1;;31308:806:0:o;37252:189::-;-1:-1:-1;;;;;37353:38:0;;;;;;;:25;:38;;;;;;37328:64;;37341:10;;37353:38;37328:12;:64::i;:::-;-1:-1:-1;;;;;37398:30:0;;;;;;;;:17;:30;;;;;:38;;-1:-1:-1;;37398:38:0;;;;;;;;;;37252:189::o;24035:118::-;1087:13:13;:11;:13::i;:::-;24114:15:0::1;:34:::0;24035:118::o;769:171:15:-;836:15;:13;:15::i;:::-;857:13;:24;;-1:-1:-1;;;;;857:24:15;;-1:-1:-1;;;;;;857:24:15;;;;;;;;917:7;1266:6:13;;-1:-1:-1;;;;;1266:6:13;;1194:85;917:7:15;-1:-1:-1;;;;;892:43:15;;;;;;;;;;;769:171;:::o;34115:323:0:-;1087:13:13;:11;:13::i;:::-;4987:6:0::1;::::0;4974:20:::1;::::0;4987:6:::1;;4986:7;4974:11;:20::i;:::-;34254:12:::2;34240:10;:26;;:48;;;;;34286:2;34270:12;:18;;34240:48;34232:65;;;;-1:-1:-1::0;;;34232:65:0::2;;;;;;35490:2:21::0;35472:21;;;35529:1;35509:18;;;35502:29;-1:-1:-1;;;35562:2:21;35547:18;;35540:34;35606:2;35591:18;;35288:327;34232:65:0::2;34303:9;:22:::0;;;34331:11:::2;:26:::0;;;34368:42:::2;::::0;;15320:25:21;;;15376:2;15361:18;;15354:34;;;34368:42:0::2;::::0;15293:18:21;34368:42:0::2;;;;;;;34115:323:::0;;:::o;5610:109::-;5054:6;;5042:19;;5054:6;;5042:11;:19::i;:::-;1087:13:13::1;:11;:13::i;:::-;5669:6:0::2;:14:::0;;-1:-1:-1;;5669:14:0::2;::::0;;5694:20:::2;::::0;5703:10:::2;13834:51:21::0;;5694:20:0::2;::::0;13822:2:21;13807:18;5694:20:0::2;13688:203:21::0;35159:1714:0;35307:21;1087:13:13;:11;:13::i;:::-;35458:69:0::1;::::0;-1:-1:-1;;;35458:69:0;;-1:-1:-1;;;;;13852:32:21;;;35458:69:0::1;::::0;::::1;13834:51:21::0;35426:29:0::1;::::0;35458:44;;::::1;::::0;::::1;::::0;13807:18:21;;35458:69:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;35458:69:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;35426:101;;35533:23;35562:19:::0;35629:6:::1;35624:1245;35641:6;:13;35637:1;:17;35624:1245;;;-1:-1:-1::0;;;;;35683:30:0;::::1;;::::0;;;:17:::1;:30;::::0;;;;35714:9;;35683:30;;;35714:6;;35721:1;;35714:9;::::1;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;35683:41:0::1;-1:-1:-1::0;;;;;35683:41:0::1;;;;;;;;;;;;;35669:55;;35750:1;35736:11;:15;35732:1078;;;35781:55;35798:11;35811;35824;35781:16;:55::i;:::-;35763:73;;35858:22;35892:13:::0;35922:6:::1;35917:875;35938:12;:19;35934:1;:23;35917:875;;;36005:11;-1:-1:-1::0;;;;;35993:45:0::1;;36054:11;36081:12;36094:1;36081:15;;;;;;;;:::i;:::-;;;;;;;35993:117;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;17744:32:21;;;17726:51;;17813:32;;17808:2;17793:18;;17786:60;17714:2;17699:18;;17552:300;35993:117:0::1;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;35978:132:0;-1:-1:-1;36124:656:0;::::1;;;36158:1;36163;36158:6:::0;36154:380:::1;;36389:11;::::0;36374:9:::1;::::0;36359:25:::1;::::0;:11;:25:::1;:::i;:::-;36358:43;;;;:::i;:::-;36341:60;;36433:14;36419:28;;36154:380;;;36502:15;36488:29;;36154:380;36569:32;36589:11:::0;36569:16;:32:::1;:::i;:::-;36550:51;;36618:60;36649:12;36662:1;36649:15;;;;;;;;:::i;:::-;;;;;;;36666:11;36625:6;36632:1;36625:9;;;;;;;;:::i;36618:60::-;36736:12;36749:1;36736:15;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;36700:65:0::1;36723:11;-1:-1:-1::0;;;;;36700:65:0::1;;36753:11;36700:65;;;;8973:25:21::0;;8961:2;8946:18;;8827:177;36700:65:0::1;;;;;;;;36124:656;35959:3;;35917:875;;;;35846:956;;35732:1078;-1:-1:-1::0;;;;;36817:30:0;::::1;36861:1;36817:30:::0;;;:17:::1;:30;::::0;;;;36848:9;;36861:1;;36848:6;;36855:1;;36848:9;::::1;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;36817:41:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;36817:41:0;:45;35656:3:::1;;35624:1245;;;;35330:1543;;;35159:1714:::0;;;;;:::o;5077:83::-;5139:6;5131:24;;;;-1:-1:-1;;;5131:24:0;;35822:2:21;5131:24:0;;;35804:21:21;35861:1;35841:18;;;35834:29;-1:-1:-1;;;35879:18:21;;;35872:35;35924:18;;5131:24:0;35620:328:21;8622:816:0;8862:17;8885:11;8907:7;8902:532;8930:12;:19;8920:30;;:1;:30;;;8902:532;;;8971:17;8989:1;8971:20;;;;;;;;;;:::i;:::-;;;;;;;;;;;9011:34;;-1:-1:-1;;;9011:34:0;;-1:-1:-1;;;;;13852:32:21;;;9011:34:0;;;13834:51:21;8971:20:0;;-1:-1:-1;9011:21:0;;;;;;13807:18:21;;9011:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8999:46;;1874:42;-1:-1:-1;;;;;9054:19:0;;9074:12;9087:1;9074:15;;;;;;;;;;:::i;:::-;;;;;;;;;;;9054:55;;-1:-1:-1;;;;;;9054:55:0;;;;;;;-1:-1:-1;;;;;36167:32:21;;;9054:55:0;;;36149:51:21;36236:32;;;36216:18;;;36209:60;9104:4:0;36285:18:21;;;36278:50;36122:18;;9054:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9121:34:0;;-1:-1:-1;;;9121:34:0;;-1:-1:-1;;;;;13852:32:21;;;9121:34:0;;;13834:51:21;9158:9:0;;-1:-1:-1;9121:21:0;;;-1:-1:-1;9121:21:0;;13807:18:21;;9121:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;9117:311;;;9191:34;;-1:-1:-1;;;9191:34:0;;-1:-1:-1;;;;;13852:32:21;;;9191:34:0;;;13834:51:21;9228:9:0;;9191:21;;;;;;13807:18:21;;9191:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;;;:::i;:::-;9179:58;;9247:172;9265:11;9288:3;9303:6;9321:9;9342;1762:42;9379:27;9407:1;9379:30;;;;;;;;;;:::i;:::-;;;;;;;9247:6;:172::i;:::-;;9117:311;8952:3;;8902:532;;;;8856:582;;8622:816;;;;;;:::o;9442:914::-;9582:12;;9600:507;9624:6;:20;;;:27;9620:1;:31;9600:507;;;9675:10;;9720:18;;9748:19;;;;9777:20;;;;:23;;-1:-1:-1;;;;;9675:10:0;;;;:35;;9720:18;9748:19;9777:20;9798:1;;9777:23;;;;;;:::i;:::-;;;;;;;9675:133;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36559:32:21;;;36541:51;;36623:2;36608:18;;36601:34;;;;36671:32;;;36666:2;36651:18;;36644:60;36529:2;36514:18;;36339:371;9675:133:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9666:142;;9847:6;:13;;;-1:-1:-1;;;;;9820:40:0;:6;:20;;;9841:1;9820:23;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;9820:40:0;;;:52;;;;;9871:1;9864:4;:8;9820:52;9816:285;;;9884:208;9902:6;:18;;;9932:6;:20;;;9953:1;9932:23;;;;;;;;:::i;:::-;;;;;;;9967:6;:13;;;9992:4;10008:6;:16;;;1762:42;10052:6;:27;;;10080:1;10052:30;;;;;;;;:::i;9884:208::-;;9816:285;9653:3;;9600:507;;;;10270:5;;10203:63;10215:6;:18;;;10235:6;:13;;;10250:6;:15;;;10203:11;:63::i;:::-;:72;;10188:108;;;;-1:-1:-1;;;10188:108:0;;36917:2:21;10188:108:0;;;36899:21:21;36956:1;36936:18;;;36929:29;-1:-1:-1;;;36974:18:21;;;36967:35;37019:18;;10188:108:0;36715:328:21;10188:108:0;10303:48;10322:6;10330:9;10341;10303:18;:48::i;37011:104::-;37097:4;-1:-1:-1;;;;;37089:12:0;:4;-1:-1:-1;;;;;37089:12:0;;37081:29;;;;-1:-1:-1;;;37081:29:0;;;;;;37250:2:21;37232:21;;;37289:1;37269:18;;;37262:29;-1:-1:-1;;;37322:2:21;37307:18;;37300:34;37366:2;37351:18;;37048:327;18675:1825:0;18844:27;18877:16;18904:6;18899:1087;18916:5;:12;18912:16;;18899:1087;;;18968:6;-1:-1:-1;;;;;18956:18:0;:5;18962:1;18956:8;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;18956:8:0;:18;;;;:106;;;19061:1;18986:72;19001:11;19014:5;19020:1;19014:8;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;19024:33:0;;;;;:20;:33;;;;;;;15201:24;;;;;:11;:24;;;;;19014:8;;;;15201:29;;;;;;;:47;;;;;;;;;15061:192;18986:72;:76;18956:106;18943:1037;;;-1:-1:-1;;;;;19252:30:0;;;;;;:17;:30;;;;;;;;19283:20;:33;;;;;;19252:65;;;;;;;;19179:5;:8;;19151:72;;19270:11;;19185:1;;19179:8;;;;;;:::i;19151:72::-;19114:123;;:6;:123;:::i;:::-;19113:205;;;;:::i;:::-;19081:237;-1:-1:-1;19332:23:0;;19328:307;;19369:31;19381:19;19369:31;;:::i;:::-;;;19434:190;19454:11;19479:6;19499:5;19505:1;19499:8;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19499:8:0;19521:19;19554:8;1762:42;19594:15;19610:1;19594:18;;;;;;;;:::i;19434:190::-;19412:212;;19328:307;19690:1;19655:5;19661:1;19655:8;;;;;;;;:::i;:::-;;;;;;;;;;;19648:39;;-1:-1:-1;;;19648:39:0;;-1:-1:-1;;;;;13852:32:21;;;19648:39:0;;;13834:51:21;19655:8:0;;;;19648:26;;13807:18:21;;19648:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:43;19644:202;;;19705:130;19752:11;19785:4;19804:19;19712:5;19718:1;19712:8;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;19712:8:0;;19705:130;;:33;:130::i;:::-;-1:-1:-1;;;;;19855:29:0;;;;;;:16;:29;;;;;19885:5;:8;;19952:19;;19855:29;19885:5;19891:1;;19885:8;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;19885:8:0;;;19855:39;;;;;;;;;;;;;;;19906:33;;;;;:20;:33;;;;;;19855:94;;;;;;;;:116;18943:1037;18930:3;;18899:1087;;;;19997:6;19992:504;20009:5;:12;20005:16;;19992:504;;;20061:6;-1:-1:-1;;;;;20049:18:0;:5;20055:1;20049:8;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;20049:8:0;:18;:103;;;;-1:-1:-1;;;;;;20079:24:0;;20151:1;20079:24;;;:11;:24;;;;;20104:5;:8;;20151:1;;20104:5;20110:1;;20104:8;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;20104:8:0;;;20079:34;;;;;;;;;;;;;;;20114:33;;;;;:20;:33;;;;;;20079:69;;;;;;;;;:73;20049:103;20036:454;;;20193:17;20202:8;20193:6;:17;:::i;:::-;20171:39;;20220:122;20265:11;20296:4;20313:19;20227:5;20233:1;20227:8;;;;;;;;:::i;20220:122::-;-1:-1:-1;;;;;20352:29:0;;;;;;;:16;:29;;;;;;;;:37;;;;;;;;;;;20401:33;;;:20;:33;;;;;;20352:92;;;;;;;:114;;;20476:5;;20036:454;20023:3;;19992:504;;1352:130:13;1266:6;;-1:-1:-1;;;;;1266:6:13;719:10:3;1415:23:13;1407:68;;;;-1:-1:-1;;;1407:68:13;;37582:2:21;1407:68:13;;;37564:21:21;;;37601:18;;;37594:30;37660:34;37640:18;;;37633:62;37712:18;;1407:68:13;37380:356:21;29205:188:0;29309:21;;29290:16;:40;29282:58;;;;-1:-1:-1;;;29282:58:0;;36917:2:21;29282:58:0;;;36899:21:21;36956:1;36936:18;;;36929:29;-1:-1:-1;;;36974:18:21;;;36967:35;37019:18;;29282:58:0;36715:328:21;29282:58:0;-1:-1:-1;;;;;29346:23:0;;;;;;;:15;:23;;;;;:42;29205:188::o;2336:287:16:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:16;;37943:2:21;2460:63:16;;;37925:21:21;37982:2;37962:18;;;37955:30;38021:33;38001:18;;;37994:61;38072:18;;2460:63:16;37741:355:21;2460:63:16;1759:1;2598:7;:18;2336:287::o;14005:311:0:-;14178:133;;-1:-1:-1;;;14178:133:0;;14222:10;14178:133;;;38370:51:21;38437:18;;;38430:34;;;38507:14;;38500:22;38480:18;;;38473:50;38566:14;;38559:22;38539:18;;;38532:50;38626:14;;38619:22;38598:19;;;38591:51;38658:19;;;38651:35;;;-1:-1:-1;;;;;14178:36:0;;;;;38342:19:21;;14178:133:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14005:311;;;;;;:::o;5164:109::-;5255:4;5247;:12;;5239:29;;;;-1:-1:-1;;;5239:29:0;;;;;;38899:2:21;38881:21;;;38938:1;38918:18;;;38911:29;-1:-1:-1;;;38971:2:21;38956:18;;38949:34;39015:2;39000:18;;38697:327;4119:95:0;-1:-1:-1;;;;;4182:18:0;;4174:35;;;;-1:-1:-1;;;4174:35:0;;;;;;39231:2:21;39213:21;;;39270:1;39250:18;;;39243:29;-1:-1:-1;;;39303:2:21;39288:18;;39281:34;39347:2;39332:18;;39029:327;25465:1193:0;25662:15;;;25675:1;25662:15;;;;;;;;25610:14;;;;25662:15;25675:1;25662:15;;;;;;;;-1:-1:-1;;25700:10:0;;25683:14;;;;-1:-1:-1;25700:10:0;;;25683:14;;-1:-1:-1;25700:10:0;;25683:14;;;;:::i;:::-;;;;;;:27;;;;;;;;;;;25733:1;25716:11;25728:1;25716:14;;;;;;;;:::i;:::-;:18;;;;:14;;;;;;;;;;;:18;25846:63;;-1:-1:-1;;;25846:63:0;;25810:30;;-1:-1:-1;;;;;25846:38:0;;;;;:63;;25892:11;;25846:63;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;25846:63:0;;;;;;;;;;;;:::i;:::-;25809:100;;;25916:26;25966:15;25982:1;25966:18;;;;;;;;:::i;:::-;;;;;;;25945:15;25961:1;25945:18;;;;;;;;:::i;:::-;;;;;;;:39;;;;:::i;:::-;26137:10;;25916:68;;-1:-1:-1;26083:10:0;;26102:47;;26137:10;;26125:24;;25916:68;26102:47;:::i;:::-;26083:67;;26485:1;26462:20;:24;;;:82;;;;-1:-1:-1;26526:10:0;;26491:47;;26526:10;;26514:24;;26491:20;:47;:::i;:::-;:52;;;;26462:82;26451:121;;;26559:6;;;;:::i;:::-;;;;26451:121;26590:63;26619:4;26625:8;26635:7;26644:8;26590:28;:63::i;:::-;26578:75;25465:1193;-1:-1:-1;;;;;;;;;25465:1193:0:o;16677:210::-;16826:10;16806:31;;;;:19;:31;;;;;;;;-1:-1:-1;;;;;16806:57:0;;;;;;;;;;:66;;;;;;;;;;;;:76;;;;;;;;16799:83;16677:210::o;1526:153:14:-;1615:13;1608:20;;-1:-1:-1;;;;;;1608:20:14;;;1638:34;1663:8;1638:24;:34::i;801:229:18:-;960:58;;-1:-1:-1;;;;;42296:32:21;;960:58:18;;;42278:51:21;42345:18;;;42338:34;;;933:86:18;;953:5;;-1:-1:-1;;;983:23:18;42251:18:21;;960:58:18;;;;-1:-1:-1;;960:58:18;;;;;;;;;;;;;;-1:-1:-1;;;;;960:58:18;-1:-1:-1;;;;;;960:58:18;;;;;;;;;;933:19;:86::i;240:90:15:-;307:11;;-1:-1:-1;;;;;307:11:15;293:10;:25;285:40;;;;-1:-1:-1;;;285:40:15;;;;;;;:::i;30972:132:0:-;31073:5;;31059:40;;-1:-1:-1;;;31059:40:0;;-1:-1:-1;;;;;13852:32:21;;;31059:40:0;;;13834:51:21;31037:7:0;;31073:5;;31059:35;;13807:18:21;;31059:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31052:47;30972:132;-1:-1:-1;;30972:132:0:o;17187:168:17:-;17243:7;17279:1;17270:5;:10;;17262:55;;;;-1:-1:-1;;;17262:55:17;;42585:2:21;17262:55:17;;;42567:21:21;;;42604:18;;;42597:30;42663:34;42643:18;;;42636:62;42715:18;;17262:55:17;42383:356:21;17262:55:17;-1:-1:-1;17342:5:17;17187:168::o;32386:1194:0:-;32532:17;;-1:-1:-1;;;;;32583:18:0;;1762:42;32583:18;;:41;;-1:-1:-1;;;;;;32605:19:0;;1762:42;32605:19;32583:41;32579:997;;;32646:58;32664:8;32682:9;32694;32646:17;:58::i;:::-;32634:70;;32579:997;;;-1:-1:-1;;;;;32740:32:0;;;;;;;:22;:32;;;;;;;;;32728:44;;:99;;-1:-1:-1;;;;;;32795:32:0;;;;;;;:22;:32;;;;;;32782:45;;;32795:32;;32782:45;32728:99;32717:859;;;-1:-1:-1;;;;;32873:32:0;;;;;;;:22;:32;;;;;;32852:54;;32863:8;;32873:32;32852:10;:54::i;:::-;32842:64;-1:-1:-1;;;;;;32918:22:0;;;32914:65;;-1:-1:-1;32962:8:0;32914:65;-1:-1:-1;;;;;33060:32:0;;;;;;;:22;:32;;;;;;32998:119;;33023:8;;33041:9;;33060:32;33102:7;32998:15;:119::i;32717:859::-;-1:-1:-1;;;;;33169:32:0;;;;;;;:22;:32;;;;;;33148:54;;33159:8;;33169:32;33148:10;:54::i;:::-;-1:-1:-1;;;;;33253:32:0;;;33210:18;33253:32;;;:22;:32;;;;;;33138:64;;-1:-1:-1;33210:18:0;33231:55;;33242:9;;33253:32;33231:10;:55::i;:::-;-1:-1:-1;;;;;33369:32:0;;;;;;;:22;:32;;;;;;33210:76;;-1:-1:-1;33307:119:0;;33332:8;;33350:9;;33369:32;33411:7;33307:15;:119::i;:::-;-1:-1:-1;;;;;33471:32:0;;;;;;;:22;:32;;;;;;33295:131;;-1:-1:-1;33446:123:0;;33471:32;33295:131;33532:9;33551:10;33446:15;:123::i;:::-;33434:135;;33130:446;32717:859;32551:1029;32386:1194;;;;;;:::o;34442:390::-;34614:59;;-1:-1:-1;;;34614:59:0;;-1:-1:-1;;;;;13852:32:21;;;34614:59:0;;;13834:51:21;34567:20:0;;;;34614:46;;;;;13807:18:21;;34614:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34595:78;;34697:1;34683:11;:15;34679:149;;;34808:11;;34788:15;34802:1;34788:11;:15;:::i;:::-;34787:33;;;;:::i;:::-;34764:9;;34750:11;;:23;;;;:::i;:::-;34735:39;;:11;:39;:::i;:::-;34734:87;;;;:::i;34679:149::-;34589:243;34442:390;;;;;:::o;20504:284::-;20708:75;;-1:-1:-1;;;20708:75:0;;-1:-1:-1;;;;;43049:32:21;;;20708:75:0;;;43031:51:21;43118:32;;;43098:18;;;43091:60;43167:18;;;43160:34;;;43210:18;;;43203:34;;;43274:32;;;43253:19;;;43246:61;43323:19;;;43316:35;;;20686:7:0;;20708:22;;;;;;43003:19:21;;20708:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20701:82;20504:284;-1:-1:-1;;;;;;;;20504:284:0:o;11982:514::-;12097:14;12123:12;;12119:373;;12146:13;12161:15;12180:27;12195:11;12180:14;:27::i;:::-;12145:62;;;;12215:18;12248:11;-1:-1:-1;;;;;12241:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12236:35;;:2;:35;:::i;:::-;12215:56;;;-1:-1:-1;12337:7:0;12312:19;12215:56;12312:2;:19;:::i;:::-;12290:18;12303:5;12291:8;12290:18;:::i;:::-;:42;;;;:::i;:::-;12289:56;;;;:::i;:::-;-1:-1:-1;;;;;12421:38:0;;;;;;;:25;:38;;;;;;12279:67;;-1:-1:-1;12354:131:0;;:36;;;;12400:11;;12421:38;12469:8;12354:36;:131::i;:::-;12137:355;;;12119:373;11982:514;;;;;:::o;10360:1179::-;10563:27;;;;;10706:5;;10736:18;;10692:63;;-1:-1:-1;;;10692:63:0;;-1:-1:-1;;;;;13852:32:21;;;10692:63:0;;;13834:51:21;10502:19:0;;10706:5;;;;10692:43;;13807:18:21;;10692:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10759:1;10692:68;10681:279;;-1:-1:-1;10794:27:0;;;;10842:1;;-1:-1:-1;10842:1:0;10851:103;10872:16;:23;10868:1;:27;10851:103;;;10926:16;10943:1;10926:19;;;;;;;;:::i;:::-;;;;;;;10912:33;;;;;:::i;:::-;;-1:-1:-1;10897:3:0;;10851:103;;;;10681:279;10987:13;;;;11012:18;;10980:51;;-1:-1:-1;;;10980:51:0;;-1:-1:-1;;;;;13852:32:21;;;10980:51:0;;;13834::21;10980:31:0;;;;;13807:18:21;;10980:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10966:65;;11042:6;11037:498;11058:9;:17;;;:24;11054:1;:28;11037:498;;;11168:1;11145:16;11162:1;11145:19;;;;;;;;:::i;:::-;;;;;;;:24;;:43;;;;;11187:1;11173:11;:15;11145:43;11141:388;;;11200:320;11218:6;:18;;;11248:6;:13;;;11273:9;:17;;;11291:1;11273:20;;;;;;;;:::i;:::-;;;;;;;11343:10;11320:16;11337:1;11320:19;;;;;;;;:::i;:::-;;;;;;;11306:11;:33;;;;:::i;:::-;11305:48;;;;:::i;:::-;11365:6;:16;;;11401:1;11481:6;:26;;;11508:1;11481:29;;;;;;;;:::i;11200:320::-;;11141:388;11084:3;;11037:498;;1040:269:18;1229:68;;-1:-1:-1;;;;;29912:32:21;;;1229:68:18;;;29894:51:21;29981:32;;29961:18;;;29954:60;30030:18;;;30023:34;;;1202:96:18;;1222:5;;-1:-1:-1;;;1252:27:18;29867:18:21;;1229:68:18;29692:371:21;628:859:12;766:19;793:20;816:33;844:4;816:27;:33::i;:::-;793:56;-1:-1:-1;;;;;;;;;;;960:33:12;;;956:527;;1003:17;1023:36;-1:-1:-1;;;;;1023:36:12;;;;:::i;:::-;1003:56;;1093:10;-1:-1:-1;;;;;1081:22:12;:9;-1:-1:-1;;;;;1081:22:12;;:140;;1173:48;-1:-1:-1;;;1199:10:12;-1:-1:-1;;;;;1173:48:12;1211:9;1173:15;:48::i;:::-;1081:140;;;1114:48;1130:9;1141:10;-1:-1:-1;;;;;1114:48:12;-1:-1:-1;;;1114:15:12;:48::i;:::-;1067:154;;995:233;956:527;;;1242:17;1262:52;-1:-1:-1;;;;;1262:52:12;;;1306:7;1262:15;:52::i;:::-;1242:72;;1348:10;-1:-1:-1;;;;;1336:22:12;:9;-1:-1:-1;;;;;1336:22:12;;:140;;1428:48;-1:-1:-1;;;1454:10:12;-1:-1:-1;;;;;1428:48:12;1466:9;1428:15;:48::i;:::-;1336:140;;;1369:48;1385:9;1396:10;-1:-1:-1;;;;;1369:48:12;-1:-1:-1;;;1369:15:12;:48::i;2426:187:13:-;2518:6;;;-1:-1:-1;;;;;2534:17:13;;;-1:-1:-1;;;;;;2534:17:13;;;;;;;2566:40;;2518:6;;;2534:17;2518:6;;2566:40;;2499:16;;2566:40;2489:124;2426:187;:::o;4082:742:18:-;4517:23;4543:69;4571:4;4543:69;;;;;;;;;;;;;;;;;4551:5;-1:-1:-1;;;;;4543:27:18;;;:69;;;;;:::i;:::-;4630:17;;4517:95;;-1:-1:-1;4630:21:18;4626:188;;4733:10;4722:30;;;;;;;;;;;;:::i;:::-;4714:85;;;;-1:-1:-1;;;4714:85:18;;43564:2:21;4714:85:18;;;43546:21:21;43603:2;43583:18;;;43576:30;43642:34;43622:18;;;43615:62;-1:-1:-1;;;43693:18:21;;;43686:40;43743:19;;4714:85:18;43362:406:21;32236:146:0;32347:5;;32333:44;;-1:-1:-1;;;32333:44:0;;-1:-1:-1;;;;;17744:32:21;;;32333:44:0;;;17726:51:21;17813:32;;;17793:18;;;17786:60;32311:7:0;;32347:5;;32333:28;;17699:18:21;;32333:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;33584:251::-;33713:7;33728:18;33749:58;33770:5;33785:3;33791:6;33799:7;33749:20;:58::i;:::-;33728:79;33584:251;-1:-1:-1;;;;;;33584:251:0:o;1385:2759:19:-;1448:20;1504:15;1529:1;1522:4;:8;;;:57;;1573:4;1566:12;;1522:57;;;1549:4;1542:12;;1541:13;;1522:57;1504:75;-1:-1:-1;667:9:19;1597:35;;1593:51;;;1641:3;;-1:-1:-1;;;1641:3:19;;;;;;;;;;;1593:51;1659:13;1675:7;1685:3;1675:13;1692:1;1675:18;:125;;-1:-1:-1;;;1675:125:19;;;1712:34;1675:125;1659:141;;;-1:-1:-1;1828:3:19;1818:13;;:18;1814:83;;1855:34;1847:42;1894:3;1846:51;1814:83;1925:3;1915:13;;:18;1911:83;;1952:34;1944:42;1991:3;1943:51;1911:83;2022:3;2012:13;;:18;2008:83;;2049:34;2041:42;2088:3;2040:51;2008:83;2119:4;2109:14;;:19;2105:84;;2147:34;2139:42;2186:3;2138:51;2105:84;2217:4;2207:14;;:19;2203:84;;2245:34;2237:42;2284:3;2236:51;2203:84;2315:4;2305:14;;:19;2301:84;;2343:34;2335:42;2382:3;2334:51;2301:84;2413:4;2403:14;;:19;2399:84;;2441:34;2433:42;2480:3;2432:51;2399:84;2511:5;2501:15;;:20;2497:85;;2540:34;2532:42;2579:3;2531:51;2497:85;2610:5;2600:15;;:20;2596:85;;2639:34;2631:42;2678:3;2630:51;2596:85;2709:5;2699:15;;:20;2695:85;;2738:34;2730:42;2777:3;2729:51;2695:85;2808:5;2798:15;;:20;2794:85;;2837:34;2829:42;2876:3;2828:51;2794:85;2907:6;2897:16;;:21;2893:86;;2937:34;2929:42;2976:3;2928:51;2893:86;3007:6;2997:16;;:21;2993:86;;3037:34;3029:42;3076:3;3028:51;2993:86;3107:6;3097:16;;:21;3093:86;;3137:34;3129:42;3176:3;3128:51;3093:86;3207:6;3197:16;;:21;3193:86;;3237:34;3229:42;3276:3;3228:51;3193:86;3307:7;3297:17;;:22;3293:86;;3338:33;3330:41;3376:3;3329:50;3293:86;3407:7;3397:17;;:22;3393:85;;3438:32;3430:40;3475:3;3429:49;3393:85;3506:7;3496:17;;:22;3492:83;;3537:30;3529:38;3572:3;3528:47;3492:83;3603:7;3593:17;;:22;3589:78;;3634:25;3626:33;3664:3;3625:42;3589:78;3693:1;3686:4;:8;;;3682:47;;;3724:5;-1:-1:-1;;3704:25:19;;;;;:::i;:::-;;3696:33;;3682:47;4104:7;4095:5;:17;:22;:30;;4124:1;4095:30;;;4120:1;4095:30;4078:48;;4088:2;4079:5;:11;;4078:48;4055:72;;1480:2658;;1385:2759;;;:::o;741:4127:4:-;853:14;;;-1:-1:-1;;1416:1:4;1413;1406:20;1459:1;1456;1452:9;1443:18;;1514:5;1510:2;1507:13;1499:5;1495:2;1491:14;1487:34;1478:43;;;1615:5;1624:1;1615:10;1611:203;;1667:1;1653:11;:15;1645:24;;;;;;-1:-1:-1;1728:23:4;;;;-1:-1:-1;1786:13:4;;1611:203;1953:5;1939:11;:19;1931:28;;;;;;2260:17;2344:11;2341:1;2338;2331:25;2736:12;2752:15;;;2751:31;;2888:22;;;;;3763:1;3744;:15;;3743:21;;4006:17;;;4002:21;;3995:28;4068:17;;;4064:21;;4057:28;4131:17;;;4127:21;;4120:28;4194:17;;;4190:21;;4183:28;4257:17;;;4253:21;;4246:28;4321:17;;;4317:21;;;4310:28;3300:12;;;;3296:23;;;3321:1;3292:31;2489:20;;;2478:32;;;3359:12;;;;2536:21;;;;3032:16;;;;3350:21;;;;4813:11;;;;;-1:-1:-1;;741:4127:4;;;;;:::o;3873:223:1:-;4006:12;4037:52;4059:6;4067:4;4073:1;4076:12;4006;5241;5255:23;5282:6;-1:-1:-1;;;;;5282:11:1;5301:5;5308:4;5282:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5240:73;;;;5330:69;5357:6;5365:7;5374:10;5386:12;7646;7674:7;7670:418;;;7701:10;:17;7722:1;7701:22;7697:286;;-1:-1:-1;;;;;1465:19:1;;;7908:60;;;;-1:-1:-1;;;7908:60:1;;44688:2:21;7908:60:1;;;44670:21:21;44727:2;44707:18;;;44700:30;44766:31;44746:18;;;44739:59;44815:18;;7908:60:1;44486:353:21;7908:60:1;-1:-1:-1;8003:10:1;7996:17;;7670:418;8044:33;8052:10;8064:12;8775:17;;:21;8771:379;;9003:10;8997:17;9059:15;9046:10;9042:2;9038:19;9031:44;8771:379;9126:12;9119:20;;-1:-1:-1;;;9119:20:1;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:127:21;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:255;218:2;212:9;260:6;248:19;;-1:-1:-1;;;;;282:34:21;;318:22;;;279:62;276:88;;;344:18;;:::i;:::-;380:2;373:22;146:255;:::o;406:275::-;477:2;471:9;542:2;523:13;;-1:-1:-1;;519:27:21;507:40;;-1:-1:-1;;;;;562:34:21;;598:22;;;559:62;556:88;;;624:18;;:::i;:::-;660:2;653:22;406:275;;-1:-1:-1;406:275:21:o;686:131::-;-1:-1:-1;;;;;761:31:21;;751:42;;741:70;;807:1;804;797:12;822:134;890:20;;919:31;890:20;919:31;:::i;:::-;822:134;;;:::o;961:183::-;1021:4;-1:-1:-1;;;;;1046:6:21;1043:30;1040:56;;;1076:18;;:::i;:::-;-1:-1:-1;1121:1:21;1117:14;1133:4;1113:25;;961:183::o;1149:744::-;1203:5;1256:3;1249:4;1241:6;1237:17;1233:27;1223:55;;1274:1;1271;1264:12;1223:55;1314:6;1301:20;1341:64;1357:47;1397:6;1357:47;:::i;:::-;1341:64;:::i;:::-;1429:3;1453:6;1448:3;1441:19;1485:4;1480:3;1476:14;1469:21;;1546:4;1536:6;1533:1;1529:14;1521:6;1517:27;1513:38;1499:52;;1574:3;1566:6;1563:15;1560:35;;;1591:1;1588;1581:12;1560:35;1627:4;1619:6;1615:17;1641:221;1657:6;1652:3;1649:15;1641:221;;;1739:3;1726:17;1756:31;1781:5;1756:31;:::i;:::-;1800:18;;1847:4;1838:14;;;;1674;1641:221;;;-1:-1:-1;1880:7:21;1149:744;-1:-1:-1;;;;;1149:744:21:o;1898:723::-;1952:5;2005:3;1998:4;1990:6;1986:17;1982:27;1972:55;;2023:1;2020;2013:12;1972:55;2063:6;2050:20;2090:64;2106:47;2146:6;2106:47;:::i;2090:64::-;2178:3;2202:6;2197:3;2190:19;2234:4;2229:3;2225:14;2218:21;;2295:4;2285:6;2282:1;2278:14;2270:6;2266:27;2262:38;2248:52;;2323:3;2315:6;2312:15;2309:35;;;2340:1;2337;2330:12;2309:35;2376:4;2368:6;2364:17;2390:200;2406:6;2401:3;2398:15;2390:200;;;2498:17;;2528:18;;2575:4;2566:14;;;;2423;2390:200;;2626:2500;2717:6;2770:2;2758:9;2749:7;2745:23;2741:32;2738:52;;;2786:1;2783;2776:12;2738:52;2826:9;2813:23;-1:-1:-1;;;;;2851:6:21;2848:30;2845:50;;;2891:1;2888;2881:12;2845:50;2914:22;;2970:6;2952:16;;;2948:29;2945:49;;;2990:1;2987;2980:12;2945:49;3016:22;;:::i;:::-;3061;3080:2;3061:22;:::i;:::-;3054:5;3047:37;3116:31;3143:2;3139;3135:11;3116:31;:::i;:::-;3111:2;3100:14;;3093:55;3214:2;3206:11;;;3193:25;3234:14;;;3227:31;3324:2;3316:11;;;3303:25;3344:14;;;3337:31;3414:3;3406:12;;3393:26;-1:-1:-1;;;;;3431:32:21;;3428:52;;;3476:1;3473;3466:12;3428:52;3513:56;3561:7;3550:8;3546:2;3542:17;3513:56;:::i;:::-;3507:3;3500:5;3496:15;3489:81;;3616:3;3612:2;3608:12;3595:26;-1:-1:-1;;;;;3636:8:21;3633:32;3630:52;;;3678:1;3675;3668:12;3630:52;3715:56;3763:7;3752:8;3748:2;3744:17;3715:56;:::i;:::-;3709:3;3702:5;3698:15;3691:81;;3818:3;3814:2;3810:12;3797:26;-1:-1:-1;;;;;3838:8:21;3835:32;3832:52;;;3880:1;3877;3870:12;3832:52;3917:56;3965:7;3954:8;3950:2;3946:17;3917:56;:::i;:::-;3911:3;3904:5;3900:15;3893:81;;4020:3;4016:2;4012:12;3999:26;-1:-1:-1;;;;;4040:8:21;4037:32;4034:52;;;4082:1;4079;4072:12;4034:52;4119:56;4167:7;4156:8;4152:2;4148:17;4119:56;:::i;:::-;4113:3;4106:5;4102:15;4095:81;;4222:3;4218:2;4214:12;4201:26;-1:-1:-1;;;;;4242:8:21;4239:32;4236:52;;;4284:1;4281;4274:12;4236:52;4321:56;4369:7;4358:8;4354:2;4350:17;4321:56;:::i;:::-;4315:3;4304:15;;4297:81;-1:-1:-1;4444:3:21;4436:12;;;4423:26;4465:15;;;4458:32;4536:3;4528:12;;4515:26;-1:-1:-1;;;;;4553:32:21;;4550:52;;;4598:1;4595;4588:12;4550:52;4635:56;4683:7;4672:8;4668:2;4664:17;4635:56;:::i;:::-;4629:3;4622:5;4618:15;4611:81;;4738:3;4734:2;4730:12;4717:26;-1:-1:-1;;;;;4758:8:21;4755:32;4752:52;;;4800:1;4797;4790:12;4752:52;4837:56;4885:7;4874:8;4870:2;4866:17;4837:56;:::i;:::-;4831:3;4824:5;4820:15;4813:81;;4940:3;4936:2;4932:12;4919:26;-1:-1:-1;;;;;4960:8:21;4957:32;4954:52;;;5002:1;4999;4992:12;4954:52;5039:56;5087:7;5076:8;5072:2;5068:17;5039:56;:::i;:::-;5033:3;5022:15;;5015:81;-1:-1:-1;5026:5:21;2626:2500;-1:-1:-1;;;;2626:2500:21:o;5131:118::-;5217:5;5210:13;5203:21;5196:5;5193:32;5183:60;;5239:1;5236;5229:12;5254:1124;5405:6;5413;5421;5429;5437;5445;5498:3;5486:9;5477:7;5473:23;5469:33;5466:53;;;5515:1;5512;5505:12;5466:53;5554:9;5541:23;5573:31;5598:5;5573:31;:::i;:::-;5623:5;-1:-1:-1;5680:2:21;5665:18;;5652:32;5693:33;5652:32;5693:33;:::i;:::-;5745:7;-1:-1:-1;5825:2:21;5810:18;;5797:32;;-1:-1:-1;5906:2:21;5891:18;;5878:32;-1:-1:-1;;;;;5922:30:21;;5919:50;;;5965:1;5962;5955:12;5919:50;5988:61;6041:7;6032:6;6021:9;6017:22;5988:61;:::i;:::-;5978:71;;;6102:3;6091:9;6087:19;6074:33;-1:-1:-1;;;;;6122:8:21;6119:32;6116:52;;;6164:1;6161;6154:12;6116:52;6187:63;6242:7;6231:8;6220:9;6216:24;6187:63;:::i;:::-;6177:73;;;6302:3;6291:9;6287:19;6274:33;6316:30;6338:7;6316:30;:::i;:::-;6365:7;6355:17;;;5254:1124;;;;;;;;:::o;6383:1472::-;6534:6;6542;6550;6603:2;6591:9;6582:7;6578:23;6574:32;6571:52;;;6619:1;6616;6609:12;6571:52;6659:9;6646:23;-1:-1:-1;;;;;6684:6:21;6681:30;6678:50;;;6724:1;6721;6714:12;6678:50;6747:61;6800:7;6791:6;6780:9;6776:22;6747:61;:::i;:::-;6737:71;;;6861:2;6850:9;6846:18;6833:32;-1:-1:-1;;;;;6880:8:21;6877:32;6874:52;;;6922:1;6919;6912:12;6874:52;6945:63;7000:7;6989:8;6978:9;6974:24;6945:63;:::i;:::-;6935:73;;;7061:2;7050:9;7046:18;7033:32;-1:-1:-1;;;;;7080:8:21;7077:32;7074:52;;;7122:1;7119;7112:12;7074:52;7145:24;;7200:4;7192:13;;7188:27;-1:-1:-1;7178:55:21;;7229:1;7226;7219:12;7178:55;7269:2;7256:16;7292:64;7308:47;7348:6;7308:47;:::i;7292:64::-;7378:3;7402:6;7397:3;7390:19;7434:2;7429:3;7425:12;7418:19;;7489:2;7479:6;7476:1;7472:14;7468:2;7464:23;7460:32;7446:46;;7515:7;7507:6;7504:19;7501:39;;;7536:1;7533;7526:12;7501:39;7568:2;7564;7560:11;7549:22;;7580:245;7596:6;7591:3;7588:15;7580:245;;;7676:3;7663:17;7724:8;7717:5;7713:20;7706:5;7703:31;7693:59;;7748:1;7745;7738:12;7693:59;7765:18;;7812:2;7613:12;;;;7803;;;;7580:245;;;7844:5;7834:15;;;;;;6383:1472;;;;;:::o;7860:590::-;7978:6;7986;8039:2;8027:9;8018:7;8014:23;8010:32;8007:52;;;8055:1;8052;8045:12;8007:52;8095:9;8082:23;-1:-1:-1;;;;;8120:6:21;8117:30;8114:50;;;8160:1;8157;8150:12;8114:50;8183:61;8236:7;8227:6;8216:9;8212:22;8183:61;:::i;:::-;8173:71;;;8297:2;8286:9;8282:18;8269:32;-1:-1:-1;;;;;8316:8:21;8313:32;8310:52;;;8358:1;8355;8348:12;8310:52;8381:63;8436:7;8425:8;8414:9;8410:24;8381:63;:::i;:::-;8371:73;;;7860:590;;;;;:::o;8455:367::-;8523:6;8531;8584:2;8572:9;8563:7;8559:23;8555:32;8552:52;;;8600:1;8597;8590:12;8552:52;8639:9;8626:23;8658:31;8683:5;8658:31;:::i;:::-;8708:5;8786:2;8771:18;;;;8758:32;;-1:-1:-1;;;8455:367:21:o;9009:247::-;9068:6;9121:2;9109:9;9100:7;9096:23;9092:32;9089:52;;;9137:1;9134;9127:12;9089:52;9176:9;9163:23;9195:31;9220:5;9195:31;:::i;9261:226::-;9320:6;9373:2;9361:9;9352:7;9348:23;9344:32;9341:52;;;9389:1;9386;9379:12;9341:52;-1:-1:-1;9434:23:21;;9261:226;-1:-1:-1;9261:226:21:o;9492:508::-;9569:6;9577;9585;9638:2;9626:9;9617:7;9613:23;9609:32;9606:52;;;9654:1;9651;9644:12;9606:52;9693:9;9680:23;9712:31;9737:5;9712:31;:::i;:::-;9762:5;-1:-1:-1;9840:2:21;9825:18;;9812:32;;-1:-1:-1;9922:2:21;9907:18;;9894:32;9935:33;9894:32;9935:33;:::i;:::-;9987:7;9977:17;;;9492:508;;;;;:::o;10005:529::-;10082:6;10090;10098;10151:2;10139:9;10130:7;10126:23;10122:32;10119:52;;;10167:1;10164;10157:12;10119:52;10206:9;10193:23;10225:31;10250:5;10225:31;:::i;:::-;10275:5;-1:-1:-1;10332:2:21;10317:18;;10304:32;10345:33;10304:32;10345:33;:::i;:::-;10397:7;-1:-1:-1;10456:2:21;10441:18;;10428:32;10469:33;10428:32;10469:33;:::i;10539:388::-;10607:6;10615;10668:2;10656:9;10647:7;10643:23;10639:32;10636:52;;;10684:1;10681;10674:12;10636:52;10723:9;10710:23;10742:31;10767:5;10742:31;:::i;:::-;10792:5;-1:-1:-1;10849:2:21;10834:18;;10821:32;10862:33;10821:32;10862:33;:::i;:::-;10914:7;10904:17;;;10539:388;;;;;:::o;11385:415::-;11452:6;11460;11513:2;11501:9;11492:7;11488:23;11484:32;11481:52;;;11529:1;11526;11519:12;11481:52;11568:9;11555:23;11587:31;11612:5;11587:31;:::i;:::-;11637:5;-1:-1:-1;11694:2:21;11679:18;;11666:32;11742:6;11729:20;;11717:33;;11707:61;;11764:1;11761;11754:12;12227:188;12295:20;;-1:-1:-1;;;;;12344:46:21;;12334:57;;12324:85;;12405:1;12402;12395:12;12420:462;12497:6;12505;12513;12566:2;12554:9;12545:7;12541:23;12537:32;12534:52;;;12582:1;12579;12572:12;12534:52;12621:9;12608:23;12640:31;12665:5;12640:31;:::i;:::-;12690:5;-1:-1:-1;12714:38:21;12748:2;12733:18;;12714:38;:::i;13079:604::-;13165:6;13173;13181;13189;13242:3;13230:9;13221:7;13217:23;13213:33;13210:53;;;13259:1;13256;13249:12;13210:53;13298:9;13285:23;13317:31;13342:5;13317:31;:::i;:::-;13367:5;-1:-1:-1;13391:38:21;13425:2;13410:18;;13391:38;:::i;:::-;13381:48;;13481:2;13470:9;13466:18;13453:32;13494:33;13519:7;13494:33;:::i;:::-;13546:7;-1:-1:-1;13605:2:21;13590:18;;13577:32;13618:33;13577:32;13618:33;:::i;:::-;13079:604;;;;-1:-1:-1;13079:604:21;;-1:-1:-1;;13079:604:21:o;13896:650::-;13982:6;13990;13998;14006;14059:3;14047:9;14038:7;14034:23;14030:33;14027:53;;;14076:1;14073;14066:12;14027:53;14115:9;14102:23;14134:31;14159:5;14134:31;:::i;:::-;14184:5;-1:-1:-1;14241:2:21;14226:18;;14213:32;14254:33;14213:32;14254:33;:::i;:::-;14306:7;-1:-1:-1;14365:2:21;14350:18;;14337:32;14378:33;14337:32;14378:33;:::i;:::-;13896:650;;;;-1:-1:-1;14430:7:21;;14510:2;14495:18;14482:32;;-1:-1:-1;;13896:650:21:o;14551:590::-;14669:6;14677;14730:2;14718:9;14709:7;14705:23;14701:32;14698:52;;;14746:1;14743;14736:12;14698:52;14786:9;14773:23;-1:-1:-1;;;;;14811:6:21;14808:30;14805:50;;;14851:1;14848;14841:12;14805:50;14874:61;14927:7;14918:6;14907:9;14903:22;14874:61;:::i;:::-;14864:71;;;14988:2;14977:9;14973:18;14960:32;-1:-1:-1;;;;;15007:8:21;15004:32;15001:52;;;15049:1;15046;15039:12;15001:52;15072:63;15127:7;15116:8;15105:9;15101:24;15072:63;:::i;15399:508::-;15476:6;15484;15492;15545:2;15533:9;15524:7;15520:23;15516:32;15513:52;;;15561:1;15558;15551:12;15513:52;15600:9;15587:23;15619:31;15644:5;15619:31;:::i;:::-;15669:5;-1:-1:-1;15726:2:21;15711:18;;15698:32;15739:33;15698:32;15739:33;:::i;:::-;15399:508;;15791:7;;-1:-1:-1;;;15871:2:21;15856:18;;;;15843:32;;15399:508::o;15912:616::-;16027:6;16035;16043;16096:2;16084:9;16075:7;16071:23;16067:32;16064:52;;;16112:1;16109;16102:12;16064:52;16151:9;16138:23;16170:31;16195:5;16170:31;:::i;:::-;16220:5;-1:-1:-1;16276:2:21;16261:18;;16248:32;-1:-1:-1;;;;;16292:30:21;;16289:50;;;16335:1;16332;16325:12;16289:50;16358:61;16411:7;16402:6;16391:9;16387:22;16358:61;:::i;:::-;15912:616;;16348:71;;-1:-1:-1;;;;16492:2:21;16477:18;;;;16464:32;;15912:616::o;16533:276::-;16591:6;16644:2;16632:9;16623:7;16619:23;16615:32;16612:52;;;16660:1;16657;16650:12;16612:52;16699:9;16686:23;16749:10;16742:5;16738:22;16731:5;16728:33;16718:61;;16775:1;16772;16765:12;16814:382;16879:6;16887;16940:2;16928:9;16919:7;16915:23;16911:32;16908:52;;;16956:1;16953;16946:12;16908:52;16995:9;16982:23;17014:31;17039:5;17014:31;:::i;:::-;17064:5;-1:-1:-1;17121:2:21;17106:18;;17093:32;17134:30;17093:32;17134:30;:::i;17201:346::-;17269:6;17277;17330:2;17318:9;17309:7;17305:23;17301:32;17298:52;;;17346:1;17343;17336:12;17298:52;-1:-1:-1;;17391:23:21;;;17511:2;17496:18;;;17483:32;;-1:-1:-1;17201:346:21:o;17857:624::-;17959:6;17967;17975;18028:2;18016:9;18007:7;18003:23;17999:32;17996:52;;;18044:1;18041;18034:12;17996:52;18083:9;18070:23;18102:31;18127:5;18102:31;:::i;:::-;18152:5;-1:-1:-1;18209:2:21;18194:18;;18181:32;18222:33;18181:32;18222:33;:::i;:::-;18274:7;-1:-1:-1;18332:2:21;18317:18;;18304:32;-1:-1:-1;;;;;18348:30:21;;18345:50;;;18391:1;18388;18381:12;18345:50;18414:61;18467:7;18458:6;18447:9;18443:22;18414:61;:::i;:::-;18404:71;;;17857:624;;;;;:::o;18486:325::-;18688:2;18670:21;;;18727:1;18707:18;;;18700:29;-1:-1:-1;;;18760:2:21;18745:18;;18738:32;18802:2;18787:18;;18486:325::o;18816:127::-;18877:10;18872:3;18868:20;18865:1;18858:31;18908:4;18905:1;18898:15;18932:4;18929:1;18922:15;18948:128;19015:9;;;19036:11;;;19033:37;;;19050:18;;:::i;19433:373::-;19506:6;19514;19567:2;19555:9;19546:7;19542:23;19538:32;19535:52;;;19583:1;19580;19573:12;19535:52;19615:9;19609:16;19634:28;19656:5;19634:28;:::i;:::-;19731:2;19716:18;;19710:25;19681:5;;-1:-1:-1;19744:30:21;19710:25;19744:30;:::i;19811:741::-;19876:5;19929:3;19922:4;19914:6;19910:17;19906:27;19896:55;;19947:1;19944;19937:12;19896:55;19980:6;19974:13;20007:64;20023:47;20063:6;20023:47;:::i;20007:64::-;20095:3;20119:6;20114:3;20107:19;20151:4;20146:3;20142:14;20135:21;;20212:4;20202:6;20199:1;20195:14;20187:6;20183:27;20179:38;20165:52;;20240:3;20232:6;20229:15;20226:35;;;20257:1;20254;20247:12;20226:35;20293:4;20285:6;20281:17;20307:214;20323:6;20318:3;20315:15;20307:214;;;20398:3;20392:10;20415:31;20440:5;20415:31;:::i;:::-;20459:18;;20506:4;20497:14;;;;20340;20307:214;;20557:609;20686:6;20694;20747:2;20735:9;20726:7;20722:23;20718:32;20715:52;;;20763:1;20760;20753:12;20715:52;20796:9;20790:16;-1:-1:-1;;;;;20821:6:21;20818:30;20815:50;;;20861:1;20858;20851:12;20815:50;20884:72;20948:7;20939:6;20928:9;20924:22;20884:72;:::i;:::-;20874:82;;;21002:2;20991:9;20987:18;20981:25;-1:-1:-1;;;;;21021:8:21;21018:32;21015:52;;;21063:1;21060;21053:12;21015:52;21086:74;21152:7;21141:8;21130:9;21126:24;21086:74;:::i;21171:230::-;21241:6;21294:2;21282:9;21273:7;21269:23;21265:32;21262:52;;;21310:1;21307;21300:12;21262:52;-1:-1:-1;21355:16:21;;21171:230;-1:-1:-1;21171:230:21:o;21406:363::-;21501:6;21554:2;21542:9;21533:7;21529:23;21525:32;21522:52;;;21570:1;21567;21560:12;21522:52;21603:9;21597:16;-1:-1:-1;;;;;21628:6:21;21625:30;21622:50;;;21668:1;21665;21658:12;21622:50;21691:72;21755:7;21746:6;21735:9;21731:22;21691:72;:::i;22125:446::-;22178:3;22216:5;22210:12;22243:6;22238:3;22231:19;22275:4;22270:3;22266:14;22259:21;;22314:4;22307:5;22303:16;22337:1;22347:199;22361:6;22358:1;22355:13;22347:199;;;22426:13;;-1:-1:-1;;;;;22422:39:21;22410:52;;22491:4;22482:14;;;;22519:17;;;;22458:1;22376:9;22347:199;;;-1:-1:-1;22562:3:21;;22125:446;-1:-1:-1;;;;22125:446:21:o;22576:261::-;22755:2;22744:9;22737:21;22718:4;22775:56;22827:2;22816:9;22812:18;22804:6;22775:56;:::i;22842:720::-;22907:5;22960:3;22953:4;22945:6;22941:17;22937:27;22927:55;;22978:1;22975;22968:12;22927:55;23011:6;23005:13;23038:64;23054:47;23094:6;23054:47;:::i;23038:64::-;23126:3;23150:6;23145:3;23138:19;23182:4;23177:3;23173:14;23166:21;;23243:4;23233:6;23230:1;23226:14;23218:6;23214:27;23210:38;23196:52;;23271:3;23263:6;23260:15;23257:35;;;23288:1;23285;23278:12;23257:35;23324:4;23316:6;23312:17;23338:193;23354:6;23349:3;23346:15;23338:193;;;23446:10;;23469:18;;23516:4;23507:14;;;;23371;23338:193;;23567:609;23696:6;23704;23757:2;23745:9;23736:7;23732:23;23728:32;23725:52;;;23773:1;23770;23763:12;23725:52;23806:9;23800:16;-1:-1:-1;;;;;23831:6:21;23828:30;23825:50;;;23871:1;23868;23861:12;23825:50;23894:72;23958:7;23949:6;23938:9;23934:22;23894:72;:::i;:::-;23884:82;;;24012:2;24001:9;23997:18;23991:25;-1:-1:-1;;;;;24031:8:21;24028:32;24025:52;;;24073:1;24070;24063:12;24025:52;24096:74;24162:7;24151:8;24140:9;24136:24;24096:74;:::i;24181:420::-;24234:3;24272:5;24266:12;24299:6;24294:3;24287:19;24331:4;24326:3;24322:14;24315:21;;24370:4;24363:5;24359:16;24393:1;24403:173;24417:6;24414:1;24411:13;24403:173;;;24478:13;;24466:26;;24521:4;24512:14;;;;24549:17;;;;24439:1;24432:9;24403:173;;24606:562;-1:-1:-1;;;;;24891:32:21;;24873:51;;24960:2;24955;24940:18;;24933:30;;;-1:-1:-1;;24986:56:21;;25023:18;;25015:6;24986:56;:::i;:::-;25090:9;25082:6;25078:22;25073:2;25062:9;25058:18;25051:50;25118:44;25155:6;25147;25118:44;:::i;25462:245::-;25529:6;25582:2;25570:9;25561:7;25557:23;25553:32;25550:52;;;25598:1;25595;25588:12;25550:52;25630:9;25624:16;25649:28;25671:5;25649:28;:::i;26054:830::-;26201:6;26209;26217;26225;26278:3;26266:9;26257:7;26253:23;26249:33;26246:53;;;26295:1;26292;26285:12;26246:53;26328:9;26322:16;-1:-1:-1;;;;;26353:6:21;26350:30;26347:50;;;26393:1;26390;26383:12;26347:50;26416:72;26480:7;26471:6;26460:9;26456:22;26416:72;:::i;:::-;26406:82;;;26534:2;26523:9;26519:18;26513:25;-1:-1:-1;;;;;26553:8:21;26550:32;26547:52;;;26595:1;26592;26585:12;26547:52;26618:74;26684:7;26673:8;26662:9;26658:24;26618:74;:::i;:::-;26754:2;26739:18;;26733:25;26848:2;26833:18;;;26827:25;26054:830;;26608:84;;-1:-1:-1;26054:830:21;-1:-1:-1;;;;26054:830:21:o;26889:168::-;26962:9;;;26993;;27010:15;;;27004:22;;26990:37;26980:71;;27031:18;;:::i;27062:127::-;27123:10;27118:3;27114:20;27111:1;27104:31;27154:4;27151:1;27144:15;27178:4;27175:1;27168:15;27194:120;27234:1;27260;27250:35;;27265:18;;:::i;:::-;-1:-1:-1;27299:9:21;;27194:120::o;27319:1172::-;-1:-1:-1;;;;;27685:32:21;;;27667:51;;27749:2;27734:18;;27727:34;;;27797:32;;27792:2;27777:18;;27770:60;27861:2;27846:18;;27839:34;;;27910:3;27904;27889:19;;27882:32;;;-1:-1:-1;;27937:57:21;;27974:19;;27966:6;27937:57;:::i;:::-;28031:22;;;28025:3;28010:19;;28003:51;28103:13;;28125:22;;;28194:1;28187:17;;;28175:2;28227:16;;;;28163:15;;28103:13;28271:194;28285:6;28282:1;28279:13;28271:194;;;28350:13;;-1:-1:-1;;;;;28346:39:21;28334:52;;28382:1;28441:14;;;;28415:2;28406:12;;;;28300:9;28271:194;;;-1:-1:-1;28482:3:21;;27319:1172;-1:-1:-1;;;;;;;;;;27319:1172:21:o;28496:135::-;28535:3;28556:17;;;28553:43;;28576:18;;:::i;:::-;-1:-1:-1;28623:1:21;28612:13;;28496:135::o;28636:127::-;28697:10;28692:3;28688:20;28685:1;28678:31;28728:4;28725:1;28718:15;28752:4;28749:1;28742:15;28768:251;28838:6;28891:2;28879:9;28870:7;28866:23;28862:32;28859:52;;;28907:1;28904;28897:12;28859:52;28939:9;28933:16;28958:31;28983:5;28958:31;:::i;30068:125::-;30133:9;;;30154:10;;;30151:36;;;30167:18;;:::i;30198:179::-;30276:13;;30329:22;30318:34;;30308:45;;30298:73;;30367:1;30364;30357:12;30382:571;30485:6;30493;30501;30509;30517;30570:3;30558:9;30549:7;30545:23;30541:33;30538:53;;;30587:1;30584;30577:12;30538:53;30610:39;30639:9;30610:39;:::i;:::-;30689:2;30674:18;;30668:25;30755:2;30740:18;;30734:25;30849:2;30834:18;;30828:25;30600:49;;-1:-1:-1;30668:25:21;;-1:-1:-1;30734:25:21;-1:-1:-1;30828:25:21;-1:-1:-1;30898:49:21;30942:3;30927:19;;30898:49;:::i;:::-;30888:59;;30382:571;;;;;;;;:::o;31291:273::-;31359:6;31412:2;31400:9;31391:7;31387:23;31383:32;31380:52;;;31428:1;31425;31418:12;31380:52;31460:9;31454:16;31510:4;31503:5;31499:16;31492:5;31489:27;31479:55;;31530:1;31527;31520:12;33233:151;33323:4;33316:12;;;33302;;;33298:31;;33341:14;;33338:40;;;33358:18;;:::i;33389:375::-;33477:1;33495:5;33509:249;33530:1;33520:8;33517:15;33509:249;;;33580:4;33575:3;33571:14;33565:4;33562:24;33559:50;;;33589:18;;:::i;:::-;33639:1;33629:8;33625:16;33622:49;;;33653:16;;;;33622:49;33736:1;33732:16;;;;;33692:15;;33509:249;;;33389:375;;;;;;:::o;33769:902::-;33818:5;33848:8;33838:80;;-1:-1:-1;33889:1:21;33903:5;;33838:80;33937:4;33927:76;;-1:-1:-1;33974:1:21;33988:5;;33927:76;34019:4;34037:1;34032:59;;;;34105:1;34100:174;;;;34012:262;;34032:59;34062:1;34053:10;;34076:5;;;34100:174;34137:3;34127:8;34124:17;34121:43;;;34144:18;;:::i;:::-;-1:-1:-1;;34200:1:21;34186:16;;34259:5;;34012:262;;34358:2;34348:8;34345:16;34339:3;34333:4;34330:13;34326:36;34320:2;34310:8;34307:16;34302:2;34296:4;34293:12;34289:35;34286:77;34283:203;;;-1:-1:-1;34395:19:21;;;34471:5;;34283:203;34518:42;-1:-1:-1;;34543:8:21;34537:4;34518:42;:::i;:::-;34596:6;34592:1;34588:6;34584:19;34575:7;34572:32;34569:58;;;34607:18;;:::i;:::-;34645:20;;33769:902;-1:-1:-1;;;33769:902:21:o;34676:140::-;34734:5;34763:47;34804:4;34794:8;34790:19;34784:4;34763:47;:::i;35152:131::-;35212:5;35241:36;35268:8;35262:4;35241:36;:::i;39361:626::-;39549:2;39561:21;;;39631:13;;39534:18;;;39653:22;;;39501:4;;39732:15;;;39706:2;39691:18;;;39501:4;39775:186;39789:6;39786:1;39783:13;39775:186;;;39854:13;;39869:10;39850:30;39838:43;;39910:2;39936:15;;;;39901:12;;;;39811:1;39804:9;39775:186;;;-1:-1:-1;39978:3:21;;39361:626;-1:-1:-1;;;;;39361:626:21:o;39992:1235::-;40119:6;40127;40180:2;40168:9;40159:7;40155:23;40151:32;40148:52;;;40196:1;40193;40186:12;40148:52;40229:9;40223:16;-1:-1:-1;;;;;40254:6:21;40251:30;40248:50;;;40294:1;40291;40284:12;40248:50;40317:22;;40370:4;40362:13;;40358:27;-1:-1:-1;40348:55:21;;40399:1;40396;40389:12;40348:55;40432:2;40426:9;40455:64;40471:47;40511:6;40471:47;:::i;40455:64::-;40541:3;40565:6;40560:3;40553:19;40597:4;40592:3;40588:14;40581:21;;40654:4;40644:6;40641:1;40637:14;40633:2;40629:23;40625:34;40611:48;;40682:7;40674:6;40671:19;40668:39;;;40703:1;40700;40693:12;40668:39;40735:4;40731:2;40727:13;40716:24;;40749:242;40765:6;40760:3;40757:15;40749:242;;;40840:3;40834:10;40891:5;40888:1;40877:20;40870:5;40867:31;40857:59;;40912:1;40909;40902:12;40857:59;40929:18;;40976:4;40782:14;;;;40967;;;;40749:242;;;41010:5;41000:15;;;;;;41061:4;41050:9;41046:20;41040:27;-1:-1:-1;;;;;41082:8:21;41079:32;41076:52;;;41124:1;41121;41114:12;41232:210;41330:1;41319:16;;;41301;;;;41297:39;-1:-1:-1;;41351:32:21;;41395:16;41385:27;;41348:65;41345:91;;;41416:18;;:::i;41447:284::-;41485:1;41526;41523;41512:16;41562:1;41559;41548:16;41583:3;41573:37;;41590:18;;:::i;:::-;-1:-1:-1;;41626:30:21;;-1:-1:-1;;41658:15:21;;41622:52;41619:78;;;41677:18;;:::i;:::-;41711:14;;;41447:284;-1:-1:-1;;;41447:284:21:o;41736:166::-;41766:1;41807;41804;41793:16;41828:3;41818:37;;41835:18;;:::i;:::-;41892:3;41888:1;41885;41874:16;41869:27;41864:32;;;41736:166;;;;:::o;41907:192::-;41944:3;41991:5;41988:1;41977:20;42025:7;42021:12;42012:7;42009:25;42006:51;;42037:18;;:::i;:::-;-1:-1:-1;;42073:20:21;;41907:192;-1:-1:-1;;41907:192:21:o;44180:301::-;44309:3;44347:6;44341:13;44393:6;44386:4;44378:6;44374:17;44369:3;44363:37;44455:1;44419:16;;44444:13;;;-1:-1:-1;44419:16:21;44180:301;-1:-1:-1;44180:301:21:o;44844:418::-;44993:2;44982:9;44975:21;44956:4;45025:6;45019:13;45068:6;45063:2;45052:9;45048:18;45041:34;45127:6;45122:2;45114:6;45110:15;45105:2;45094:9;45090:18;45084:50;45183:1;45178:2;45169:6;45158:9;45154:22;45150:31;45143:42;45253:2;45246;45242:7;45237:2;45229:6;45225:15;45221:29;45210:9;45206:45;45202:54;45194:62;;;44844:418;;;;:::o
Swarm Source
ipfs://01f9e8c8499a0143475c950927f11fbab318b326774b32de7e0544fca3944e33
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.