Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
[ Download CSV Export ]
Contract Name:
VaultAdaptorMK2
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.4; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./common/Constants.sol"; import "./common/Whitelist.sol"; import "./interfaces/IVaultMK2.sol"; import "./interfaces/IERC20Detailed.sol"; interface IStrategy { function want() external view returns (address); function vault() external view returns (address); function isActive() external view returns (bool); function estimatedTotalAssets() external view returns (uint256); function withdraw(uint256 _amount) external returns (uint256); function migrate(address _newStrategy) external; function harvestTrigger(uint256 callCost) external view returns (bool); function harvest() external; } /// @notice VaultAdapterMk2 - Gro protocol stand alone vault for strategy testing /// /// Desing is based on a modified version of the yearnV2Vault /// /// ############################################### /// Vault Adaptor specifications /// ############################################### /// /// - Deposit: A deposit will move assets into the vault adaptor, which will be /// available for investment into the underlying strategies /// - Withdrawal: A withdrawal will always attempt to pull from the vaultAdaptor if possible, /// if the assets in the adaptor fail to cover the withdrawal, the adaptor will /// attempt to withdraw assets from the underlying strategies. /// - Asset availability: /// - VaultAdaptor /// - Strategies /// - Debt ratios: Ratio in %BP of assets to invest in the underlying strategies of a vault contract VaultAdaptorMK2 is Constants, Whitelist, IVaultMK2, ERC20, ReentrancyGuard { using SafeERC20 for IERC20; uint256 public constant MAXIMUM_STRATEGIES = 5; address constant ZERO_ADDRESS = address(0); // Underlying token address public immutable override token; uint256 private immutable _decimals; struct StrategyParams { uint256 activation; bool active; uint256 debtRatio; uint256 minDebtPerHarvest; uint256 maxDebtPerHarvest; uint256 lastReport; uint256 totalDebt; uint256 totalGain; uint256 totalLoss; } // Allowance bool public allowance = true; // turn allowance on/off mapping(address => bool) public claimed; uint256 public immutable BASE_ALLOWANCE; // user BASE allowance mapping(address => uint256) public userAllowance; // user additional allowance mapping(address => StrategyParams) public strategies; address[MAXIMUM_STRATEGIES] public withdrawalQueue; // Slow release of profit uint256 public lockedProfit; uint256 public releaseFactor; uint256 public debtRatio; uint256 public totalDebt; uint256 public lastReport; uint256 public activation; uint256 public depositLimit; address public bouncer; address public rewards; uint256 public vaultFee; event LogStrategyAdded( address indexed strategy, uint256 debtRatio, uint256 minDebtPerHarvest, uint256 maxDebtPerHarvest ); event LogStrategyReported( address indexed strategy, uint256 gain, uint256 loss, uint256 debtPaid, uint256 totalGain, uint256 totalLoss, uint256 totalDebt, uint256 debtAdded, uint256 debtRatio ); event LogUpdateWithdrawalQueue(address[] queue); event LogNewDebtRatio(address indexed strategy, uint256 debtRatio); event LogStrategyUpdateMinDebtPerHarvest( address indexed strategy, uint256 minDebtPerHarvest ); event LogStrategyUpdateMaxDebtPerHarvest( address indexed strategy, uint256 maxDebtPerHarvest ); event LogStrategyMigrated( address indexed newStrategy, address indexed oldStrategy ); event LogStrategyRevoked(address indexed strategy); event LogStrategyRemovedFromQueue(address indexed strategy); event LogStrategyAddedToQueue(address indexed strategy); event LogStrategyStatusUpdate(address indexed strategy, bool status); event LogDepositLimit(uint256 newLimit); event LogDebtRatios(uint256[] strategyRetios); event LogMigrate(address parent, address child, uint256 amount); event LogNewBouncer(address bouncer); event LogNewRewards(address rewards); event LogNewReleaseFactor(uint256 factor); event LogNewVaultFee(uint256 vaultFee); event LogNewStrategyHarvest(bool loss, uint256 change); event LogNewAllowance(address user, uint256 amount); event LogAllowanceStatus(bool status); event LogDeposit( address indexed from, uint256 _amount, uint256 shares, uint256 allowance ); event LogWithdrawal( address indexed from, uint256 value, uint256 shares, uint256 totalLoss, uint256 allowance ); constructor( address _token, uint256 _baseAllowance, address _bouncer ) ERC20( string( abi.encodePacked( "Gro ", IERC20Detailed(_token).symbol(), " Lab" ) ), string(abi.encodePacked("gro", IERC20Detailed(_token).symbol())) ) { token = _token; activation = block.timestamp; uint256 decimals = IERC20Detailed(_token).decimals(); _decimals = decimals; BASE_ALLOWANCE = _baseAllowance * 10**decimals; bouncer = _bouncer; // 6 hours release releaseFactor = (DEFAULT_DECIMALS_FACTOR * 46) / 10**6; } /// @notice Vault share decimals function decimals() public view override returns (uint8) { return uint8(_decimals); } /// @notice Set contract that controlls user allowance /// @param _bouncer address of new bouncer function setBouncer(address _bouncer) external onlyOwner { bouncer = _bouncer; emit LogNewBouncer(_bouncer); } /// @notice Set Vault to use allowance /// @param _status set allowance to on/off function activateAllowance(bool _status) external onlyOwner { allowance = _status; emit LogAllowanceStatus(_status); } /// @notice Set contract that will recieve vault fees /// @param _rewards address of rewards contract function setRewards(address _rewards) external onlyOwner { rewards = _rewards; emit LogNewRewards(_rewards); } /// @notice Set fee that is reduced from strategy yields when harvests are called /// @param _fee new strategy fee function setVaultFee(uint256 _fee) external onlyOwner { require(_fee < 3000, "setVaultFee: _fee > 30%"); vaultFee = _fee; emit LogNewVaultFee(_fee); } /// @notice Total limit for vault deposits /// @param _newLimit new max deposit limit for the vault function setDepositLimit(uint256 _newLimit) external onlyOwner { depositLimit = _newLimit; emit LogDepositLimit(_newLimit); } /// @notice Limit for how much individual users are allowed to deposit /// @param _user user to set allowance for /// @param _amount new allowance amount function setUserAllowance(address _user, uint256 _amount) external { require( msg.sender == bouncer, "setUserAllowance: msg.sender != bouncer" ); if (!claimed[_user]) { userAllowance[_user] += _amount * (10**_decimals) + BASE_ALLOWANCE; claimed[_user] = true; } else { userAllowance[_user] += _amount * (10**_decimals); } emit LogNewAllowance(_user, _amount); } /// @notice Set how quickly profits are released /// @param _factor how quickly profits are released function setProfitRelease(uint256 _factor) external onlyOwner { releaseFactor = _factor; emit LogNewReleaseFactor(_factor); } /// @notice Calculate system total assets function totalAssets() external view override returns (uint256) { return _totalAssets(); } /// @notice Get number of strategies in underlying vault function getStrategiesLength() external view override returns (uint256) { return strategyLength(); } /// @notice Get total amount invested in strategy /// @param _index index of strategy function getStrategyAssets(uint256 _index) external view override returns (uint256 amount) { return _getStrategyTotalAssets(_index); } /// @notice Deposit assets into the vault adaptor /// @param _amount user deposit amount function deposit(uint256 _amount) external nonReentrant returns (uint256) { require(_amount > 0, "deposit: _amount !> 0"); require( _totalAssets() + _amount <= depositLimit, "deposit: !depositLimit" ); uint256 _allowance = 0; if (allowance) { _allowance = userAllowance[msg.sender]; if (!claimed[msg.sender]) { require(_amount <= BASE_ALLOWANCE, "deposit: !userAllowance"); _allowance = BASE_ALLOWANCE - _amount; claimed[msg.sender] = true; } else { require( userAllowance[msg.sender] >= _amount, "deposit: !userAllowance" ); _allowance = userAllowance[msg.sender] - _amount; } userAllowance[msg.sender] = _allowance; } uint256 shares = _issueSharesForAmount(msg.sender, _amount); IERC20 _token = IERC20(token); _token.safeTransferFrom(msg.sender, address(this), _amount); emit LogDeposit(msg.sender, _amount, shares, _allowance); return shares; } /// @notice Mint shares for user based on deposit amount /// @param _to recipient /// @param _amount amount of want deposited function _issueSharesForAmount(address _to, uint256 _amount) internal returns (uint256) { uint256 shares; uint256 _totalSupply = totalSupply(); if (_totalSupply > 0) { shares = (_amount * _totalSupply) / _freeFunds(); } else { shares = _amount; } // unlikely to happen, just here for added safety require(shares != 0, "_issueSharesForAmount: shares == 0"); _mint(_to, shares); return shares; } /// @notice Check if underlying strategy needs to be harvested /// @param _index Index of stratey /// @param _callCost Cost of harvest in underlying token function strategyHarvestTrigger(uint256 _index, uint256 _callCost) external view override returns (bool) { require(_index < strategyLength(), "invalid index"); return IStrategy(withdrawalQueue[_index]).harvestTrigger(_callCost); } /// @notice Harvest underlying strategy /// @param _index Index of strategy /// @dev Any Gains/Losses incurred by harvesting a streategy is accounted for in the vault adapter /// and reported back to the Controller, which in turn updates current system total assets. function strategyHarvest(uint256 _index) external nonReentrant onlyWhitelist { require(_index < strategyLength(), "invalid index"); IStrategy _strategy = IStrategy(withdrawalQueue[_index]); uint256 beforeAssets = _totalAssets(); _strategy.harvest(); uint256 afterAssets = _totalAssets(); bool loss; uint256 change; if (beforeAssets > afterAssets) { change = beforeAssets - afterAssets; loss = true; } else { change = afterAssets - beforeAssets; loss = false; } emit LogNewStrategyHarvest(loss, change); } /// @notice Calculate how much profit is currently locked function _calculateLockedProfit() internal view returns (uint256) { uint256 lockedFundsRatio = (block.timestamp - lastReport) * releaseFactor; if (lockedFundsRatio < DEFAULT_DECIMALS_FACTOR) { uint256 _lockedProfit = lockedProfit; return _lockedProfit - ((lockedFundsRatio * _lockedProfit) / DEFAULT_DECIMALS_FACTOR); } else { return 0; } } function _freeFunds() internal view returns (uint256) { return _totalAssets() - _calculateLockedProfit(); } /// @notice Calculate system total assets including estimated profits function totalEstimatedAssets() external view returns (uint256) { uint256 total = IERC20(token).balanceOf(address(this)); for (uint256 i = 0; i < strategyLength(); i++) { total += _getStrategyEstimatedTotalAssets(i); } return total; } /// @notice Update the withdrawal queue /// @param _queue New withdrawal queue order function setWithdrawalQueue(address[] calldata _queue) external onlyOwner { require( _queue.length <= MAXIMUM_STRATEGIES, "setWithdrawalQueue: > MAXIMUM_STRATEGIES" ); for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { if (i >= _queue.length) { withdrawalQueue[i] = address(0); } else { withdrawalQueue[i] = _queue[i]; } emit LogUpdateWithdrawalQueue(_queue); } } /// @notice Number of active strategies in the vaultAdapter function strategyLength() internal view returns (uint256) { for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { if (withdrawalQueue[i] == address(0)) { return i; } } return MAXIMUM_STRATEGIES; } /// @notice Update the debtRatio of a specific strategy /// @param _strategy target strategy /// @param _debtRatio new debt ratio function setDebtRatio(address _strategy, uint256 _debtRatio) external { // If a strategy isnt the source of the call require(strategies[_strategy].active, "setDebtRatio: !active"); require( msg.sender == owner() || whitelist[msg.sender], "setDebtRatio: !whitelist" ); _setDebtRatio(_strategy, _debtRatio); require( debtRatio <= PERCENTAGE_DECIMAL_FACTOR, "setDebtRatio: debtRatio > 100%" ); } /// @notice Set new strategy debt ratios /// @param _strategyDebtRatios array of new debt ratios /// @dev Can be used to forecfully change the debt ratios of the underlying strategies /// by whitelisted parties/owner function setDebtRatios(uint256[] memory _strategyDebtRatios) external { require( msg.sender == owner() || whitelist[msg.sender], "setDebtRatios: !whitelist" ); require( _strategyDebtRatios.length <= MAXIMUM_STRATEGIES, "setDebtRatios: > MAXIMUM_STRATEGIES" ); address _strategy; uint256 _ratio; for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { _strategy = withdrawalQueue[i]; if (_strategy == address(0)) { break; } else { _ratio = _strategyDebtRatios[i]; } _setDebtRatio(_strategy, _ratio); } require( debtRatio <= PERCENTAGE_DECIMAL_FACTOR, "setDebtRatios: debtRatio > 100%" ); } /// @notice Add a new strategy to the vault adapter /// @param _strategy target strategy to add /// @param _debtRatio target debtRatio of strategy /// @param _minDebtPerHarvest min amount of debt the strategy can take on per harvest /// @param _maxDebtPerHarvest max amount of debt the strategy can take on per harvest function addStrategy( address _strategy, uint256 _debtRatio, uint256 _minDebtPerHarvest, uint256 _maxDebtPerHarvest ) external onlyOwner { require( withdrawalQueue[MAXIMUM_STRATEGIES - 1] == ZERO_ADDRESS, "addStrategy: > MAXIMUM_STRATEGIES" ); require(_strategy != ZERO_ADDRESS, "addStrategy: address(0x)"); require(!strategies[_strategy].active, "addStrategy: !activated"); require( address(this) == IStrategy(_strategy).vault(), "addStrategy: !vault" ); require( debtRatio + _debtRatio <= PERCENTAGE_DECIMAL_FACTOR, "addStrategy: debtRatio > 100%" ); require( _minDebtPerHarvest <= _maxDebtPerHarvest, "addStrategy: min > max" ); StrategyParams storage newStrat = strategies[_strategy]; newStrat.activation = block.timestamp; newStrat.active = true; newStrat.debtRatio = _debtRatio; newStrat.minDebtPerHarvest = _minDebtPerHarvest; newStrat.maxDebtPerHarvest = _maxDebtPerHarvest; newStrat.lastReport = block.timestamp; emit LogStrategyAdded( _strategy, _debtRatio, _minDebtPerHarvest, _maxDebtPerHarvest ); debtRatio += _debtRatio; withdrawalQueue[strategyLength()] = _strategy; _organizeWithdrawalQueue(); } /// @notice Set a new min debt equired for assets to be made available to the strategy at harvest /// @param _strategy strategy address /// @param _minDebtPerHarvest new min debt function updateStrategyMinDebtPerHarvest( address _strategy, uint256 _minDebtPerHarvest ) external onlyOwner { require( strategies[_strategy].activation > 0, "updateStrategyMinDebtPerHarvest: !activated" ); require( strategies[_strategy].maxDebtPerHarvest >= _minDebtPerHarvest, "updateStrategyMinDebtPerHarvest: min > max" ); strategies[_strategy].minDebtPerHarvest = _minDebtPerHarvest; emit LogStrategyUpdateMinDebtPerHarvest(_strategy, _minDebtPerHarvest); } /// @notice Set a new max debt that can be made avilable to the stragey at harvest /// @param _strategy strategy address /// @param _maxDebtPerHarvest new max debt function updateStrategyMaxDebtPerHarvest( address _strategy, uint256 _maxDebtPerHarvest ) external onlyOwner { require( strategies[_strategy].activation > 0, "updateStrategyMaxDebtPerHarvest: !activated" ); require( strategies[_strategy].minDebtPerHarvest <= _maxDebtPerHarvest, "updateStrategyMaxDebtPerHarvest: min > max" ); strategies[_strategy].maxDebtPerHarvest = _maxDebtPerHarvest; emit LogStrategyUpdateMaxDebtPerHarvest(_strategy, _maxDebtPerHarvest); } /// @notice Replace existing strategy with a new one, removing he old one from the vault adapters /// active strategies /// @param _oldVersion address of old strategy /// @param _newVersion address of new strategy function migrateStrategy(address _oldVersion, address _newVersion) external onlyOwner { require(_newVersion != ZERO_ADDRESS, "migrateStrategy: 0x"); require( strategies[_oldVersion].activation > 0, "migrateStrategy: oldVersion !activated" ); require( strategies[_oldVersion].active, "migrateStrategy: oldVersion !active" ); require( strategies[_newVersion].activation == 0, "migrateStrategy: newVersion activated" ); StrategyParams storage _strategy = strategies[_oldVersion]; debtRatio += _strategy.debtRatio; StrategyParams storage newStrat = strategies[_newVersion]; newStrat.activation = block.timestamp; newStrat.active = true; newStrat.debtRatio = _strategy.debtRatio; newStrat.minDebtPerHarvest = _strategy.minDebtPerHarvest; newStrat.maxDebtPerHarvest = _strategy.maxDebtPerHarvest; newStrat.lastReport = _strategy.lastReport; newStrat.totalDebt = _strategy.totalDebt; newStrat.totalDebt = 0; newStrat.totalGain = 0; newStrat.totalLoss = 0; IStrategy(_oldVersion).migrate(_newVersion); _strategy.totalDebt = 0; _strategy.minDebtPerHarvest = 0; _strategy.maxDebtPerHarvest = 0; emit LogStrategyMigrated(_oldVersion, _newVersion); _revokeStrategy(_oldVersion); for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { if (withdrawalQueue[i] == _oldVersion) { withdrawalQueue[i] = _newVersion; return; } } } /// @notice Remove strategy from vault adapter, called by strategy on emergencyExit function revokeStrategy() external { require( strategies[msg.sender].active, "revokeStrategy: strategy not active" ); _revokeStrategy(msg.sender); } /// @notice Manually add a strategy to the withdrawal queue /// @param _strategy target strategy to add function addStrategyToQueue(address _strategy) external { require( msg.sender == owner() || whitelist[msg.sender], "addStrategyToQueue: !owner|whitelist" ); require( strategies[_strategy].activation > 0, "addStrategyToQueue: !activated" ); require( withdrawalQueue[MAXIMUM_STRATEGIES - 1] == ZERO_ADDRESS, "addStrategyToQueue: queue full" ); for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { address strategy = withdrawalQueue[i]; if (strategy == ZERO_ADDRESS) break; require( _strategy != strategy, "addStrategyToQueue: strategy already in queue" ); } withdrawalQueue[MAXIMUM_STRATEGIES - 1] = _strategy; _organizeWithdrawalQueue(); emit LogStrategyAddedToQueue(_strategy); } /// @notice Manually remove a strategy to the withdrawal queue /// @param _strategy Target strategy to remove function removeStrategyFromQueue(address _strategy) external { require( msg.sender == owner() || whitelist[msg.sender], "removeStrategyFromQueue: !owner|whitelist" ); for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { if (withdrawalQueue[i] == _strategy) { withdrawalQueue[i] = ZERO_ADDRESS; _organizeWithdrawalQueue(); emit LogStrategyRemovedFromQueue(_strategy); return; } } } /// @notice Check how much credits are available for the strategy /// @param _strategy Target strategy function creditAvailable(address _strategy) external view returns (uint256) { return _creditAvailable(_strategy); } /// @notice Same as above but called by the streategy function creditAvailable() external view returns (uint256) { return _creditAvailable(msg.sender); } /// @notice Calculate the amount of assets the vault has available for the strategy to pull and invest, /// the available credit is based of the strategies debt ratio and the total available assets /// the vault has /// @param _strategy target strategy /// @dev called during harvest function _creditAvailable(address _strategy) internal view returns (uint256) { StrategyParams memory _strategyData = strategies[_strategy]; uint256 vaultTotalAssets = _totalAssets(); uint256 vaultDebtLimit = (debtRatio * vaultTotalAssets) / PERCENTAGE_DECIMAL_FACTOR; uint256 vaultTotalDebt = totalDebt; uint256 strategyDebtLimit = (_strategyData.debtRatio * vaultTotalAssets) / PERCENTAGE_DECIMAL_FACTOR; uint256 strategyTotalDebt = _strategyData.totalDebt; uint256 strategyMinDebtPerHarvest = _strategyData.minDebtPerHarvest; uint256 strategyMaxDebtPerHarvest = _strategyData.maxDebtPerHarvest; IERC20 _token = IERC20(token); if ( strategyDebtLimit <= strategyTotalDebt || vaultDebtLimit <= vaultTotalDebt ) { return 0; } uint256 available = strategyDebtLimit - strategyTotalDebt; available = Math.min(available, vaultDebtLimit - vaultTotalDebt); available = Math.min(available, _token.balanceOf(address(this))); if (available < strategyMinDebtPerHarvest) { return 0; } else { return Math.min(available, strategyMaxDebtPerHarvest); } } /// @notice Deal with any loss that a strategy has realized /// @param _strategy target strategy /// @param _loss amount of loss realized function _reportLoss(address _strategy, uint256 _loss) internal { StrategyParams storage strategy = strategies[_strategy]; // Loss can only be up the amount of debt issued to strategy require(strategy.totalDebt >= _loss, "_reportLoss: totalDebt >= loss"); // Add loss to srategy and remove loss from strategyDebt strategy.totalLoss += _loss; strategy.totalDebt -= _loss; totalDebt -= _loss; } /// @notice Amount by which a strategy exceeds its current debt limit /// @param _strategy target strategy function _debtOutstanding(address _strategy) internal view returns (uint256) { StrategyParams storage strategy = strategies[_strategy]; uint256 strategyDebtLimit = (strategy.debtRatio * _totalAssets()) / PERCENTAGE_DECIMAL_FACTOR; uint256 strategyTotalDebt = strategy.totalDebt; if (strategyTotalDebt <= strategyDebtLimit) { return 0; } else { return strategyTotalDebt - strategyDebtLimit; } } /// @notice Amount of debt the strategy has to pay back to the vault at next harvest /// @param _strategy target strategy function debtOutstanding(address _strategy) external view returns (uint256) { return _debtOutstanding(_strategy); } /// @notice Amount of debt the strategy has to pay back to the vault at next harvest /// @dev same as above but used by strategies function debtOutstanding() external view returns (uint256) { return _debtOutstanding(msg.sender); } /// @notice A strategies total debt to the vault /// @dev here to simplify strategies life when trying to get the totalDebt function strategyDebt() external view returns (uint256) { return strategies[msg.sender].totalDebt; } /// @notice Remove unwanted token from contract /// @param _token Address of unwanted token, cannot be want token /// @param _recipient Reciever of unwanted token function sweep(address _token, address _recipient) external onlyOwner { require(_token != token, "sweep: token == want"); uint256 amount = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransfer(_recipient, amount); } /// @notice Withdraw desired amount from vault adapter, if the reserves are unable to /// to cover the desired amount, start withdrawing from strategies in order specified. /// The withdrawamount if set in shares and calculated in the underlying token the vault holds. /// @param _shares Amount to withdraw in shares /// @param _maxLoss Max accepted loss when withdrawing from strategy function withdraw(uint256 _shares, uint256 _maxLoss) external nonReentrant returns (uint256) { require( _maxLoss <= PERCENTAGE_DECIMAL_FACTOR, "withdraw: _maxLoss > 100%" ); require(_shares > 0, "withdraw: _shares == 0"); uint256 userBalance = balanceOf(msg.sender); uint256 shares = _shares == type(uint256).max ? balanceOf(msg.sender) : _shares; require(shares <= userBalance, "withdraw, shares > userBalance"); uint256 value = _shareValue(shares); IERC20 _token = IERC20(token); uint256 totalLoss = 0; // If reserves dont cover the withdrawal, start withdrawing from strategies if (value > _token.balanceOf(address(this))) { address[MAXIMUM_STRATEGIES] memory _strategies = withdrawalQueue; for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { address _strategy = _strategies[i]; if (_strategy == ZERO_ADDRESS) break; uint256 vaultBalance = _token.balanceOf(address(this)); // break if we have withdrawn all we need if (value <= vaultBalance) break; uint256 amountNeeded = value - vaultBalance; StrategyParams storage _strategyData = strategies[_strategy]; amountNeeded = Math.min(amountNeeded, _strategyData.totalDebt); // If nothing is needed or strategy has no assets, continue if (amountNeeded == 0) { continue; } uint256 loss = IStrategy(_strategy).withdraw(amountNeeded); // Amount withdraw from strategy uint256 withdrawn = _token.balanceOf(address(this)) - vaultBalance; // Handle the loss if any if (loss > 0) { value = value - loss; totalLoss = totalLoss + loss; _reportLoss(_strategy, loss); } // Remove withdrawn amount from strategy and vault debts _strategyData.totalDebt -= withdrawn; totalDebt -= withdrawn; } uint256 finalBalance = _token.balanceOf(address(this)); if (value > finalBalance) { totalLoss = totalLoss + value - finalBalance; value = finalBalance; } require( totalLoss <= (_maxLoss * (value + totalLoss)) / PERCENTAGE_DECIMAL_FACTOR, "withdraw: loss > maxloss" ); } _burn(msg.sender, shares); _token.safeTransfer(msg.sender, value); // Hopefully get a bit more allowance - thx for participating! uint256 _allowance = 0; if (allowance) { _allowance = userAllowance[msg.sender] + (value + totalLoss); userAllowance[msg.sender] = _allowance; } emit LogWithdrawal(msg.sender, value, shares, totalLoss, _allowance); return value; } /// @notice Value of shares in underlying token /// @param _shares amount of shares to convert to tokens function _shareValue(uint256 _shares) internal view returns (uint256) { uint256 _totalSupply = totalSupply(); if (_totalSupply == 0) return _shares; return ((_shares * _freeFunds()) / _totalSupply); } /// @notice Value of tokens in shares /// @param _amount amount of tokens to convert to shares function _sharesForAmount(uint256 _amount) internal view returns (uint256) { uint256 _assets = _freeFunds(); if (_assets > 0) { return (_amount * totalSupply()) / _assets; } return 0; } function _calcFees(uint256 _gain) internal returns (uint256) { uint256 fees = (_gain * vaultFee) / PERCENTAGE_DECIMAL_FACTOR; if (fees > 0) _issueSharesForAmount(rewards, fees); return _gain - fees; } /// @notice Report back any gains/losses from a (strategy) harvest, vault adapetr /// calls back debt or gives out more credit to the strategy depending on available /// credit and the strategies current position. /// @param _gain Strategy gains from latest harvest /// @param _loss Strategy losses from latest harvest /// @param _debtPayment Amount strategy can pay back to vault function report( uint256 _gain, uint256 _loss, uint256 _debtPayment ) external returns (uint256) { StrategyParams storage _strategy = strategies[msg.sender]; require(_strategy.activation > 0, "report: !activated"); IERC20 _token = IERC20(token); require( _token.balanceOf(msg.sender) >= _gain + _debtPayment, "report: balance(strategy) < _gain + _debtPayment" ); if (_loss > 0) { _reportLoss(msg.sender, _loss); } _strategy.totalGain = _strategy.totalGain + _gain; uint256 debt = _debtOutstanding(msg.sender); uint256 debtPayment = Math.min(_debtPayment, debt); if (debtPayment > 0) { _strategy.totalDebt = _strategy.totalDebt - debtPayment; totalDebt -= debtPayment; debt -= debtPayment; } uint256 credit = _creditAvailable(msg.sender); if (credit > 0) { _strategy.totalDebt += credit; totalDebt += credit; } uint256 totalAvailable = _gain + debtPayment; if (totalAvailable < credit) { _token.safeTransfer(msg.sender, credit - totalAvailable); } else if (totalAvailable > credit) { _token.safeTransferFrom( msg.sender, address(this), totalAvailable - credit ); } // Profit is locked and gradually released per block // NOTE: compute current locked profit and replace with sum of current and new uint256 lockedProfitBeforeLoss = _calculateLockedProfit() + _calcFees(_gain); if (lockedProfitBeforeLoss > _loss) { lockedProfit = lockedProfitBeforeLoss - _loss; } else { lockedProfit = 0; } lastReport = block.timestamp; _strategy.lastReport = lastReport; emit LogStrategyReported( msg.sender, _gain, _loss, debtPayment, _strategy.totalGain, _strategy.totalLoss, _strategy.totalDebt, credit, _strategy.debtRatio ); if (_strategy.debtRatio == 0) { return IStrategy(msg.sender).estimatedTotalAssets(); } else { return debt; } } /// @notice Update a given strategies debt ratio /// @param _strategy target strategy /// @param _debtRatio new debt ratio /// @dev See setDebtRatios and setDebtRatio functions function _setDebtRatio(address _strategy, uint256 _debtRatio) internal { debtRatio -= strategies[_strategy].debtRatio; strategies[_strategy].debtRatio = _debtRatio; debtRatio += _debtRatio; emit LogNewDebtRatio(_strategy, _debtRatio); } /// @notice Gives the price for a single Vault share. /// @return The value of a single share. /// @dev See dev note on `withdraw`. function getPricePerShare() external view returns (uint256) { return _shareValue(10**_decimals); } /// @notice Get current enstimated amount of assets in strategy /// @param _index index of strategy function _getStrategyEstimatedTotalAssets(uint256 _index) internal view returns (uint256) { return IStrategy(withdrawalQueue[_index]).estimatedTotalAssets(); } /// @notice Get strategy totalDebt /// @param _index index of strategy function _getStrategyTotalAssets(uint256 _index) internal view returns (uint256) { StrategyParams storage strategy = strategies[withdrawalQueue[_index]]; return strategy.totalDebt; } /// @notice Remove strategy from vault /// @param _strategy address of strategy function _revokeStrategy(address _strategy) internal { debtRatio -= strategies[_strategy].debtRatio; strategies[_strategy].debtRatio = 0; strategies[_strategy].active = false; emit LogStrategyRevoked(_strategy); } /// @notice Vault adapters total assets including loose assets and debts /// @dev note that this does not consider estimated gains/losses from the strategies function _totalAssets() private view returns (uint256) { return IERC20(token).balanceOf(address(this)) + totalDebt; } /// @notice Reorder the withdrawal queue to put the zero addresses at the end function _organizeWithdrawalQueue() internal { uint256 offset; for (uint256 i; i < MAXIMUM_STRATEGIES; i++) { address strategy = withdrawalQueue[i]; if (strategy == ZERO_ADDRESS) { offset += 1; } else if (offset > 0) { withdrawalQueue[i - offset] = strategy; withdrawalQueue[i] = ZERO_ADDRESS; } } } }
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.4; contract Constants { uint8 internal constant DEFAULT_DECIMALS = 18; uint256 internal constant DEFAULT_DECIMALS_FACTOR = uint256(10)**DEFAULT_DECIMALS; uint8 internal constant PERCENTAGE_DECIMALS = 4; uint256 internal constant PERCENTAGE_DECIMAL_FACTOR = uint256(10)**PERCENTAGE_DECIMALS; }
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.4; import "@openzeppelin/contracts/access/Ownable.sol"; contract Whitelist is Ownable { mapping(address => bool) public whitelist; event LogAddToWhitelist(address indexed user); event LogRemoveFromWhitelist(address indexed user); modifier onlyWhitelist() { require(whitelist[msg.sender], "only whitelist"); _; } function addToWhitelist(address user) external onlyOwner { require(user != address(0), "WhiteList: 0x"); whitelist[user] = true; emit LogAddToWhitelist(user); } function removeFromWhitelist(address user) external onlyOwner { require(user != address(0), "WhiteList: 0x"); whitelist[user] = false; emit LogRemoveFromWhitelist(user); } }
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.4; interface IVaultMK2 { function totalAssets() external view returns (uint256); function getStrategiesLength() external view returns (uint256); function strategyHarvestTrigger(uint256 index, uint256 callCost) external view returns (bool); function getStrategyAssets(uint256 index) external view returns (uint256); function token() external view returns (address); }
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.4; interface IERC20Detailed { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/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)); } } /** * @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: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT 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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT 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 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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // 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 pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/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() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { 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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
{ "metadata": { "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_baseAllowance","type":"uint256"},{"internalType":"address","name":"_bouncer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"LogAddToWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"LogAllowanceStatus","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"strategyRetios","type":"uint256[]"}],"name":"LogDebtRatios","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowance","type":"uint256"}],"name":"LogDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"LogDepositLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"parent","type":"address"},{"indexed":false,"internalType":"address","name":"child","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogMigrate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogNewAllowance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"bouncer","type":"address"}],"name":"LogNewBouncer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRatio","type":"uint256"}],"name":"LogNewDebtRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"factor","type":"uint256"}],"name":"LogNewReleaseFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewards","type":"address"}],"name":"LogNewRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"loss","type":"bool"},{"indexed":false,"internalType":"uint256","name":"change","type":"uint256"}],"name":"LogNewStrategyHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultFee","type":"uint256"}],"name":"LogNewVaultFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"LogRemoveFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minDebtPerHarvest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxDebtPerHarvest","type":"uint256"}],"name":"LogStrategyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"LogStrategyAddedToQueue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newStrategy","type":"address"},{"indexed":true,"internalType":"address","name":"oldStrategy","type":"address"}],"name":"LogStrategyMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"LogStrategyRemovedFromQueue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"gain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtPaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalGain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalLoss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtAdded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtRatio","type":"uint256"}],"name":"LogStrategyReported","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"LogStrategyRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"LogStrategyStatusUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"maxDebtPerHarvest","type":"uint256"}],"name":"LogStrategyUpdateMaxDebtPerHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"minDebtPerHarvest","type":"uint256"}],"name":"LogStrategyUpdateMinDebtPerHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"queue","type":"address[]"}],"name":"LogUpdateWithdrawalQueue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalLoss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowance","type":"uint256"}],"name":"LogWithdrawal","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":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BASE_ALLOWANCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_STRATEGIES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"activateAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"uint256","name":"_debtRatio","type":"uint256"},{"internalType":"uint256","name":"_minDebtPerHarvest","type":"uint256"},{"internalType":"uint256","name":"_maxDebtPerHarvest","type":"uint256"}],"name":"addStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"addStrategyToQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bouncer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creditAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"creditAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"debtOutstanding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtOutstanding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPricePerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategiesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getStrategyAssets","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastReport","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedProfit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oldVersion","type":"address"},{"internalType":"address","name":"_newVersion","type":"address"}],"name":"migrateStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"releaseFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"removeStrategyFromQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gain","type":"uint256"},{"internalType":"uint256","name":"_loss","type":"uint256"},{"internalType":"uint256","name":"_debtPayment","type":"uint256"}],"name":"report","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_bouncer","type":"address"}],"name":"setBouncer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"setDebtRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_strategyDebtRatios","type":"uint256[]"}],"name":"setDebtRatios","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newLimit","type":"uint256"}],"name":"setDepositLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_factor","type":"uint256"}],"name":"setProfitRelease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setUserAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setVaultFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_queue","type":"address[]"}],"name":"setWithdrawalQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"strategies","outputs":[{"internalType":"uint256","name":"activation","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"debtRatio","type":"uint256"},{"internalType":"uint256","name":"minDebtPerHarvest","type":"uint256"},{"internalType":"uint256","name":"maxDebtPerHarvest","type":"uint256"},{"internalType":"uint256","name":"lastReport","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"totalGain","type":"uint256"},{"internalType":"uint256","name":"totalLoss","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategyDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"strategyHarvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_callCost","type":"uint256"}],"name":"strategyHarvestTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalEstimatedAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"uint256","name":"_maxDebtPerHarvest","type":"uint256"}],"name":"updateStrategyMaxDebtPerHarvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"uint256","name":"_minDebtPerHarvest","type":"uint256"}],"name":"updateStrategyMinDebtPerHarvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_maxLoss","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalQueue","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e06040526008805460ff191660011790553480156200001e57600080fd5b50604051620059bc380380620059bc8339810160408190526200004191620003d7565b826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156200007b57600080fd5b505afa15801562000090573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620000ba919081019062000417565b604051602001620000cc919062000522565b604051602081830303815290604052836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156200011557600080fd5b505afa1580156200012a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000154919081019062000417565b604051602001620001669190620004f5565b60408051808303601f190181529190526200018133620002c4565b81516200019690600590602085019062000314565b508051620001ac90600690602084019062000314565b50506001600755506001600160601b0319606084901b16608052426016556040805163313ce56760e01b815290516000916001600160a01b0386169163313ce56791600480820192602092909190829003018186803b1580156200020f57600080fd5b505afa15801562000224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200024a9190620004cb565b60ff1660a081905290506200026181600a620005c8565b6200026d908462000698565b60c052601880546001600160a01b0319166001600160a01b038416179055620f42406200029d6012600a620005d6565b620002aa90602e62000698565b620002b691906200055e565b601255506200075692505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200032290620006ed565b90600052602060002090601f01602090048101928262000346576000855562000391565b82601f106200036157805160ff191683800117855562000391565b8280016001018555821562000391579182015b828111156200039157825182559160200191906001019062000374565b506200039f929150620003a3565b5090565b5b808211156200039f5760008155600101620003a4565b80516001600160a01b0381168114620003d257600080fd5b919050565b600080600060608486031215620003ec578283fd5b620003f784620003ba565b9250602084015191506200040e60408501620003ba565b90509250925092565b60006020828403121562000429578081fd5b81516001600160401b038082111562000440578283fd5b818401915084601f83011262000454578283fd5b81518181111562000469576200046962000740565b604051601f8201601f19908116603f0116810190838211818310171562000494576200049462000740565b81604052828152876020848701011115620004ad578586fd5b620004c0836020830160208801620006ba565b979650505050505050565b600060208284031215620004dd578081fd5b815160ff81168114620004ee578182fd5b9392505050565b6267726f60e81b81526000825162000515816003850160208701620006ba565b9190910160030192915050565b63023b937960e51b81526000825162000543816004850160208701620006ba565b63102630b160e11b6004939091019283015250600801919050565b6000826200057a57634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115620005c0578160001904821115620005a457620005a46200072a565b80851615620005b257918102915b93841c939080029062000584565b509250929050565b6000620004ee8383620005e2565b6000620004ee60ff8416835b600082620005f35750600162000692565b81620006025750600062000692565b81600181146200061b5760028114620006265762000646565b600191505062000692565b60ff8411156200063a576200063a6200072a565b50506001821b62000692565b5060208310610133831016604e8410600b84101617156200066b575081810a62000692565b6200067783836200057f565b80600019048211156200068e576200068e6200072a565b0290505b92915050565b6000816000190483118215151615620006b557620006b56200072a565b500290565b60005b83811015620006d7578181015183820152602001620006bd565b83811115620006e7576000848401525b50505050565b600181811c908216806200070257607f821691505b602082108114156200072457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60805160601c60a05160c0516151d8620007e46000396000818161080001528181612a6701528181612ad501526138860152600081816104e201528181611221015281816138aa015261393e01526000818161098e015281816113c00152818161220801528181612bb401528181612c6401528181612e2201528181613a060152613dfe01526151d86000f3fe608060405234801561001057600080fd5b50600436106103fc5760003560e01c80639ec5a89411610215578063cab2080811610125578063e722befe116100b8578063f6bad0e311610087578063f6bad0e314610950578063f76e4caa14610963578063fb0fc07614610976578063fc0c546a14610989578063fc7b9c18146109b057600080fd5b8063e722befe1461090e578063ec38a86214610921578063ecf7085814610934578063f2fde38b1461093d57600080fd5b8063de242ff4116100f4578063de242ff4146108c8578063e04e7341146108d5578063e43252d7146108e8578063e438c4b7146108fb57600080fd5b8063cab208081461086b578063cea55f5714610873578063d76480131461087c578063dd62ed3e1461088f57600080fd5b8063b8dc491b116101a8578063c3535b5211610177578063c3535b52146107f2578063c45b35ef146107fb578063c533683514610822578063c822adda14610835578063c884ef831461084857600080fd5b8063b8dc491b146107b1578063bdc8144b146107c4578063bdcf36bb146107d7578063bf3759b5146107ea57600080fd5b8063a9059cbb116101e4578063a9059cbb14610765578063ac579b7714610778578063b22439f51461078b578063b6b55f251461079e57600080fd5b80639ec5a89414610724578063a0e4af9a14610737578063a1d9bafc1461073f578063a457c2d71461075257600080fd5b80633e9dc7621161031057806370a08231116102a35780638c3d7819116102725780638c3d7819146106b95780638da5cb5b146106cc57806395d89b41146106f15780639666b83b146106f95780639b19251a1461070157600080fd5b806370a082311461066d578063715018a614610696578063772d23121461069e5780638ab1d681146106a657600080fd5b806351d1df68116102df57806351d1df681461062b5780635cb44e251461063e5780635da69cb6146106515780636cb56d191461065a57600080fd5b80633e9dc762146105e4578063441a3e70146105fc57806344b813961461060f5780634757a1561461061857600080fd5b8063157122161161039357806335582baa1161036257806335582baa1461050c5780633629c8de1461051f578063395093511461052857806339ebf8231461053b5780633d68175c146105dc57600080fd5b806315712216146104ad57806318160ddd146104c057806323b872dd146104c8578063313ce567146104db57600080fd5b80630c6b2cbf116103cf5780630c6b2cbf1461045d5780630dd21b6c1461047d578063112c1f9b14610492578063135ccc471461049a57600080fd5b806301ac145b1461040157806301e1d1141461041d57806306fdde0314610425578063095ea7b31461043a575b600080fd5b61040a601a5481565b6040519081526020015b60405180910390f35b61040a6109b9565b61042d6109c8565b6040516104149190614ecf565b61044d610448366004614c1c565b610a5a565b6040519015158152602001610414565b61040a61046b366004614b6c565b600a6020526000908152604090205481565b61049061048b366004614c47565b610a71565b005b61040a610e68565b6104906104a8366004614de9565b610e73565b6104906104bb366004614b6c565b611045565b60045461040a565b61044d6104d6366004614bdc565b6110c4565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610414565b61049061051a366004614db1565b611170565b61040a60165481565b61044d610536366004614c1c565b6111db565b610598610549366004614b6c565b600b60205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007880154600890980154969760ff90961696949593949293919290919089565b60408051998a5297151560208a0152968801959095526060870193909352608086019190915260a085015260c084015260e083015261010082015261012001610414565b61040a611217565b336000908152600b602052604090206006015461040a565b61040a61060a366004614e19565b61124c565b61040a60115481565b610490610626366004614c1c565b6118fc565b610490610639366004614de9565b611a79565b61044d61064c366004614e19565b611ad8565b61040a60125481565b610490610668366004614ba4565b611bbc565b61040a61067b366004614b6c565b6001600160a01b031660009081526002602052604090205490565b610490611f85565b61040a600581565b6104906106b4366004614b6c565b611fbb565b6104906106c7366004614de9565b612074565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610414565b61042d612124565b61040a612133565b61044d61070f366004614b6c565b60016020526000908152604090205460ff1681565b6019546106d9906001600160a01b031681565b61049061213d565b61040a61074d366004614e3a565b6121b4565b61044d610760366004614c1c565b6125b3565b61044d610773366004614c1c565b61264c565b610490610786366004614c81565b612659565b610490610799366004614b6c565b612805565b61040a6107ac366004614de9565b612967565b6104906107bf366004614ba4565b612c38565b6104906107d2366004614de9565b612d6b565b61040a6107e5366004614b6c565b612dca565b61040a612dd5565b61040a60155481565b61040a7f000000000000000000000000000000000000000000000000000000000000000081565b6018546106d9906001600160a01b031681565b6106d9610843366004614de9565b612de0565b61044d610856366004614b6c565b60096020526000908152604090205460ff1681565b61040a612e00565b61040a60135481565b61040a61088a366004614b6c565b612edd565b61040a61089d366004614ba4565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b60085461044d9060ff1681565b61040a6108e3366004614de9565b612ee8565b6104906108f6366004614b6c565b612ef3565b610490610909366004614c1c565b612fb2565b61049061091c366004614c1c565b6130f0565b61049061092f366004614b6c565b613261565b61040a60175481565b61049061094b366004614b6c565b6132d9565b61049061095e366004614cf1565b613374565b610490610971366004614b6c565b613531565b610490610984366004614c1c565b6137fa565b6106d97f000000000000000000000000000000000000000000000000000000000000000081565b61040a60145481565b60006109c36139e2565b905090565b6060600580546109d790615103565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0390615103565b8015610a505780601f10610a2557610100808354040283529160200191610a50565b820191906000526020600020905b815481529060010190602001808311610a3357829003601f168201915b5050505050905090565b6000610a67338484613a8a565b5060015b92915050565b6000546001600160a01b03163314610aa45760405162461bcd60e51b8152600401610a9b90614f02565b60405180910390fd5b6000600c610ab4600160056150c0565b60058110610ad257634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031614610b345760405162461bcd60e51b815260206004820152602160248201527f61646453747261746567793a203e204d4158494d554d5f5354524154454749456044820152605360f81b6064820152608401610a9b565b6001600160a01b038416610b8a5760405162461bcd60e51b815260206004820152601860248201527f61646453747261746567793a20616464726573732830782900000000000000006044820152606401610a9b565b6001600160a01b0384166000908152600b602052604090206001015460ff1615610bf65760405162461bcd60e51b815260206004820152601760248201527f61646453747261746567793a20216163746976617465640000000000000000006044820152606401610a9b565b836001600160a01b031663fbfa77cf6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c2f57600080fd5b505afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c679190614b88565b6001600160a01b0316306001600160a01b031614610cbd5760405162461bcd60e51b815260206004820152601360248201527218591914dd1c985d1959de4e88085d985d5b1d606a1b6044820152606401610a9b565b610cc96004600a614ff5565b83601354610cd79190614f6e565b1115610d255760405162461bcd60e51b815260206004820152601d60248201527f61646453747261746567793a2064656274526174696f203e20313030250000006044820152606401610a9b565b80821115610d6e5760405162461bcd60e51b81526020600482015260166024820152750c2c8c8a6e8e4c2e8cacef27440dad2dc407c40dac2f60531b6044820152606401610a9b565b6001600160a01b0384166000818152600b6020908152604091829020428082556001808301805460ff19169091179055600282018890556003820187905560048201869055600582015582518781529182018690529181018490529091907f3586d47464d021baa33927385fac3386971b58ccfe7f5dfe4c837d38f8910c759060600160405180910390a28360136000828254610e0b9190614f6e565b90915550859050600c610e1c613bae565b60058110610e3a57634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b0392909216919091179055610e61613c0e565b5050505050565b60006109c333613d08565b60026007541415610e965760405162461bcd60e51b8152600401610a9b90614f37565b60026007553360009081526001602052604090205460ff16610eeb5760405162461bcd60e51b815260206004820152600e60248201526d1bdb9b1e481dda1a5d195b1a5cdd60921b6044820152606401610a9b565b610ef3613bae565b8110610f315760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a9b565b6000600c8260058110610f5457634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031690506000610f6b6139e2565b9050816001600160a01b0316634641257d6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610fa857600080fd5b505af1158015610fbc573d6000803e3d6000fd5b505050506000610fca6139e2565b905060008082841115610fec57610fe183856150c0565b905060019150610ffd565b610ff684846150c0565b9050600091505b604080518315158152602081018390527f563299b3cea13d0c7eaf34be3ef046674da9c4515ccb7168d0b6b76ee51de999910160405180910390a15050600160075550505050565b6000546001600160a01b0316331461106f5760405162461bcd60e51b8152600401610a9b90614f02565b601880546001600160a01b0319166001600160a01b0383169081179091556040519081527f37fc88d041ee44a8c99855f5123550d8063586b8943d755664fe21853a37ded6906020015b60405180910390a150565b60006110d1848484613f19565b6001600160a01b0384166000908152600360209081526040808320338452909152902054828110156111565760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610a9b565b6111638533858403613a8a565b60019150505b9392505050565b6000546001600160a01b0316331461119a5760405162461bcd60e51b8152600401610a9b90614f02565b6008805460ff19168215159081179091556040519081527fedc78a6979d711a718e08c7bf6abc68c7fae72f0e425a8594db3bed0ac1bcad8906020016110b9565b3360008181526003602090815260408083206001600160a01b03871684529091528120549091610a67918590611212908690614f6e565b613a8a565b60006109c36112477f0000000000000000000000000000000000000000000000000000000000000000600a614fe9565b6140e9565b6000600260075414156112715760405162461bcd60e51b8152600401610a9b90614f37565b60026007556112826004600a614ff5565b8211156112d15760405162461bcd60e51b815260206004820152601960248201527f77697468647261773a205f6d61784c6f7373203e2031303025000000000000006044820152606401610a9b565b6000831161131a5760405162461bcd60e51b8152602060048201526016602482015275077697468647261773a205f736861726573203d3d20360541b6044820152606401610a9b565b3360009081526002602052604081205490600019851461133a578461134b565b336000908152600260205260409020545b90508181111561139d5760405162461bcd60e51b815260206004820152601e60248201527f77697468647261772c20736861726573203e207573657242616c616e636500006044820152606401610a9b565b60006113a8826140e9565b6040516370a0823160e01b81523060048201529091507f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038316906370a082319060240160206040518083038186803b15801561140f57600080fd5b505afa158015611423573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114479190614e01565b83111561183c576040805160a0810191829052600091600c9060059082845b81546001600160a01b03168152600190910190602001808311611466575050505050905060005b60058110156117205760008282600581106114b857634e487b7160e01b600052603260045260246000fd5b602002015190506001600160a01b0381166114d35750611720565b6040516370a0823160e01b81523060048201526000906001600160a01b038716906370a082319060240160206040518083038186803b15801561151557600080fd5b505afa158015611529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154d9190614e01565b905080871161155d575050611720565b600061156982896150c0565b6001600160a01b0384166000908152600b60205260409020600681015491925090611595908390614120565b9150816115a5575050505061170e565b604051632e1a7d4d60e01b8152600481018390526000906001600160a01b03861690632e1a7d4d90602401602060405180830381600087803b1580156115ea57600080fd5b505af11580156115fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116229190614e01565b6040516370a0823160e01b815230600482015290915060009085906001600160a01b038c16906370a082319060240160206040518083038186803b15801561166957600080fd5b505afa15801561167d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a19190614e01565b6116ab91906150c0565b905081156116d5576116bd828c6150c0565b9a506116c9828a614f6e565b98506116d58683614136565b808360060160008282546116e991906150c0565b92505081905550806014600082825461170291906150c0565b90915550505050505050505b8061171881615138565b91505061148d565b506040516370a0823160e01b81523060048201526000906001600160a01b038516906370a082319060240160206040518083038186803b15801561176357600080fd5b505afa158015611777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179b9190614e01565b9050808511156117c057806117b08685614f6e565b6117ba91906150c0565b92508094505b6117cc6004600a614ff5565b6117d68487614f6e565b6117e0908b6150a1565b6117ea9190614f86565b8311156118395760405162461bcd60e51b815260206004820152601860248201527f77697468647261773a206c6f7373203e206d61786c6f737300000000000000006044820152606401610a9b565b50505b61184633856141f4565b61185a6001600160a01b0383163385614342565b60085460009060ff16156118a1576118728285614f6e565b336000908152600a602052604090205461188c9190614f6e565b336000908152600a6020526040902081905590505b60408051858152602081018790529081018390526060810182905233907fab0db1f1d6053f0c5e9e0333bd02e8e46a6996df63ddf355481cf233cea5ae279060800160405180910390a2505060016007555095945050505050565b6000546001600160a01b031633146119265760405162461bcd60e51b8152600401610a9b90614f02565b6001600160a01b0382166000908152600b602052604090205461199f5760405162461bcd60e51b815260206004820152602b60248201527f75706461746553747261746567794d617844656274506572486172766573743a60448201526a08085858dd1a5d985d195960aa1b6064820152608401610a9b565b6001600160a01b0382166000908152600b6020526040902060030154811015611a1d5760405162461bcd60e51b815260206004820152602a60248201527f75706461746553747261746567794d617844656274506572486172766573743a604482015269040dad2dc407c40dac2f60b31b6064820152608401610a9b565b6001600160a01b0382166000818152600b602052604090819020600401839055517fd57caa6337591e8c2fe908a4fb0bb9c4bcaf42a657ee20be2717ef81aa4f19aa90611a6d9084815260200190565b60405180910390a25050565b6000546001600160a01b03163314611aa35760405162461bcd60e51b8152600401610a9b90614f02565b60128190556040518181527f878c3cca2b60914ab09a7e6a59c03fe2cb9b7c7ead8fef12a5eb1d90bcd1ab10906020016110b9565b6000611ae2613bae565b8310611b205760405162461bcd60e51b815260206004820152600d60248201526c0d2dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610a9b565b600c8360058110611b4157634e487b7160e01b600052603260045260246000fd5b015460405163ed882c2b60e01b8152600481018490526001600160a01b039091169063ed882c2b9060240160206040518083038186803b158015611b8457600080fd5b505afa158015611b98573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111699190614dcd565b6000546001600160a01b03163314611be65760405162461bcd60e51b8152600401610a9b90614f02565b6001600160a01b038116611c325760405162461bcd60e51b81526020600482015260136024820152720dad2cee4c2e8caa6e8e4c2e8cacef2744060f606b1b6044820152606401610a9b565b6001600160a01b0382166000908152600b6020526040902054611ca65760405162461bcd60e51b815260206004820152602660248201527f6d69677261746553747261746567793a206f6c6456657273696f6e20216163746044820152651a5d985d195960d21b6064820152608401610a9b565b6001600160a01b0382166000908152600b602052604090206001015460ff16611d1d5760405162461bcd60e51b815260206004820152602360248201527f6d69677261746553747261746567793a206f6c6456657273696f6e202161637460448201526269766560e81b6064820152608401610a9b565b6001600160a01b0381166000908152600b602052604090205415611d915760405162461bcd60e51b815260206004820152602560248201527f6d69677261746553747261746567793a206e657756657273696f6e20616374696044820152641d985d195960da1b6064820152608401610a9b565b6001600160a01b0382166000908152600b6020526040812060028101546013805492939192909190611dc4908490614f6e565b90915550506001600160a01b038281166000818152600b60205260408082204281556001808201805460ff191690911790556002868101549082015560038087015490820155600480870154818301556005808801549083015560068201849055600782018490556008820193909355905163ce5494bb60e01b815291820192909252909185169063ce5494bb90602401600060405180830381600087803b158015611e6f57600080fd5b505af1158015611e83573d6000803e3d6000fd5b505060006006850181905560038501819055600485018190556040516001600160a01b038088169450881692507feb6703dc9f9bdf90f637c0ef7b9dd7a08c095983cf29923c90d98f345dd95caf9190a3611edd846143a5565b60005b6005811015610e6157846001600160a01b0316600c8260058110611f1457634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161415611f6f5783600c8260058110611f4757634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b039290921691909117905550611f81915050565b80611f7981615138565b915050611ee0565b5050565b6000546001600160a01b03163314611faf5760405162461bcd60e51b8152600401610a9b90614f02565b611fb9600061442c565b565b6000546001600160a01b03163314611fe55760405162461bcd60e51b8152600401610a9b90614f02565b6001600160a01b03811661202b5760405162461bcd60e51b815260206004820152600d60248201526c0aed0d2e8ca98d2e6e8744060f609b1b6044820152606401610a9b565b6001600160a01b038116600081815260016020526040808220805460ff19169055517f9e9499495e2efd848d33cb197bde94612c1ec36f30605b60d445511e056069e19190a250565b6000546001600160a01b0316331461209e5760405162461bcd60e51b8152600401610a9b90614f02565b610bb881106120ef5760405162461bcd60e51b815260206004820152601760248201527f7365745661756c744665653a205f666565203e203330250000000000000000006044820152606401610a9b565b601a8190556040518181527f01fa6949e7a4e70ebcf603589526b183cfd84c0023e87018cf99f1d661a72bbc906020016110b9565b6060600680546109d790615103565b60006109c3613bae565b336000908152600b602052604090206001015460ff166121ab5760405162461bcd60e51b815260206004820152602360248201527f7265766f6b6553747261746567793a207374726174656779206e6f742061637460448201526269766560e81b6064820152608401610a9b565b611fb9336143a5565b336000908152600b6020526040812080546122065760405162461bcd60e51b81526020600482015260126024820152711c995c1bdc9d0e88085858dd1a5d985d195960721b6044820152606401610a9b565b7f00000000000000000000000000000000000000000000000000000000000000006122318487614f6e565b6040516370a0823160e01b81523360048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561227057600080fd5b505afa158015612284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a89190614e01565b101561230f5760405162461bcd60e51b815260206004820152603060248201527f7265706f72743a2062616c616e636528737472617465677929203c205f67616960448201526f1b880ac817d919589d14185e5b595b9d60821b6064820152608401610a9b565b841561231f5761231f3386614136565b85826007015461232f9190614f6e565b6007830155600061233f3361447c565b9050600061234d8683614120565b905080156123925780846006015461236591906150c0565b8460060181905550806014600082825461237f91906150c0565b9091555061238f905081836150c0565b91505b600061239d33613d08565b905080156123d857808560060160008282546123b99190614f6e565b9250508190555080601460008282546123d29190614f6e565b90915550505b60006123e4838b614f6e565b9050818110156124125761240d336123fc83856150c0565b6001600160a01b0388169190614342565b61243b565b8181111561243b5761243b333061242985856150c0565b6001600160a01b0389169291906144ef565b60006124468b614527565b61244e614577565b6124589190614f6e565b9050898111156124745761246c8a826150c0565b60115561247a565b60006011555b426015819055506015548760050181905550336001600160a01b03167fdd2147c7c786ce7a36d0010e0b96b77cafac9d0a6802f882d2c2255777d744b48c8c878b600701548c600801548d600601548a8f60020154604051612514989796959493929190978852602088019690965260408701949094526060860192909252608085015260a084015260c083015260e08201526101000190565b60405180910390a260028701546125a457336001600160a01b031663efbb5cb06040518163ffffffff1660e01b815260040160206040518083038186803b15801561255e57600080fd5b505afa158015612572573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125969190614e01565b975050505050505050611169565b84975050505050505050611169565b3360009081526003602090815260408083206001600160a01b0386168452909152812054828110156126355760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610a9b565b6126423385858403613a8a565b5060019392505050565b6000610a67338484613f19565b6000546001600160a01b031633146126835760405162461bcd60e51b8152600401610a9b90614f02565b60058111156126e55760405162461bcd60e51b815260206004820152602860248201527f7365745769746864726177616c51756575653a203e204d4158494d554d5f5354604482015267524154454749455360c01b6064820152608401610a9b565b60005b60058110156128005781811061273f576000600c826005811061271b57634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b03929092169190911790556127b5565b82828281811061275f57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906127749190614b6c565b600c826005811061279557634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b03929092169190911790555b7fc24e80a5fd747b0bbfa6f9a1d7c50f98ab024556c97d3bd6a5cf651445e6b3dd83836040516127e6929190614e81565b60405180910390a1806127f881615138565b9150506126e8565b505050565b6000546001600160a01b031633148061282d57503360009081526001602052604090205460ff165b61288b5760405162461bcd60e51b815260206004820152602960248201527f72656d6f7665537472617465677946726f6d51756575653a20216f776e65727c6044820152681dda1a5d195b1a5cdd60ba1b6064820152608401610a9b565b60005b6005811015611f8157816001600160a01b0316600c82600581106128c257634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161415612955576000600c82600581106128f657634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b039290921691909117905561291d613c0e565b6040516001600160a01b038316907fdb6049adb19dec12ff8b7422e722c7d155939bb8080c2ba3f9c8a3b0443c7ad490600090a25050565b8061295f81615138565b91505061288e565b60006002600754141561298c5760405162461bcd60e51b8152600401610a9b90614f37565b6002600755816129d65760405162461bcd60e51b815260206004820152601560248201527406465706f7369743a205f616d6f756e7420213e203605c1b6044820152606401610a9b565b601754826129e26139e2565b6129ec9190614f6e565b1115612a335760405162461bcd60e51b815260206004820152601660248201527519195c1bdcda5d0e880859195c1bdcda5d131a5b5a5d60521b6044820152606401610a9b565b60085460009060ff1615612ba45750336000908152600a602090815260408083205460099092529091205460ff16612b1a577f0000000000000000000000000000000000000000000000000000000000000000831115612acf5760405162461bcd60e51b81526020600482015260176024820152766465706f7369743a202175736572416c6c6f77616e636560481b6044820152606401610a9b565b612af9837f00000000000000000000000000000000000000000000000000000000000000006150c0565b336000908152600960205260409020805460ff191660011790559050612b91565b336000908152600a6020526040902054831115612b735760405162461bcd60e51b81526020600482015260176024820152766465706f7369743a202175736572416c6c6f77616e636560481b6044820152606401610a9b565b336000908152600a6020526040902054612b8e9084906150c0565b90505b336000908152600a602052604090208190555b6000612bb033856145e6565b90507f0000000000000000000000000000000000000000000000000000000000000000612be86001600160a01b0382163330886144ef565b604080518681526020810184905290810184905233907f4b2bcb0ca50531683faa51870e1018aa0d7272c7f2acc5399389b0c0493865d99060600160405180910390a25060016007559392505050565b6000546001600160a01b03163314612c625760405162461bcd60e51b8152600401610a9b90614f02565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415612cdb5760405162461bcd60e51b81526020600482015260146024820152731cddd9595c0e881d1bdad95b880f4f481dd85b9d60621b6044820152606401610a9b565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b158015612d1d57600080fd5b505afa158015612d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d559190614e01565b90506128006001600160a01b0384168383614342565b6000546001600160a01b03163314612d955760405162461bcd60e51b8152600401610a9b90614f02565b60178190556040518181527f90ab2effdb5b095500fdf80ad1d4c418e957095fb6e475ff03576beefc97cae7906020016110b9565b6000610a6b8261447c565b60006109c33361447c565b600c8160058110612df057600080fd5b01546001600160a01b0316905081565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015612e6457600080fd5b505afa158015612e78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9c9190614e01565b905060005b612ea9613bae565b811015612ed757612eb98161468d565b612ec39083614f6e565b915080612ecf81615138565b915050612ea1565b50919050565b6000610a6b82613d08565b6000610a6b82614735565b6000546001600160a01b03163314612f1d5760405162461bcd60e51b8152600401610a9b90614f02565b6001600160a01b038116612f635760405162461bcd60e51b815260206004820152600d60248201526c0aed0d2e8ca98d2e6e8744060f609b1b6044820152606401610a9b565b6001600160a01b0381166000818152600160208190526040808320805460ff1916909217909155517f4e3d8c117d484081f7268ed79cded71ad42979b92feb5f8f7f9824ac5cbfe3759190a250565b6001600160a01b0382166000908152600b602052604090206001015460ff166130155760405162461bcd60e51b815260206004820152601560248201527473657444656274526174696f3a202161637469766560581b6044820152606401610a9b565b6000546001600160a01b031633148061303d57503360009081526001602052604090205460ff165b6130895760405162461bcd60e51b815260206004820152601860248201527f73657444656274526174696f3a202177686974656c69737400000000000000006044820152606401610a9b565b6130938282614783565b61309f6004600a614ff5565b6013541115611f815760405162461bcd60e51b815260206004820152601e60248201527f73657444656274526174696f3a2064656274526174696f203e203130302500006044820152606401610a9b565b6000546001600160a01b0316331461311a5760405162461bcd60e51b8152600401610a9b90614f02565b6001600160a01b0382166000908152600b60205260409020546131935760405162461bcd60e51b815260206004820152602b60248201527f75706461746553747261746567794d696e44656274506572486172766573743a60448201526a08085858dd1a5d985d195960aa1b6064820152608401610a9b565b6001600160a01b0382166000908152600b60205260409020600401548111156132115760405162461bcd60e51b815260206004820152602a60248201527f75706461746553747261746567794d696e44656274506572486172766573743a604482015269040dad2dc407c40dac2f60b31b6064820152608401610a9b565b6001600160a01b0382166000818152600b602052604090819020600301839055517f97d937f34d1eadd7b324f774a47165e95470edd473866a60d2162850ca57823790611a6d9084815260200190565b6000546001600160a01b0316331461328b5760405162461bcd60e51b8152600401610a9b90614f02565b601980546001600160a01b0319166001600160a01b0383169081179091556040519081527f47d7c5d0e54dad44a791a37aaafbe848a5b4e4fb8c64462d67fa949c7e106222906020016110b9565b6000546001600160a01b031633146133035760405162461bcd60e51b8152600401610a9b90614f02565b6001600160a01b0381166133685760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a9b565b6133718161442c565b50565b6000546001600160a01b031633148061339c57503360009081526001602052604090205460ff165b6133e85760405162461bcd60e51b815260206004820152601960248201527f73657444656274526174696f733a202177686974656c697374000000000000006044820152606401610a9b565b6005815111156134465760405162461bcd60e51b815260206004820152602360248201527f73657444656274526174696f733a203e204d4158494d554d5f5354524154454760448201526249455360e81b6064820152608401610a9b565b60008060005b60058110156134d357600c816005811061347657634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031692508261348d576134d3565b8381815181106134ad57634e487b7160e01b600052603260045260246000fd5b602002602001015191506134c18383614783565b806134cb81615138565b91505061344c565b506134e06004600a614ff5565b60135411156128005760405162461bcd60e51b815260206004820152601f60248201527f73657444656274526174696f733a2064656274526174696f203e2031303025006044820152606401610a9b565b6000546001600160a01b031633148061355957503360009081526001602052604090205460ff165b6135b15760405162461bcd60e51b8152602060048201526024808201527f6164645374726174656779546f51756575653a20216f776e65727c77686974656044820152631b1a5cdd60e21b6064820152608401610a9b565b6001600160a01b0381166000908152600b60205260409020546136165760405162461bcd60e51b815260206004820152601e60248201527f6164645374726174656779546f51756575653a202161637469766174656400006044820152606401610a9b565b6000600c613626600160056150c0565b6005811061364457634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161461369c5760405162461bcd60e51b815260206004820152601e60248201527f6164645374726174656779546f51756575653a2071756575652066756c6c00006044820152606401610a9b565b60005b600581101561376e576000600c82600581106136cb57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03169050806136e3575061376e565b806001600160a01b0316836001600160a01b0316141561375b5760405162461bcd60e51b815260206004820152602d60248201527f6164645374726174656779546f51756575653a20737472617465677920616c7260448201526c6561647920696e20717565756560981b6064820152608401610a9b565b508061376681615138565b91505061369f565b5080600c61377e600160056150c0565b6005811061379c57634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b03929092169190911790556137c3613c0e565b6040516001600160a01b038216907f9bc825e07ecd66a8b4fa4d5a982ca78e22dce2099ea4348ff8b5297b4afac26a90600090a250565b6018546001600160a01b031633146138645760405162461bcd60e51b815260206004820152602760248201527f73657455736572416c6c6f77616e63653a206d73672e73656e64657220213d206044820152663137bab731b2b960c91b6064820152608401610a9b565b6001600160a01b03821660009081526009602052604090205460ff16613939577f00000000000000000000000000000000000000000000000000000000000000006138d07f0000000000000000000000000000000000000000000000000000000000000000600a614fe9565b6138da90836150a1565b6138e49190614f6e565b6001600160a01b0383166000908152600a60205260408120805490919061390c908490614f6e565b90915550506001600160a01b0382166000908152600960205260409020805460ff1916600117905561399c565b6139647f0000000000000000000000000000000000000000000000000000000000000000600a614fe9565b61396e90826150a1565b6001600160a01b0383166000908152600a602052604081208054909190613996908490614f6e565b90915550505b604080516001600160a01b0384168152602081018390527f9028c777fc890e3be2f623e0bc932c51e841f34385fcd65571a2e744e5f63e8e910160405180910390a15050565b6014546040516370a0823160e01b8152306004820152600091906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015613a4857600080fd5b505afa158015613a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a809190614e01565b6109c39190614f6e565b6001600160a01b038316613aec5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a9b565b6001600160a01b038216613b4d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a9b565b6001600160a01b0383811660008181526003602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000805b6005811015613c06576000600c8260058110613bde57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161415613bf457919050565b80613bfe81615138565b915050613bb2565b506005905090565b6000805b6005811015611f81576000600c8260058110613c3e57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b0316905080613c6257613c5b600184614f6e565b9250613cf5565b8215613cf55780600c613c7585856150c0565b60058110613c9357634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b03929092169190911790556000600c8360058110613cd557634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b03929092169190911790555b5080613d0081615138565b915050613c12565b6001600160a01b0381166000908152600b6020908152604080832081516101208101835281548152600182015460ff161515938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460e08301526008015461010082015281613d926139e2565b90506000613da26004600a614ff5565b82601354613db091906150a1565b613dba9190614f86565b6014549091506000613dce6004600a614ff5565b848660400151613dde91906150a1565b613de89190614f86565b60c08601516060870151608088015192935090917f00000000000000000000000000000000000000000000000000000000000000008385111580613e2c5750858711155b15613e42575060009a9950505050505050505050565b6000613e4e85876150c0565b9050613e6381613e5e898b6150c0565b614120565b6040516370a0823160e01b8152306004820152909150613ee39082906001600160a01b038516906370a082319060240160206040518083038186803b158015613eab57600080fd5b505afa158015613ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e5e9190614e01565b905083811015613eff575060009b9a5050505050505050505050565b613f098184614120565b9c9b505050505050505050505050565b6001600160a01b038316613f7d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610a9b565b6001600160a01b038216613fdf5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610a9b565b6001600160a01b038316600090815260026020526040902054818110156140575760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610a9b565b6001600160a01b0380851660009081526002602052604080822085850390559185168152908120805484929061408e908490614f6e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516140da91815260200190565b60405180910390a35b50505050565b6000806140f560045490565b905080614103575090919050565b8061410c614827565b61411690856150a1565b6111699190614f86565b600081831061412f5781611169565b5090919050565b6001600160a01b0382166000908152600b6020526040902060068101548211156141a25760405162461bcd60e51b815260206004820152601e60248201527f5f7265706f72744c6f73733a20746f74616c44656274203e3d206c6f737300006044820152606401610a9b565b818160080160008282546141b69190614f6e565b92505081905550818160060160008282546141d191906150c0565b9250508190555081601460008282546141ea91906150c0565b9091555050505050565b6001600160a01b0382166142545760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a9b565b6001600160a01b038216600090815260026020526040902054818110156142c85760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a9b565b6001600160a01b03831660009081526002602052604081208383039055600480548492906142f79084906150c0565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6040516001600160a01b03831660248201526044810182905261280090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614843565b6001600160a01b0381166000908152600b602052604081206002015460138054919290916143d49084906150c0565b90915550506001600160a01b0381166000818152600b602052604080822060028101839055600101805460ff19169055517fc3445f0d5a9ec5b7494384e18eb737b20cc1f3ab475b478e10b8739e4cd436e59190a250565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381166000908152600b60205260408120816144a16004600a614ff5565b6144a96139e2565b83600201546144b891906150a1565b6144c29190614f86565b60068301549091508181116144dc57506000949350505050565b6144e682826150c0565b95945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526140e39085906323b872dd60e01b9060840161436e565b6000806145366004600a614ff5565b601a5461454390856150a1565b61454d9190614f86565b9050801561456d5760195461456b906001600160a01b0316826145e6565b505b61116981846150c0565b6000806012546015544261458b91906150c0565b61459591906150a1565b90506145a36012600a614ff5565b8110156145de576011546145b96012600a614ff5565b6145c382846150a1565b6145cd9190614f86565b6145d790826150c0565b9250505090565b600091505090565b60008060006145f460045490565b9050801561461f57614604614827565b61460e82866150a1565b6146189190614f86565b9150614623565b8391505b8161467b5760405162461bcd60e51b815260206004820152602260248201527f5f6973737565536861726573466f72416d6f756e743a20736861726573203d3d604482015261020360f41b6064820152608401610a9b565b6146858583614915565b509392505050565b6000600c82600581106146b057634e487b7160e01b600052603260045260246000fd5b0160009054906101000a90046001600160a01b03166001600160a01b031663efbb5cb06040518163ffffffff1660e01b815260040160206040518083038186803b1580156146fd57600080fd5b505afa158015614711573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b9190614e01565b600080600b6000600c856005811061475d57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031681526020810191909152604001600020600601549392505050565b6001600160a01b0382166000908152600b602052604081206002015460138054919290916147b29084906150c0565b90915550506001600160a01b0382166000908152600b60205260408120600201829055601380548392906147e7908490614f6e565b90915550506040518181526001600160a01b038316907f20026fcfbe8b4c825d73835e062d785add204e5b6dc6c7672c82edfb48195e8190602001611a6d565b6000614831614577565b6148396139e2565b6109c391906150c0565b6000614898826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166149f49092919063ffffffff16565b80519091501561280057808060200190518101906148b69190614dcd565b6128005760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a9b565b6001600160a01b03821661496b5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a9b565b806004600082825461497d9190614f6e565b90915550506001600160a01b038216600090815260026020526040812080548392906149aa908490614f6e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6060614a038484600085614a0b565b949350505050565b606082471015614a6c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a9b565b843b614aba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a9b565b600080866001600160a01b03168587604051614ad69190614e65565b60006040518083038185875af1925050503d8060008114614b13576040519150601f19603f3d011682016040523d82523d6000602084013e614b18565b606091505b5091509150614b28828286614b33565b979650505050505050565b60608315614b42575081611169565b825115614b525782518084602001fd5b8160405162461bcd60e51b8152600401610a9b9190614ecf565b600060208284031215614b7d578081fd5b81356111698161517f565b600060208284031215614b99578081fd5b81516111698161517f565b60008060408385031215614bb6578081fd5b8235614bc18161517f565b91506020830135614bd18161517f565b809150509250929050565b600080600060608486031215614bf0578081fd5b8335614bfb8161517f565b92506020840135614c0b8161517f565b929592945050506040919091013590565b60008060408385031215614c2e578182fd5b8235614c398161517f565b946020939093013593505050565b60008060008060808587031215614c5c578081fd5b8435614c678161517f565b966020860135965060408601359560600135945092505050565b60008060208385031215614c93578182fd5b823567ffffffffffffffff80821115614caa578384fd5b818501915085601f830112614cbd578384fd5b813581811115614ccb578485fd5b8660208260051b8501011115614cdf578485fd5b60209290920196919550909350505050565b60006020808385031215614d03578182fd5b823567ffffffffffffffff80821115614d1a578384fd5b818501915085601f830112614d2d578384fd5b813581811115614d3f57614d3f615169565b8060051b604051601f19603f83011681018181108582111715614d6457614d64615169565b604052828152858101935084860182860187018a1015614d82578788fd5b8795505b83861015614da4578035855260019590950194938601938601614d86565b5098975050505050505050565b600060208284031215614dc2578081fd5b813561116981615194565b600060208284031215614dde578081fd5b815161116981615194565b600060208284031215614dfa578081fd5b5035919050565b600060208284031215614e12578081fd5b5051919050565b60008060408385031215614e2b578182fd5b50508035926020909101359150565b600080600060608486031215614e4e578283fd5b505081359360208301359350604090920135919050565b60008251614e778184602087016150d7565b9190910192915050565b60208082528181018390526000908460408401835b86811015614ec4578235614ea98161517f565b6001600160a01b031682529183019190830190600101614e96565b509695505050505050565b6020815260008251806020840152614eee8160408501602087016150d7565b601f01601f19169190910160400192915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60008219821115614f8157614f81615153565b500190565b600082614fa157634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115614fe1578160001904821115614fc757614fc7615153565b80851615614fd457918102915b93841c9390800290614fab565b509250929050565b60006111698383615000565b600061116960ff8416835b60008261500f57506001610a6b565b8161501c57506000610a6b565b8160018114615032576002811461503c57615058565b6001915050610a6b565b60ff84111561504d5761504d615153565b50506001821b610a6b565b5060208310610133831016604e8410600b841016171561507b575081810a610a6b565b6150858383614fa6565b806000190482111561509957615099615153565b029392505050565b60008160001904831182151516156150bb576150bb615153565b500290565b6000828210156150d2576150d2615153565b500390565b60005b838110156150f25781810151838201526020016150da565b838111156140e35750506000910152565b600181811c9082168061511757607f821691505b60208210811415612ed757634e487b7160e01b600052602260045260246000fd5b600060001982141561514c5761514c615153565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461337157600080fd5b801515811461337157600080fdfea264697066735822122035c6218c3f9cc9df84a695534baddcf673de8e3cf3a702469e6420e67ae7e07764736f6c63430008040033000000000000000000000000d586e7f844cea2f87f50152665bcbc2c279d8d70000000000000000000000000000000000000000000000000000000000000138800000000000000000000000060861b5afdf4b6e449dd194a6b54d6a64dfe2d81
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d586e7f844cea2f87f50152665bcbc2c279d8d70000000000000000000000000000000000000000000000000000000000000138800000000000000000000000060861b5afdf4b6e449dd194a6b54d6a64dfe2d81
-----Decoded View---------------
Arg [0] : _token (address): 0xd586e7f844cea2f87f50152665bcbc2c279d8d70
Arg [1] : _baseAllowance (uint256): 5000
Arg [2] : _bouncer (address): 0x60861b5afdf4b6e449dd194a6b54d6a64dfe2d81
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000d586e7f844cea2f87f50152665bcbc2c279d8d70
Arg [1] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [2] : 00000000000000000000000060861b5afdf4b6e449dd194a6b54d6a64dfe2d81
Deployed ByteCode Sourcemap
1884:35638:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3228:23;;;;;;;;;31167:25:14;;;31155:2;31140:18;3228:23:0;;;;;;;;8353:102;;;:::i;2084:98:7:-;;;:::i;:::-;;;;;;;:::i;4181:166::-;;;;;;:::i;:::-;;:::i;:::-;;;7587:14:14;;7580:22;7562:41;;7550:2;7535:18;4181:166:7;7517:92:14;2718:48:0;;;;;;:::i;:::-;;;;;;;;;;;;;;16262:1475;;;;;;:::i;:::-;;:::i;:::-;;23519:111;;;:::i;11591:672::-;;;;;;:::i;:::-;;:::i;6220:130::-;;;;;;:::i;:::-;;:::i;3172:106:7:-;3259:12;;3172:106;;4814:478;;;;;;:::i;:::-;;:::i;6011:97:0:-;;;33545:4:14;6091:9:0;33533:17:14;33515:36;;33503:2;33488:18;6011:97:0;33470:87:14;6446:138:0;;;;;;:::i;:::-;;:::i;3107:25::-;;;;;;5687:212:7;;;;;;:::i;:::-;;:::i;2802:52:0:-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31568:25:14;;;31636:14;;31629:22;31624:2;31609:18;;31602:50;31668:18;;;31661:34;;;;31726:2;31711:18;;31704:34;;;;31769:3;31754:19;;31747:35;;;;31813:3;31798:19;;31791:35;31857:3;31842:19;;31835:35;31901:3;31886:19;;31879:35;31945:3;31930:19;;31923:35;31555:3;31540:19;2802:52:0;31522:442:14;35627:110:0;;;:::i;27175:112::-;27259:10;27222:7;27248:22;;;:10;:22;;;;;:32;;;27175:112;;28146:3148;;;;;;:::i;:::-;;:::i;2948:27::-;;;;;;18699:583;;;;;;:::i;:::-;;:::i;8156:145::-;;;;;;:::i;:::-;;:::i;11012:286::-;;;;;;:::i;:::-;;:::i;2981:28::-;;;;;;19522:1686;;;;;;:::i;:::-;;:::i;3336:125:7:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3436:18:7;3410:7;3436:18;;;:9;:18;;;;;;;3336:125;1605:92:5;;;:::i;2027:46:0:-;;2072:1;2027:46;;606:199:2;;;;;;:::i;:::-;;:::i;6959:178:0:-;;;;;;:::i;:::-;;:::i;973:85:5:-;1019:7;1045:6;-1:-1:-1;;;;;1045:6:5;973:85;;;-1:-1:-1;;;;;6006:32:14;;;5988:51;;5976:2;5961:18;973:85:5;5943:102:14;2295::7;;;:::i;8522:112:0:-;;;:::i;149:41:2:-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;3200:22:0;;;;;-1:-1:-1;;;;;3200:22:0;;;21302:200;;;:::i;32636:2370::-;;;;;;:::i;:::-;;:::i;6386:405:7:-;;;;;;:::i;:::-;;:::i;3664:172::-;;;;;;:::i;:::-;;:::i;13373:499:0:-;;;;;;:::i;:::-;;:::i;22661:522::-;;;;;;:::i;:::-;;:::i;9019:1162::-;;;;;;:::i;:::-;;:::i;27468:258::-;;;;;;:::i;:::-;;:::i;7251:145::-;;;;;;:::i;:::-;;:::i;26626:155::-;;;;;;:::i;:::-;;:::i;26926:111::-;;;:::i;3076:25::-;;;;;;2650:39;;;;;3172:22;;;;;-1:-1:-1;;;;;3172:22:0;;;2861:50;;;;;;:::i;:::-;;:::i;2605:39::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;12992:282;;;:::i;3016:24::-;;;;;;23300:155;;;;;;:::i;:::-;;:::i;3894:149:7:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4009:18:7;;;3983:7;4009:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3894:149;2546:28:0;;;;;;;;;8734:182;;;;;;:::i;:::-;;:::i;412:188:2:-;;;;;;:::i;:::-;;:::i;14347:500:0:-;;;;;;:::i;:::-;;:::i;17934:583::-;;;;;;:::i;:::-;;:::i;6700:130::-;;;;;;:::i;:::-;;:::i;3138:27::-;;;;;;1846:189:5;;;;;;:::i;:::-;;:::i;15090:827:0:-;;;;;;:::i;:::-;;:::i;21620:917::-;;;;;;:::i;:::-;;:::i;7568:473::-;;;;;;:::i;:::-;;:::i;2152:39::-;;;;;3046:24;;;;;;8353:102;8408:7;8434:14;:12;:14::i;:::-;8427:21;;8353:102;:::o;2084:98:7:-;2138:13;2170:5;2163:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2084:98;:::o;4181:166::-;4264:4;4280:39;666:10:12;4303:7:7;4312:6;4280:8;:39::i;:::-;-1:-1:-1;4336:4:7;4181:166;;;;;:::o;16262:1475:0:-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;;;;;;;;;2119:1:0::1;16466:15;16482:22;16503:1;2072;16482:22;:::i;:::-;16466:39;;;;;-1:-1:-1::0;;;16466:39:0::1;;;;;;;;;;::::0;-1:-1:-1;;;;;16466:39:0::1;:55;16445:135;;;::::0;-1:-1:-1;;;16445:135:0;;20810:2:14;16445:135:0::1;::::0;::::1;20792:21:14::0;20849:2;20829:18;;;20822:30;20888:34;20868:18;;;20861:62;-1:-1:-1;;;20939:18:14;;;20932:31;20980:19;;16445:135:0::1;20782:223:14::0;16445:135:0::1;-1:-1:-1::0;;;;;16598:25:0;::::1;16590:62;;;::::0;-1:-1:-1;;;16590:62:0;;26371:2:14;16590:62:0::1;::::0;::::1;26353:21:14::0;26410:2;26390:18;;;26383:30;26449:26;26429:18;;;26422:54;26493:18;;16590:62:0::1;26343:174:14::0;16590:62:0::1;-1:-1:-1::0;;;;;16671:21:0;::::1;;::::0;;;:10:::1;:21;::::0;;;;:28:::1;;::::0;::::1;;16670:29;16662:65;;;::::0;-1:-1:-1;;;16662:65:0;;14344:2:14;16662:65:0::1;::::0;::::1;14326:21:14::0;14383:2;14363:18;;;14356:30;14422:25;14402:18;;;14395:53;14465:18;;16662:65:0::1;14316:173:14::0;16662:65:0::1;16785:9;-1:-1:-1::0;;;;;16775:26:0::1;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;16758:45:0::1;16766:4;-1:-1:-1::0;;;;;16758:45:0::1;;16737:111;;;::::0;-1:-1:-1;;;16737:111:0;;11200:2:14;16737:111:0::1;::::0;::::1;11182:21:14::0;11239:2;11219:18;;;11212:30;-1:-1:-1;;;11258:18:14;;;11251:49;11317:18;;16737:111:0::1;11172:169:14::0;16737:111:0::1;329:32:1;268:1;337:2;329:32;:::i;:::-;16891:10:0;16879:9;;:22;;;;:::i;:::-;:51;;16858:127;;;::::0;-1:-1:-1;;;16858:127:0;;21212:2:14;16858:127:0::1;::::0;::::1;21194:21:14::0;21251:2;21231:18;;;21224:30;21290:31;21270:18;;;21263:59;21339:18;;16858:127:0::1;21184:179:14::0;16858:127:0::1;17038:18;17016;:40;;16995:109;;;::::0;-1:-1:-1;;;16995:109:0;;23759:2:14;16995:109:0::1;::::0;::::1;23741:21:14::0;23798:2;23778:18;;;23771:30;-1:-1:-1;;;23817:18:14;;;23810:52;23879:18;;16995:109:0::1;23731:172:14::0;16995:109:0::1;-1:-1:-1::0;;;;;17149:21:0;::::1;17115:31;17149:21:::0;;;:10:::1;:21;::::0;;;;;;;;17202:15:::1;17180:37:::0;;;17245:4:::1;17227:15:::0;;::::1;:22:::0;;-1:-1:-1;;17227:22:0::1;::::0;;::::1;::::0;;17259:18:::1;::::0;::::1;:31:::0;;;17300:26:::1;::::0;::::1;:47:::0;;;17357:26:::1;::::0;::::1;:47:::0;;;17414:19:::1;::::0;::::1;:37:::0;17467:137;;32171:25:14;;;32212:18;;;32205:34;;;32255:18;;;32248:34;;;17149:21:0;;;17467:137:::1;::::0;32159:2:14;32144:18;17467:137:0::1;;;;;;;17628:10;17615:9;;:23;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;17685:9:0;;-1:-1:-1;17649:15:0::1;17665:16;:14;:16::i;:::-;17649:33;;;;;-1:-1:-1::0;;;17649:33:0::1;;;;;;;;;;:45:::0;;-1:-1:-1;;;;;;17649:45:0::1;-1:-1:-1::0;;;;;17649:45:0;;;::::1;::::0;;;::::1;::::0;;17704:26:::1;:24;:26::i;:::-;1255:1:5;16262:1475:0::0;;;;:::o;23519:111::-;23569:7;23595:28;23612:10;23595:16;:28::i;11591:672::-;1680:1:6;2259:7;;:19;;2251:63;;;;-1:-1:-1;;;2251:63:6;;;;;;;:::i;:::-;1680:1;2389:7;:18;358:10:2::1;348:21;::::0;;;:9:::1;:21;::::0;;;;;::::1;;340:48;;;::::0;-1:-1:-1;;;340:48:2;;24518:2:14;340:48:2::1;::::0;::::1;24500:21:14::0;24557:2;24537:18;;;24530:30;-1:-1:-1;;;24576:18:14;;;24569:44;24630:18;;340:48:2::1;24490:164:14::0;340:48:2::1;11723:16:0::2;:14;:16::i;:::-;11714:6;:25;11706:51;;;::::0;-1:-1:-1;;;11706:51:0;;29756:2:14;11706:51:0::2;::::0;::::2;29738:21:14::0;29795:2;29775:18;;;29768:30;-1:-1:-1;;;29814:18:14;;;29807:43;29867:18;;11706:51:0::2;29728:163:14::0;11706:51:0::2;11767:19;11799:15;11815:6;11799:23;;;;;-1:-1:-1::0;;;11799:23:0::2;;;;;;;;;;::::0;-1:-1:-1;;;;;11799:23:0::2;::::0;-1:-1:-1;11799:23:0::2;11856:14;:12;:14::i;:::-;11833:37;;11880:9;-1:-1:-1::0;;;;;11880:17:0::2;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;11909;11931:14;:12;:14::i;:::-;11909:36;;11955:9;11974:14:::0;12017:11:::2;12002:12;:26;11998:209;;;12053:26;12068:11:::0;12053:12;:26:::2;:::i;:::-;12044:35;;12100:4;12093:11;;11998:209;;;12144:26;12158:12:::0;12144:11;:26:::2;:::i;:::-;12135:35;;12191:5;12184:12;;11998:209;12221:35;::::0;;7807:14:14;;7800:22;7782:41;;7854:2;7839:18;;7832:34;;;12221:35:0::2;::::0;7755:18:14;12221:35:0::2;;;;;;;-1:-1:-1::0;;1637:1:6;2562:7;:22;-1:-1:-1;;;;11591:672:0:o;6220:130::-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;6287:7:0::1;:18:::0;;-1:-1:-1;;;;;;6287:18:0::1;-1:-1:-1::0;;;;;6287:18:0;::::1;::::0;;::::1;::::0;;;6320:23:::1;::::0;5988:51:14;;;6320:23:0::1;::::0;5976:2:14;5961:18;6320:23:0::1;;;;;;;;6220:130:::0;:::o;4814:478:7:-;4950:4;4966:36;4976:6;4984:9;4995:6;4966:9;:36::i;:::-;-1:-1:-1;;;;;5040:19:7;;5013:24;5040:19;;;:11;:19;;;;;;;;666:10:12;5040:33:7;;;;;;;;5091:26;;;;5083:79;;;;-1:-1:-1;;;5083:79:7;;21929:2:14;5083:79:7;;;21911:21:14;21968:2;21948:18;;;21941:30;22007:34;21987:18;;;21980:62;-1:-1:-1;;;22058:18:14;;;22051:38;22106:19;;5083:79:7;21901:230:14;5083:79:7;5196:57;5205:6;666:10:12;5246:6:7;5227:16;:25;5196:8;:57::i;:::-;5281:4;5274:11;;;4814:478;;;;;;:::o;6446:138:0:-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;6516:9:0::1;:19:::0;;-1:-1:-1;;6516:19:0::1;::::0;::::1;;::::0;;::::1;::::0;;;6550:27:::1;::::0;7562:41:14;;;6550:27:0::1;::::0;7550:2:14;7535:18;6550:27:0::1;7517:92:14::0;5687:212:7;666:10:12;5775:4:7;5823:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;5823:34:7;;;;;;;;;;5775:4;;5791:80;;5814:7;;5823:47;;5860:10;;5823:47;:::i;:::-;5791:8;:80::i;35627:110:0:-;35678:7;35704:26;35716:13;35720:9;35716:2;:13;:::i;:::-;35704:11;:26::i;28146:3148::-;28254:7;1680:1:6;2259:7;;:19;;2251:63;;;;-1:-1:-1;;;2251:63:6;;;;;;;:::i;:::-;1680:1;2389:7;:18;329:32:1::1;268:1;337:2;329:32;:::i;:::-;28298:8:0;:37;;28277:109;;;::::0;-1:-1:-1;;;28277:109:0;;26017:2:14;28277:109:0::1;::::0;::::1;25999:21:14::0;26056:2;26036:18;;;26029:30;26095:27;26075:18;;;26068:55;26140:18;;28277:109:0::1;25989:175:14::0;28277:109:0::1;28414:1;28404:7;:11;28396:46;;;::::0;-1:-1:-1;;;28396:46:0;;23408:2:14;28396:46:0::1;::::0;::::1;23390:21:14::0;23447:2;23427:18;;;23420:30;-1:-1:-1;;;23466:18:14;;;23459:52;23528:18;;28396:46:0::1;23380:172:14::0;28396:46:0::1;28485:10;28453:19;3436:18:7::0;;;:9;:18;;;;;;;-1:-1:-1;;28523:28:0;::::1;:86;;28602:7;28523:86;;;28576:10;3410:7:7::0;3436:18;;;:9;:18;;;;;;28566:21:0::1;28506:103;;28637:11;28627:6;:21;;28619:64;;;::::0;-1:-1:-1;;;28619:64:0;;17050:2:14;28619:64:0::1;::::0;::::1;17032:21:14::0;17089:2;17069:18;;;17062:30;17128:32;17108:18;;;17101:60;17178:18;;28619:64:0::1;17022:180:14::0;28619:64:0::1;28693:13;28709:19;28721:6;28709:11;:19::i;:::-;28905:31;::::0;-1:-1:-1;;;28905:31:0;;28930:4:::1;28905:31;::::0;::::1;5988:51:14::0;28693:35:0;;-1:-1:-1;28762:5:0::1;::::0;28739:13:::1;::::0;-1:-1:-1;;;;;28905:16:0;::::1;::::0;::::1;::::0;5961:18:14;;28905:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28897:5;:39;28893:1947;;;28952:64;::::0;;;;::::1;::::0;;;;-1:-1:-1;;29001:15:0::1;::::0;28952:64:::1;::::0;29001:15;28952:64;::::1;::::0;;-1:-1:-1;;;;;28952:64:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;29035:9;29030:1363;2072:1;29046;:22;29030:1363;;;29093:17;29113:11;29125:1;29113:14;;;;;-1:-1:-1::0;;;29113:14:0::1;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;;29149:25:0;::::1;29145:36;;29176:5;;;29145:36;29222:31;::::0;-1:-1:-1;;;29222:31:0;;29247:4:::1;29222:31;::::0;::::1;5988:51:14::0;29199:20:0::1;::::0;-1:-1:-1;;;;;29222:16:0;::::1;::::0;::::1;::::0;5961:18:14;;29222:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29199:54;;29342:12;29333:5;:21;29329:32;;29356:5;;;;29329:32;29379:20;29402;29410:12:::0;29402:5;:20:::1;:::i;:::-;-1:-1:-1::0;;;;;29480:21:0;::::1;29441:36;29480:21:::0;;;:10:::1;:21;::::0;;;;29557:23:::1;::::0;::::1;::::0;29379:43;;-1:-1:-1;29480:21:0;29534:47:::1;::::0;29379:43;;29534:8:::1;:47::i;:::-;29519:62:::0;-1:-1:-1;29679:17:0;29675:72:::1;;29720:8;;;;;;29675:72;29780:43;::::0;-1:-1:-1;;;29780:43:0;;::::1;::::0;::::1;31167:25:14::0;;;29765:12:0::1;::::0;-1:-1:-1;;;;;29780:29:0;::::1;::::0;::::1;::::0;31140:18:14;;29780:43:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29910:31;::::0;-1:-1:-1;;;29910:31:0;;29935:4:::1;29910:31;::::0;::::1;5988:51:14::0;29765:58:0;;-1:-1:-1;29890:17:0::1;::::0;29964:12;;-1:-1:-1;;;;;29910:16:0;::::1;::::0;::::1;::::0;5961:18:14;;29910:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:66;;;;:::i;:::-;29890:86:::0;-1:-1:-1;30041:8:0;;30037:175:::1;;30081:12;30089:4:::0;30081:5;:12:::1;:::i;:::-;30073:20:::0;-1:-1:-1;30127:16:0::1;30139:4:::0;30127:9;:16:::1;:::i;:::-;30115:28;;30165;30177:9;30188:4;30165:11;:28::i;:::-;30329:9;30302:13;:23;;;:36;;;;;;;:::i;:::-;;;;;;;;30369:9;30356;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;;29030:1363:0::1;29070:3:::0;::::1;::::0;::::1;:::i;:::-;;;;29030:1363;;;-1:-1:-1::0;30429:31:0::1;::::0;-1:-1:-1;;;30429:31:0;;30454:4:::1;30429:31;::::0;::::1;5988:51:14::0;30406:20:0::1;::::0;-1:-1:-1;;;;;30429:16:0;::::1;::::0;::::1;::::0;5961:18:14;;30429:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30406:54;;30486:12;30478:5;:20;30474:141;;;30550:12:::0;30530:17:::1;30542:5:::0;30530:9;:17:::1;:::i;:::-;:32;;;;:::i;:::-;30518:44;;30588:12;30580:20;;30474:141;329:32:1;268:1;337:2;329:32;:::i;:::-;30700:17:0;30708:9:::0;30700:5;:17:::1;:::i;:::-;30688:30;::::0;:8;:30:::1;:::i;:::-;30687:84;;;;:::i;:::-;30654:9;:117;;30629:200;;;::::0;-1:-1:-1;;;30629:200:0;;12358:2:14;30629:200:0::1;::::0;::::1;12340:21:14::0;12397:2;12377:18;;;12370:30;12436:26;12416:18;;;12409:54;12480:18;;30629:200:0::1;12330:174:14::0;30629:200:0::1;28893:1947;;;30849:25;30855:10;30867:6;30849:5;:25::i;:::-;30884:38;-1:-1:-1::0;;;;;30884:19:0;::::1;30904:10;30916:5:::0;30884:19:::1;:38::i;:::-;31039:9;::::0;31003:18:::1;::::0;31039:9:::1;;31035:152;;;31106:17;31114:9:::0;31106:5;:17:::1;:::i;:::-;31091:10;31077:25;::::0;;;:13:::1;:25;::::0;;;;;:47:::1;::::0;;::::1;:::i;:::-;31152:10;31138:25;::::0;;;:13:::1;:25;::::0;;;;:38;;;31064:60;-1:-1:-1;31035:152:0::1;31202:63;::::0;;32524:25:14;;;32580:2;32565:18;;32558:34;;;32608:18;;;32601:34;;;32666:2;32651:18;;32644:34;;;31216:10:0::1;::::0;31202:63:::1;::::0;32511:3:14;32496:19;31202:63:0::1;;;;;;;-1:-1:-1::0;;1637:1:6;2562:7;:22;-1:-1:-1;31282:5:0;28146:3148;-1:-1:-1;;;;;28146:3148:0:o;18699:583::-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;-1:-1:-1;;;;;18859:21:0;::::1;18894:1;18859:21:::0;;;:10:::1;:21;::::0;;;;:32;18838:126:::1;;;::::0;-1:-1:-1;;;18838:126:0;;16279:2:14;18838:126:0::1;::::0;::::1;16261:21:14::0;16318:2;16298:18;;;16291:30;16357:34;16337:18;;;16330:62;-1:-1:-1;;;16408:18:14;;;16401:41;16459:19;;18838:126:0::1;16251:233:14::0;18838:126:0::1;-1:-1:-1::0;;;;;18995:21:0;::::1;;::::0;;;:10:::1;:21;::::0;;;;:39:::1;;::::0;:61;-1:-1:-1;18995:61:0::1;18974:150;;;::::0;-1:-1:-1;;;18974:150:0;;14696:2:14;18974:150:0::1;::::0;::::1;14678:21:14::0;14735:2;14715:18;;;14708:30;14774:34;14754:18;;;14747:62;-1:-1:-1;;;14825:18:14;;;14818:40;14875:19;;18974:150:0::1;14668:232:14::0;18974:150:0::1;-1:-1:-1::0;;;;;19135:21:0;::::1;;::::0;;;:10:::1;:21;::::0;;;;;;:39:::1;;:60:::0;;;19210:65;::::1;::::0;::::1;::::0;19177:18;31167:25:14;;31155:2;31140:18;;31122:76;19210:65:0::1;;;;;;;;18699:583:::0;;:::o;8156:145::-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;8228:13:0::1;:23:::0;;;8266:28:::1;::::0;31167:25:14;;;8266:28:0::1;::::0;31155:2:14;31140:18;8266:28:0::1;31122:76:14::0;11012:286:0;11143:4;11180:16;:14;:16::i;:::-;11171:6;:25;11163:51;;;;-1:-1:-1;;;11163:51:0;;29756:2:14;11163:51:0;;;29738:21:14;29795:2;29775:18;;;29768:30;-1:-1:-1;;;29814:18:14;;;29807:43;29867:18;;11163:51:0;29728:163:14;11163:51:0;11241:15;11257:6;11241:23;;;;;-1:-1:-1;;;11241:23:0;;;;;;;;;;;11231:60;;-1:-1:-1;;;11231:60:0;;;;;31167:25:14;;;-1:-1:-1;;;;;11241:23:0;;;;11231:49;;31140:18:14;;11231:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;19522:1686::-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;-1:-1:-1;;;;;19646:27:0;::::1;19638:59;;;::::0;-1:-1:-1;;;19638:59:0;;25263:2:14;19638:59:0::1;::::0;::::1;25245:21:14::0;25302:2;25282:18;;;25275:30;-1:-1:-1;;;25321:18:14;;;25314:49;25380:18;;19638:59:0::1;25235:169:14::0;19638:59:0::1;-1:-1:-1::0;;;;;19728:23:0;::::1;19765:1;19728:23:::0;;;:10:::1;:23;::::0;;;;:34;19707:123:::1;;;::::0;-1:-1:-1;;;19707:123:0;;8467:2:14;19707:123:0::1;::::0;::::1;8449:21:14::0;8506:2;8486:18;;;8479:30;8545:34;8525:18;;;8518:62;-1:-1:-1;;;8596:18:14;;;8589:36;8642:19;;19707:123:0::1;8439:228:14::0;19707:123:0::1;-1:-1:-1::0;;;;;19861:23:0;::::1;;::::0;;;:10:::1;:23;::::0;;;;:30:::1;;::::0;::::1;;19840:112;;;::::0;-1:-1:-1;;;19840:112:0;;20046:2:14;19840:112:0::1;::::0;::::1;20028:21:14::0;20085:2;20065:18;;;20058:30;20124:34;20104:18;;;20097:62;-1:-1:-1;;;20175:18:14;;;20168:33;20218:19;;19840:112:0::1;20018:225:14::0;19840:112:0::1;-1:-1:-1::0;;;;;19983:23:0;::::1;;::::0;;;:10:::1;:23;::::0;;;;:34;:39;19962:123:::1;;;::::0;-1:-1:-1;;;19962:123:0;;9630:2:14;19962:123:0::1;::::0;::::1;9612:21:14::0;9669:2;9649:18;;;9642:30;9708:34;9688:18;;;9681:62;-1:-1:-1;;;9759:18:14;;;9752:35;9804:19;;19962:123:0::1;9602:227:14::0;19962:123:0::1;-1:-1:-1::0;;;;;20131:23:0;::::1;20096:32;20131:23:::0;;;:10:::1;:23;::::0;;;;20178:19:::1;::::0;::::1;::::0;20165:9:::1;:32:::0;;20131:23;;20178:19;;20165:9;;20096:32;20165::::1;::::0;20178:19;;20165:32:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;20242:23:0;;::::1;20208:31;20242:23:::0;;;:10:::1;:23;::::0;;;;;20297:15:::1;20275:37:::0;;20340:4:::1;20322:15:::0;;::::1;:22:::0;;-1:-1:-1;;20322:22:0::1;::::0;;::::1;::::0;;20375:19:::1;::::0;;::::1;::::0;20354:18;;::::1;:40:::0;20433:27:::1;::::0;;::::1;::::0;20404:26;;::::1;:56:::0;20499:27:::1;::::0;;::::1;::::0;20470:26;;::::1;:56:::0;20558:20:::1;::::0;;::::1;::::0;20536:19;;::::1;:42:::0;20609:19:::1;20588:18:::0;::::1;20638:22:::0;;;20670:18:::1;::::0;::::1;:22:::0;;;20702:18:::1;::::0;::::1;:22:::0;;;;20735:43;;-1:-1:-1;;;20735:43:0;;;;::::1;5988:51:14::0;;;;20242:23:0;;20735:30;::::1;::::0;::::1;::::0;5961:18:14;;20735:43:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;20811:1:0::1;20789:19;::::0;::::1;:23:::0;;;20822:27:::1;::::0;::::1;:31:::0;;;20863:27:::1;::::0;::::1;:31:::0;;;20910:45:::1;::::0;-1:-1:-1;;;;;20910:45:0;;::::1;::::0;-1:-1:-1;20910:45:0;::::1;::::0;-1:-1:-1;20910:45:0::1;::::0;20811:1;20910:45:::1;20966:28;20982:11;20966:15;:28::i;:::-;21010:9;21005:197;2072:1;21021;:22;21005:197;;;21090:11;-1:-1:-1::0;;;;;21068:33:0::1;:15;21084:1;21068:18;;;;;-1:-1:-1::0;;;21068:18:0::1;;;;;;;;;;::::0;-1:-1:-1;;;;;21068:18:0::1;:33;21064:128;;;21142:11;21121:15;21137:1;21121:18;;;;;-1:-1:-1::0;;;21121:18:0::1;;;;;;;;;;:32:::0;;-1:-1:-1;;;;;;21121:32:0::1;-1:-1:-1::0;;;;;21121:32:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;21171:7:0::1;::::0;-1:-1:-1;;21171:7:0::1;21064:128;21045:3:::0;::::1;::::0;::::1;:::i;:::-;;;;21005:197;;1255:1:5;19522:1686:0::0;;:::o;1605:92:5:-;1019:7;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;1669:21:::1;1687:1;1669:9;:21::i;:::-;1605:92::o:0;606:199:2:-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;-1:-1:-1;;;;;686:18:2;::::1;678:44;;;::::0;-1:-1:-1;;;678:44:2;;29054:2:14;678:44:2::1;::::0;::::1;29036:21:14::0;29093:2;29073:18;;;29066:30;-1:-1:-1;;;29112:18:14;;;29105:43;29165:18;;678:44:2::1;29026:163:14::0;678:44:2::1;-1:-1:-1::0;;;;;732:15:2;::::1;750:5;732:15:::0;;;:9:::1;:15;::::0;;;;;:23;;-1:-1:-1;;732:23:2::1;::::0;;770:28;::::1;::::0;750:5;770:28:::1;606:199:::0;:::o;6959:178:0:-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;7038:4:0::1;7031;:11;7023:47;;;::::0;-1:-1:-1;;;7023:47:0;;8874:2:14;7023:47:0::1;::::0;::::1;8856:21:14::0;8913:2;8893:18;;;8886:30;8952:25;8932:18;;;8925:53;8995:18;;7023:47:0::1;8846:173:14::0;7023:47:0::1;7080:8;:15:::0;;;7110:20:::1;::::0;31167:25:14;;;7110:20:0::1;::::0;31155:2:14;31140:18;7110:20:0::1;31122:76:14::0;2295:102:7;2351:13;2383:7;2376:14;;;;;:::i;8522:112:0:-;8585:7;8611:16;:14;:16::i;21302:200::-;21379:10;21368:22;;;;:10;:22;;;;;:29;;;;;21347:111;;;;-1:-1:-1;;;21347:111:0;;19642:2:14;21347:111:0;;;19624:21:14;19681:2;19661:18;;;19654:30;19720:34;19700:18;;;19693:62;-1:-1:-1;;;19771:18:14;;;19764:33;19814:19;;21347:111:0;19614:225:14;21347:111:0;21468:27;21484:10;21468:15;:27::i;32636:2370::-;32817:10;32752:7;32806:22;;;:10;:22;;;;;32846:20;;32838:55;;;;-1:-1:-1;;;32838:55:0;;18883:2:14;32838:55:0;;;18865:21:14;18922:2;18902:18;;;18895:30;-1:-1:-1;;;18941:18:14;;;18934:48;18999:18;;32838:55:0;18855:168:14;32838:55:0;32926:5;32995:20;33003:12;32995:5;:20;:::i;:::-;32963:28;;-1:-1:-1;;;32963:28:0;;32980:10;32963:28;;;5988:51:14;-1:-1:-1;;;;;32963:16:0;;;;;5961:18:14;;32963:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;32942:147;;;;-1:-1:-1;;;32942:147:0;;18112:2:14;32942:147:0;;;18094:21:14;18151:2;18131:18;;;18124:30;18190:34;18170:18;;;18163:62;-1:-1:-1;;;18241:18:14;;;18234:46;18297:19;;32942:147:0;18084:238:14;32942:147:0;33104:9;;33100:70;;33129:30;33141:10;33153:5;33129:11;:30::i;:::-;33224:5;33202:9;:19;;;:27;;;;:::i;:::-;33180:19;;;:49;33240:12;33255:28;33272:10;33255:16;:28::i;:::-;33240:43;;33293:19;33315:28;33324:12;33338:4;33315:8;:28::i;:::-;33293:50;-1:-1:-1;33358:15:0;;33354:172;;33433:11;33411:9;:19;;;:33;;;;:::i;:::-;33389:9;:19;;:55;;;;33471:11;33458:9;;:24;;;;;;;:::i;:::-;;;;-1:-1:-1;33496:19:0;;-1:-1:-1;33504:11:0;33496:19;;:::i;:::-;;;33354:172;33536:14;33553:28;33570:10;33553:16;:28::i;:::-;33536:45;-1:-1:-1;33596:10:0;;33592:103;;33645:6;33622:9;:19;;;:29;;;;;;;:::i;:::-;;;;;;;;33678:6;33665:9;;:19;;;;;;;:::i;:::-;;;;-1:-1:-1;;33592:103:0;33705:22;33730:19;33738:11;33730:5;:19;:::i;:::-;33705:44;;33781:6;33764:14;:23;33760:307;;;33803:56;33823:10;33835:23;33844:14;33835:6;:23;:::i;:::-;-1:-1:-1;;;;;33803:19:0;;;:56;:19;:56::i;:::-;33760:307;;;33897:6;33880:14;:23;33876:191;;;33919:137;33960:10;33996:4;34019:23;34036:6;34019:14;:23;:::i;:::-;-1:-1:-1;;;;;33919:23:0;;;:137;;:23;:137::i;:::-;34225:30;34297:16;34307:5;34297:9;:16::i;:::-;34258:24;:22;:24::i;:::-;:55;;;;:::i;:::-;34225:88;;34352:5;34327:22;:30;34323:153;;;34388:30;34413:5;34388:22;:30;:::i;:::-;34373:12;:45;34323:153;;;34464:1;34449:12;:16;34323:153;34499:15;34486:10;:28;;;;34547:10;;34524:9;:20;;:33;;;;34606:10;-1:-1:-1;;;;;34573:268:0;;34630:5;34649;34668:11;34693:9;:19;;;34726:9;:19;;;34759:9;:19;;;34792:6;34812:9;:19;;;34573:268;;;;;;;;;;;;33032:25:14;;;33088:2;33073:18;;33066:34;;;;33131:2;33116:18;;33109:34;;;;33174:2;33159:18;;33152:34;;;;33217:3;33202:19;;33195:35;33261:3;33246:19;;33239:35;33305:3;33290:19;;33283:35;33349:3;33334:19;;33327:35;33019:3;33004:19;;32986:382;34573:268:0;;;;;;;;34856:19;;;;34852:148;;34913:10;-1:-1:-1;;;;;34903:42:0;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34896:51;;;;;;;;;;;34852:148;34985:4;34978:11;;;;;;;;;;;6386:405:7;666:10:12;6479:4:7;6522:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;6522:34:7;;;;;;;;;;6574:35;;;;6566:85;;;;-1:-1:-1;;;6566:85:7;;30098:2:14;6566:85:7;;;30080:21:14;30137:2;30117:18;;;30110:30;30176:34;30156:18;;;30149:62;-1:-1:-1;;;30227:18:14;;;30220:35;30272:19;;6566:85:7;30070:227:14;6566:85:7;6685:67;666:10:12;6708:7:7;6736:15;6717:16;:34;6685:8;:67::i;:::-;-1:-1:-1;6780:4:7;;6386:405;-1:-1:-1;;;6386:405:7:o;3664:172::-;3750:4;3766:42;666:10:12;3790:9:7;3801:6;3766:9;:42::i;13373:499:0:-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;2072:1:0::1;13478:35:::0;::::1;;13457:122;;;::::0;-1:-1:-1;;;13457:122:0;;10791:2:14;13457:122:0::1;::::0;::::1;10773:21:14::0;10830:2;10810:18;;;10803:30;10869:34;10849:18;;;10842:62;-1:-1:-1;;;10920:18:14;;;10913:38;10968:19;;13457:122:0::1;10763:230:14::0;13457:122:0::1;13594:9;13589:277;2072:1;13605;:22;13589:277;;;13652:18:::0;;::::1;13648:157;;13719:1;13690:15;13706:1;13690:18;;;;;-1:-1:-1::0;;;13690:18:0::1;;;;;;;;;;:31:::0;;-1:-1:-1;;;;;;13690:31:0::1;-1:-1:-1::0;;;;;13690:31:0;;;::::1;::::0;;;::::1;::::0;;13648:157:::1;;;13781:6;;13788:1;13781:9;;;;;-1:-1:-1::0;;;13781:9:0::1;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13760:15;13776:1;13760:18;;;;;-1:-1:-1::0;;;13760:18:0::1;;;;;;;;;;:30:::0;;-1:-1:-1;;;;;;13760:30:0::1;-1:-1:-1::0;;;;;13760:30:0;;;::::1;::::0;;;::::1;::::0;;13648:157:::1;13823:32;13848:6;;13823:32;;;;;;;:::i;:::-;;;;;;;;13629:3:::0;::::1;::::0;::::1;:::i;:::-;;;;13589:277;;;;13373:499:::0;;:::o;22661:522::-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;22753:10:0;:21;;:46;;-1:-1:-1;22788:10:0;22778:21;;;;:9;:21;;;;;;;;22753:46;22732:134;;;;-1:-1:-1;;;22732:134:0;;13122:2:14;22732:134:0;;;13104:21:14;13161:2;13141:18;;;13134:30;13200:34;13180:18;;;13173:62;-1:-1:-1;;;13251:18:14;;;13244:39;13300:19;;22732:134:0;13094:231:14;22732:134:0;22881:9;22876:301;2072:1;22892;:22;22876:301;;;22961:9;-1:-1:-1;;;;;22939:31:0;:15;22955:1;22939:18;;;;;-1:-1:-1;;;22939:18:0;;;;;;;;;;;-1:-1:-1;;;;;22939:18:0;:31;22935:232;;;2119:1;22990:15;23006:1;22990:18;;;;;-1:-1:-1;;;22990:18:0;;;;;;;;;;:33;;-1:-1:-1;;;;;;22990:33:0;-1:-1:-1;;;;;22990:33:0;;;;;;;;;;23041:26;:24;:26::i;:::-;23090:38;;-1:-1:-1;;;;;23090:38:0;;;;;;;;23146:7;22661:522;:::o;22935:232::-;22916:3;;;;:::i;:::-;;;;22876:301;;9019:1162;9084:7;1680:1:6;2259:7;;:19;;2251:63;;;;-1:-1:-1;;;2251:63:6;;;;;;;:::i;:::-;1680:1;2389:7;:18;9111:11:0;9103:45:::1;;;::::0;-1:-1:-1;;;9103:45:0;;17762:2:14;9103:45:0::1;::::0;::::1;17744:21:14::0;17801:2;17781:18;;;17774:30;-1:-1:-1;;;17820:18:14;;;17813:51;17881:18;;9103:45:0::1;17734:171:14::0;9103:45:0::1;9207:12;;9196:7;9179:14;:12;:14::i;:::-;:24;;;;:::i;:::-;:40;;9158:109;;;::::0;-1:-1:-1;;;9158:109:0;;15107:2:14;9158:109:0::1;::::0;::::1;15089:21:14::0;15146:2;15126:18;;;15119:30;-1:-1:-1;;;15165:18:14;;;15158:52;15227:18;;9158:109:0::1;15079:172:14::0;9158:109:0::1;9313:9;::::0;9277:18:::1;::::0;9313:9:::1;;9309:597;;;-1:-1:-1::0;9365:10:0::1;9351:25;::::0;;;:13:::1;:25;::::0;;;;;;;;9395:7:::1;:19:::0;;;;;;;::::1;;9390:454;;9453:14;9442:7;:25;;9434:61;;;::::0;-1:-1:-1;;;9434:61:0;;10439:2:14;9434:61:0::1;::::0;::::1;10421:21:14::0;10478:2;10458:18;;;10451:30;-1:-1:-1;;;10497:18:14;;;10490:53;10560:18;;9434:61:0::1;10411:173:14::0;9434:61:0::1;9526:24;9543:7:::0;9526:14:::1;:24;:::i;:::-;9576:10;9568:19;::::0;;;:7:::1;:19;::::0;;;;:26;;-1:-1:-1;;9568:26:0::1;9590:4;9568:26;::::0;;9513:37;-1:-1:-1;9390:454:0::1;;;9676:10;9662:25;::::0;;;:13:::1;:25;::::0;;;;;:36;-1:-1:-1;9662:36:0::1;9633:130;;;::::0;-1:-1:-1;;;9633:130:0;;10439:2:14;9633:130:0::1;::::0;::::1;10421:21:14::0;10478:2;10458:18;;;10451:30;-1:-1:-1;;;10497:18:14;;;10490:53;10560:18;;9633:130:0::1;10411:173:14::0;9633:130:0::1;9808:10;9794:25;::::0;;;:13:::1;:25;::::0;;;;;:35:::1;::::0;9822:7;;9794:35:::1;:::i;:::-;9781:48;;9390:454;9871:10;9857:25;::::0;;;:13:::1;:25;::::0;;;;:38;;;9309:597:::1;9916:14;9933:42;9955:10;9967:7;9933:21;:42::i;:::-;9916:59:::0;-1:-1:-1;10009:5:0::1;10025:59;-1:-1:-1::0;;;;;10025:23:0;::::1;10049:10;10069:4;10076:7:::0;10025:23:::1;:59::i;:::-;10100:51;::::0;;32171:25:14;;;32227:2;32212:18;;32205:34;;;32255:18;;;32248:34;;;10111:10:0::1;::::0;10100:51:::1;::::0;32159:2:14;32144:18;10100:51:0::1;;;;;;;-1:-1:-1::0;1637:1:6;2562:7;:22;10168:6:0;9019:1162;-1:-1:-1;;;9019:1162:0:o;27468:258::-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;27566:5:0::1;-1:-1:-1::0;;;;;27556:15:0::1;:6;-1:-1:-1::0;;;;;27556:15:0::1;;;27548:48;;;::::0;-1:-1:-1;;;27548:48:0;;27891:2:14;27548:48:0::1;::::0;::::1;27873:21:14::0;27930:2;27910:18;;;27903:30;-1:-1:-1;;;27949:18:14;;;27942:50;28009:18;;27548:48:0::1;27863:170:14::0;27548:48:0::1;27623:39;::::0;-1:-1:-1;;;27623:39:0;;27656:4:::1;27623:39;::::0;::::1;5988:51:14::0;27606:14:0::1;::::0;-1:-1:-1;;;;;27623:24:0;::::1;::::0;::::1;::::0;5961:18:14;;27623:39:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27606:56:::0;-1:-1:-1;27672:47:0::1;-1:-1:-1::0;;;;;27672:27:0;::::1;27700:10:::0;27606:56;27672:27:::1;:47::i;7251:145::-:0;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;7324:12:0::1;:24:::0;;;7363:26:::1;::::0;31167:25:14;;;7363:26:0::1;::::0;31155:2:14;31140:18;7363:26:0::1;31122:76:14::0;26626:155:0;26717:7;26747:27;26764:9;26747:16;:27::i;26926:111::-;26976:7;27002:28;27019:10;27002:16;:28::i;2861:50::-;;;;;;;;;;;;;;-1:-1:-1;;;;;2861:50:0;;-1:-1:-1;2861:50:0;:::o;12992:282::-;13082:38;;-1:-1:-1;;;13082:38:0;;13114:4;13082:38;;;5988:51:14;13047:7:0;;;;-1:-1:-1;;;;;13089:5:0;13082:23;;;;5961:18:14;;13082:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13066:54;;13135:9;13130:116;13154:16;:14;:16::i;:::-;13150:1;:20;13130:116;;;13200:35;13233:1;13200:32;:35::i;:::-;13191:44;;;;:::i;:::-;;-1:-1:-1;13172:3:0;;;;:::i;:::-;;;;13130:116;;;-1:-1:-1;13262:5:0;12992:282;-1:-1:-1;12992:282:0:o;23300:155::-;23391:7;23421:27;23438:9;23421:16;:27::i;8734:182::-;8841:14;8878:31;8902:6;8878:23;:31::i;412:188:2:-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;-1:-1:-1;;;;;487:18:2;::::1;479:44;;;::::0;-1:-1:-1;;;479:44:2;;29054:2:14;479:44:2::1;::::0;::::1;29036:21:14::0;29093:2;29073:18;;;29066:30;-1:-1:-1;;;29112:18:14;;;29105:43;29165:18;;479:44:2::1;29026:163:14::0;479:44:2::1;-1:-1:-1::0;;;;;533:15:2;::::1;;::::0;;;551:4:::1;533:15;::::0;;;;;;;:22;;-1:-1:-1;;533:22:2::1;::::0;;::::1;::::0;;;570:23;::::1;::::0;533:15;570:23:::1;412:188:::0;:::o;14347:500:0:-;-1:-1:-1;;;;;14488:21:0;;;;;;:10;:21;;;;;:28;;;;;14480:62;;;;-1:-1:-1;;;14480:62:0;;23058:2:14;14480:62:0;;;23040:21:14;23097:2;23077:18;;;23070:30;-1:-1:-1;;;23116:18:14;;;23109:51;23177:18;;14480:62:0;23030:171:14;14480:62:0;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;14573:10:0;:21;;:46;;-1:-1:-1;14608:10:0;14598:21;;;;:9;:21;;;;;;;;14573:46;14552:117;;;;-1:-1:-1;;;14552:117:0;;17409:2:14;14552:117:0;;;17391:21:14;17448:2;17428:18;;;17421:30;17487:26;17467:18;;;17460:54;17531:18;;14552:117:0;17381:174:14;14552:117:0;14679:36;14693:9;14704:10;14679:13;:36::i;:::-;329:32:1;268:1;337:2;329:32;:::i;:::-;14746:9:0;;:38;;14725:115;;;;-1:-1:-1;;;14725:115:0;;30864:2:14;14725:115:0;;;30846:21:14;30903:2;30883:18;;;30876:30;30942:32;30922:18;;;30915:60;30992:18;;14725:115:0;30836:180:14;17934:583:0;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;-1:-1:-1;;;;;18094:21:0;::::1;18129:1;18094:21:::0;;;:10:::1;:21;::::0;;;;:32;18073:126:::1;;;::::0;-1:-1:-1;;;18073:126:0;;19230:2:14;18073:126:0::1;::::0;::::1;19212:21:14::0;19269:2;19249:18;;;19242:30;19308:34;19288:18;;;19281:62;-1:-1:-1;;;19359:18:14;;;19352:41;19410:19;;18073:126:0::1;19202:233:14::0;18073:126:0::1;-1:-1:-1::0;;;;;18230:21:0;::::1;;::::0;;;:10:::1;:21;::::0;;;;:39:::1;;::::0;:61;-1:-1:-1;18230:61:0::1;18209:150;;;::::0;-1:-1:-1;;;18209:150:0;;12711:2:14;18209:150:0::1;::::0;::::1;12693:21:14::0;12750:2;12730:18;;;12723:30;12789:34;12769:18;;;12762:62;-1:-1:-1;;;12840:18:14;;;12833:40;12890:19;;18209:150:0::1;12683:232:14::0;18209:150:0::1;-1:-1:-1::0;;;;;18370:21:0;::::1;;::::0;;;:10:::1;:21;::::0;;;;;;:39:::1;;:60:::0;;;18445:65;::::1;::::0;::::1;::::0;18412:18;31167:25:14;;31155:2;31140:18;;31122:76;6700:130:0;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;6767:7:0::1;:18:::0;;-1:-1:-1;;;;;;6767:18:0::1;-1:-1:-1::0;;;;;6767:18:0;::::1;::::0;;::::1;::::0;;;6800:23:::1;::::0;5988:51:14;;;6800:23:0::1;::::0;5976:2:14;5961:18;6800:23:0::1;5943:102:14::0;1846:189:5;1019:7;1045:6;-1:-1:-1;;;;;1045:6:5;666:10:12;1185:23:5;1177:68;;;;-1:-1:-1;;;1177:68:5;;;;;;;:::i;:::-;-1:-1:-1;;;;;1934:22:5;::::1;1926:73;;;::::0;-1:-1:-1;;;1926:73:5;;11548:2:14;1926:73:5::1;::::0;::::1;11530:21:14::0;11587:2;11567:18;;;11560:30;11626:34;11606:18;;;11599:62;-1:-1:-1;;;11677:18:14;;;11670:36;11723:19;;1926:73:5::1;11520:228:14::0;1926:73:5::1;2009:19;2019:8;2009:9;:19::i;:::-;1846:189:::0;:::o;15090:827:0:-;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;15191:10:0;:21;;:46;;-1:-1:-1;15226:10:0;15216:21;;;;:9;:21;;;;;;;;15191:46;15170:118;;;;-1:-1:-1;;;15170:118:0;;18529:2:14;15170:118:0;;;18511:21:14;18568:2;18548:18;;;18541:30;18607:27;18587:18;;;18580:55;18652:18;;15170:118:0;18501:175:14;15170:118:0;2072:1;15319:19;:26;:48;;15298:130;;;;-1:-1:-1;;;15298:130:0;;27487:2:14;15298:130:0;;;27469:21:14;27526:2;27506:18;;;27499:30;27565:34;27545:18;;;27538:62;-1:-1:-1;;;27616:18:14;;;27609:33;27659:19;;15298:130:0;27459:225:14;15298:130:0;15438:17;15465:14;15494:9;15489:296;2072:1;15505;:22;15489:296;;;15560:15;15576:1;15560:18;;;;;-1:-1:-1;;;15560:18:0;;;;;;;;;;;-1:-1:-1;;;;;15560:18:0;;-1:-1:-1;15596:23:0;15592:137;;15639:5;;15592:137;15692:19;15712:1;15692:22;;;;;;-1:-1:-1;;;15692:22:0;;;;;;;;;;;;;;;15683:31;;15742:32;15756:9;15767:6;15742:13;:32::i;:::-;15529:3;;;;:::i;:::-;;;;15489:296;;;-1:-1:-1;329:32:1;268:1;337:2;329:32;:::i;:::-;15815:9:0;;:38;;15794:116;;;;-1:-1:-1;;;15794:116:0;;20450:2:14;15794:116:0;;;20432:21:14;20489:2;20469:18;;;20462:30;20528:33;20508:18;;;20501:61;20579:18;;15794:116:0;20422:181:14;21620:917:0;1019:7:5;1045:6;-1:-1:-1;;;;;1045:6:5;21707:10:0;:21;;:46;;-1:-1:-1;21742:10:0;21732:21;;;;:9;:21;;;;;;;;21707:46;21686:129;;;;-1:-1:-1;;;21686:129:0;;13532:2:14;21686:129:0;;;13514:21:14;13571:2;13551:18;;;13544:30;13610:34;13590:18;;;13583:62;-1:-1:-1;;;13661:18:14;;;13654:34;13705:19;;21686:129:0;13504:226:14;21686:129:0;-1:-1:-1;;;;;21846:21:0;;21881:1;21846:21;;;:10;:21;;;;;:32;21825:113;;;;-1:-1:-1;;;21825:113:0;;22699:2:14;21825:113:0;;;22681:21:14;22738:2;22718:18;;;22711:30;22777:32;22757:18;;;22750:60;22827:18;;21825:113:0;22671:180:14;21825:113:0;2119:1;21969:15;21985:22;22006:1;2072;21985:22;:::i;:::-;21969:39;;;;;-1:-1:-1;;;21969:39:0;;;;;;;;;;;-1:-1:-1;;;;;21969:39:0;:55;21948:132;;;;-1:-1:-1;;;21948:132:0;;16691:2:14;21948:132:0;;;16673:21:14;16730:2;16710:18;;;16703:30;16769:32;16749:18;;;16742:60;16819:18;;21948:132:0;16663:180:14;21948:132:0;22095:9;22090:295;2072:1;22106;:22;22090:295;;;22149:16;22168:15;22184:1;22168:18;;;;;-1:-1:-1;;;22168:18:0;;;;;;;;;;;-1:-1:-1;;;;;22168:18:0;;-1:-1:-1;22204:24:0;22200:35;;22230:5;;;22200:35;22287:8;-1:-1:-1;;;;;22274:21:0;:9;-1:-1:-1;;;;;22274:21:0;;;22249:125;;;;-1:-1:-1;;;22249:125:0;;15865:2:14;22249:125:0;;;15847:21:14;15904:2;15884:18;;;15877:30;15943:34;15923:18;;;15916:62;-1:-1:-1;;;15994:18:14;;;15987:43;16047:19;;22249:125:0;15837:235:14;22249:125:0;-1:-1:-1;22130:3:0;;;;:::i;:::-;;;;22090:295;;;-1:-1:-1;22436:9:0;22394:15;22410:22;22431:1;2072;22410:22;:::i;:::-;22394:39;;;;;-1:-1:-1;;;22394:39:0;;;;;;;;;;:51;;-1:-1:-1;;;;;;22394:51:0;-1:-1:-1;;;;;22394:51:0;;;;;;;;;;22455:26;:24;:26::i;:::-;22496:34;;-1:-1:-1;;;;;22496:34:0;;;;;;;;21620:917;:::o;7568:473::-;7680:7;;-1:-1:-1;;;;;7680:7:0;7666:10;:21;7645:107;;;;-1:-1:-1;;;7645:107:0;;24110:2:14;7645:107:0;;;24092:21:14;24149:2;24129:18;;;24122:30;24188:34;24168:18;;;24161:62;-1:-1:-1;;;24239:18:14;;;24232:37;24286:19;;7645:107:0;24082:229:14;7645:107:0;-1:-1:-1;;;;;7767:14:0;;;;;;:7;:14;;;;;;;;7762:227;;7849:14;7832:13;7836:9;7832:2;:13;:::i;:::-;7821:25;;:7;:25;:::i;:::-;:42;;;;:::i;:::-;-1:-1:-1;;;;;7797:20:0;;;;;;:13;:20;;;;;:66;;:20;;;:66;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;7877:14:0;;;;;;:7;:14;;;;;:21;;-1:-1:-1;;7877:21:0;7894:4;7877:21;;;7762:227;;;7964:13;7968:9;7964:2;:13;:::i;:::-;7953:25;;:7;:25;:::i;:::-;-1:-1:-1;;;;;7929:20:0;;;;;;:13;:20;;;;;:49;;:20;;;:49;;;;;:::i;:::-;;;;-1:-1:-1;;7762:227:0;8003:31;;;-1:-1:-1;;;;;6622:32:14;;6604:51;;6686:2;6671:18;;6664:34;;;8003:31:0;;6577:18:14;8003:31:0;;;;;;;7568:473;;:::o;36880:129::-;36993:9;;36952:38;;-1:-1:-1;;;36952:38:0;;36984:4;36952:38;;;5988:51:14;36926:7:0;;36993:9;-1:-1:-1;;;;;36959:5:0;36952:23;;;;5961:18:14;;36952:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;;:::i;9962:370:7:-;-1:-1:-1;;;;;10093:19:7;;10085:68;;;;-1:-1:-1;;;10085:68:7;;26724:2:14;10085:68:7;;;26706:21:14;26763:2;26743:18;;;26736:30;26802:34;26782:18;;;26775:62;-1:-1:-1;;;26853:18:14;;;26846:34;26897:19;;10085:68:7;26696:226:14;10085:68:7;-1:-1:-1;;;;;10171:21:7;;10163:68;;;;-1:-1:-1;;;10163:68:7;;11955:2:14;10163:68:7;;;11937:21:14;11994:2;11974:18;;;11967:30;12033:34;12013:18;;;12006:62;-1:-1:-1;;;12084:18:14;;;12077:32;12126:19;;10163:68:7;11927:224:14;10163:68:7;-1:-1:-1;;;;;10242:18:7;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10293:32;;31167:25:14;;;10293:32:7;;31140:18:14;10293:32:7;;;;;;;9962:370;;;:::o;13942:257:0:-;13991:7;14015:9;14010:148;2072:1;14026;:22;14010:148;;;14103:1;14073:15;14089:1;14073:18;;;;;-1:-1:-1;;;14073:18:0;;;;;;;;;;;-1:-1:-1;;;;;14073:18:0;:32;14069:79;;;14132:1;13942:257;-1:-1:-1;13942:257:0:o;14069:79::-;14050:3;;;;:::i;:::-;;;;14010:148;;;;2072:1;14167:25;;13942:257;:::o;37097:423::-;37152:14;37181:9;37176:338;2072:1;37192;:22;37176:338;;;37235:16;37254:15;37270:1;37254:18;;;;;-1:-1:-1;;;37254:18:0;;;;;;;;;;;-1:-1:-1;;;;;37254:18:0;;-1:-1:-1;37290:24:0;37286:218;;37334:11;37344:1;37334:11;;:::i;:::-;;;37286:218;;;37370:10;;37366:138;;37430:8;37400:15;37416:10;37420:6;37416:1;:10;:::i;:::-;37400:27;;;;;-1:-1:-1;;;37400:27:0;;;;;;;;;;:38;;-1:-1:-1;;;;;;37400:38:0;-1:-1:-1;;;;;37400:38:0;;;;;;;;;;-1:-1:-1;37456:15:0;37472:1;37456:18;;;;;-1:-1:-1;;;37456:18:0;;;;;;;;;;:33;;-1:-1:-1;;;;;;37456:33:0;-1:-1:-1;;;;;37456:33:0;;;;;;;;;;37366:138;-1:-1:-1;37216:3:0;;;;:::i;:::-;;;;37176:338;;23948:1303;-1:-1:-1;;;;;24101:21:0;;24040:7;24101:21;;;:10;:21;;;;;;;;24063:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24040:7;24159:14;:12;:14::i;:::-;24132:41;-1:-1:-1;24183:22:0;329:32:1;268:1;337:2;329:32;:::i;:::-;24221:16:0;24209:9;;:28;;;;:::i;:::-;24208:70;;;;:::i;:::-;24313:9;;24183:95;;-1:-1:-1;24288:22:0;329:32:1;268:1;337:2;329:32;:::i;:::-;24399:16:0;24361:13;:23;;;:54;;;;:::i;:::-;24360:84;;;;:::i;:::-;24482:23;;;;24551:31;;;;24628;;;;24332:112;;-1:-1:-1;24482:23:0;;24693:5;24727:38;;;;;:86;;;24799:14;24781;:32;;24727:86;24710:147;;;-1:-1:-1;24845:1:0;;23948:1303;-1:-1:-1;;;;;;;;;;23948:1303:0:o;24710:147::-;24867:17;24887:37;24907:17;24887;:37;:::i;:::-;24867:57;-1:-1:-1;24947:52:0;24867:57;24967:31;24984:14;24967;:31;:::i;:::-;24947:8;:52::i;:::-;25042:31;;-1:-1:-1;;;25042:31:0;;25067:4;25042:31;;;5988:51:14;24935:64:0;;-1:-1:-1;25022:52:0;;24935:64;;-1:-1:-1;;;;;25042:16:0;;;;;5961:18:14;;25042:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;25022:52::-;25010:64;;25101:25;25089:9;:37;25085:160;;;-1:-1:-1;25149:1:0;;23948:1303;-1:-1:-1;;;;;;;;;;;23948:1303:0:o;25085:160::-;25188:46;25197:9;25208:25;25188:8;:46::i;:::-;25181:53;23948:1303;-1:-1:-1;;;;;;;;;;;;23948:1303:0:o;7265:713:7:-;-1:-1:-1;;;;;7400:20:7;;7392:70;;;;-1:-1:-1;;;7392:70:7;;25611:2:14;7392:70:7;;;25593:21:14;25650:2;25630:18;;;25623:30;25689:34;25669:18;;;25662:62;-1:-1:-1;;;25740:18:14;;;25733:35;25785:19;;7392:70:7;25583:227:14;7392:70:7;-1:-1:-1;;;;;7480:23:7;;7472:71;;;;-1:-1:-1;;;7472:71:7;;9226:2:14;7472:71:7;;;9208:21:14;9265:2;9245:18;;;9238:30;9304:34;9284:18;;;9277:62;-1:-1:-1;;;9355:18:14;;;9348:33;9398:19;;7472:71:7;9198:225:14;7472:71:7;-1:-1:-1;;;;;7636:17:7;;7612:21;7636:17;;;:9;:17;;;;;;7671:23;;;;7663:74;;;;-1:-1:-1;;;7663:74:7;;13937:2:14;7663:74:7;;;13919:21:14;13976:2;13956:18;;;13949:30;14015:34;13995:18;;;13988:62;-1:-1:-1;;;14066:18:14;;;14059:36;14112:19;;7663:74:7;13909:228:14;7663:74:7;-1:-1:-1;;;;;7771:17:7;;;;;;;:9;:17;;;;;;7791:22;;;7771:42;;7833:20;;;;;;;;:30;;7807:6;;7771:17;7833:30;;7807:6;;7833:30;:::i;:::-;;;;;;;;7896:9;-1:-1:-1;;;;;7879:35:7;7888:6;-1:-1:-1;;;;;7879:35:7;;7907:6;7879:35;;;;31167:25:14;;31155:2;31140:18;;31122:76;7879:35:7;;;;;;;;7925:46;7265:713;;;;:::o;31413:228:0:-;31474:7;31493:20;31516:13;3259:12:7;;;3172:106;31516:13:0;31493:36;-1:-1:-1;31543:17:0;31539:37;;-1:-1:-1;31569:7:0;;31413:228;-1:-1:-1;31413:228:0:o;31539:37::-;31621:12;31605;:10;:12::i;:::-;31595:22;;:7;:22;:::i;:::-;31594:39;;;;:::i;391:104:13:-;449:7;479:1;475;:5;:13;;487:1;475:13;;;-1:-1:-1;483:1:13;;391:104;-1:-1:-1;391:104:13:o;25407:452:0:-;-1:-1:-1;;;;;25515:21:0;;25481:31;25515:21;;;:10;:21;;;;;25623:18;;;;:27;-1:-1:-1;25623:27:0;25615:70;;;;-1:-1:-1;;;25615:70:0;;21570:2:14;25615:70:0;;;21552:21:14;21609:2;21589:18;;;21582:30;21648:32;21628:18;;;21621:60;21698:18;;25615:70:0;21542:180:14;25615:70:0;25782:5;25760:8;:18;;;:27;;;;;;;:::i;:::-;;;;;;;;25819:5;25797:8;:18;;;:27;;;;;;;:::i;:::-;;;;;;;;25847:5;25834:9;;:18;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;25407:452:0:o;8963:576:7:-;-1:-1:-1;;;;;9046:21:7;;9038:67;;;;-1:-1:-1;;;9038:67:7;;24861:2:14;9038:67:7;;;24843:21:14;24900:2;24880:18;;;24873:30;24939:34;24919:18;;;24912:62;-1:-1:-1;;;24990:18:14;;;24983:31;25031:19;;9038:67:7;24833:223:14;9038:67:7;-1:-1:-1;;;;;9201:18:7;;9176:22;9201:18;;;:9;:18;;;;;;9237:24;;;;9229:71;;;;-1:-1:-1;;;9229:71:7;;10036:2:14;9229:71:7;;;10018:21:14;10075:2;10055:18;;;10048:30;10114:34;10094:18;;;10087:62;-1:-1:-1;;;10165:18:14;;;10158:32;10207:19;;9229:71:7;10008:224:14;9229:71:7;-1:-1:-1;;;;;9334:18:7;;;;;;:9;:18;;;;;9355:23;;;9334:44;;9398:12;:22;;9372:6;;9334:18;9398:22;;9372:6;;9398:22;:::i;:::-;;;;-1:-1:-1;;9436:37:7;;31167:25:14;;;9462:1:7;;-1:-1:-1;;;;;9436:37:7;;;;;31155:2:14;31140:18;9436:37:7;;;;;;;13589:277:0::1;13373:499:::0;;:::o;634:205:10:-;773:58;;-1:-1:-1;;;;;6622:32:14;;773:58:10;;;6604:51:14;6671:18;;;6664:34;;;746:86:10;;766:5;;-1:-1:-1;;;796:23:10;6577:18:14;;773:58:10;;;;-1:-1:-1;;773:58:10;;;;;;;;;;;;;;-1:-1:-1;;;;;773:58:10;-1:-1:-1;;;;;;773:58:10;;;;;;;;;;746:19;:86::i;36459:249:0:-;-1:-1:-1;;;;;36535:21:0;;;;;;:10;:21;;;;;:31;;;36522:9;:44;;36535:31;;36522:9;;:44;;36535:31;;36522:44;:::i;:::-;;;;-1:-1:-1;;;;;;;36576:21:0;;36610:1;36576:21;;;:10;:21;;;;;;:31;;;:35;;;36621:28;;:36;;-1:-1:-1;;36621:36:0;;;36672:29;;;36610:1;36672:29;36459:249;:::o;2041:169:5:-;2096:16;2115:6;;-1:-1:-1;;;;;2131:17:5;;;-1:-1:-1;;;;;;2131:17:5;;;;;;2163:40;;2115:6;;;;;;;2163:40;;2096:16;2163:40;2041:169;;:::o;25980:510:0:-;-1:-1:-1;;;;;26129:21:0;;26072:7;26129:21;;;:10;:21;;;;;26072:7;329:32:1;268:1;337:2;329:32;:::i;:::-;26210:14:0;:12;:14::i;:::-;26189:8;:18;;;:35;;;;:::i;:::-;26188:77;;;;:::i;:::-;26303:18;;;;26160:105;;-1:-1:-1;26336:38:0;;;26332:152;;-1:-1:-1;26397:1:0;;25980:510;-1:-1:-1;;;;25980:510:0:o;26332:152::-;26436:37;26456:17;26436;:37;:::i;:::-;26429:44;25980:510;-1:-1:-1;;;;;25980:510:0:o;845:241:10:-;1010:68;;-1:-1:-1;;;;;6308:15:14;;;1010:68:10;;;6290:34:14;6360:15;;6340:18;;;6333:43;6392:18;;;6385:34;;;983:96:10;;1003:5;;-1:-1:-1;;;1033:27:10;6225:18:14;;1010:68:10;6207:218:14;31989:228:0;32041:7;;329:32:1;268:1;337:2;329:32;:::i;:::-;32084:8:0;;32076:16;;:5;:16;:::i;:::-;32075:46;;;;:::i;:::-;32060:61;-1:-1:-1;32135:8:0;;32131:50;;32167:7;;32145:36;;-1:-1:-1;;;;;32167:7:0;32176:4;32145:21;:36::i;:::-;;32131:50;32198:12;32206:4;32198:5;:12;:::i;12331:456::-;12388:7;12407:24;12479:13;;12453:10;;12435:15;:28;;;;:::i;:::-;12434:58;;;;:::i;:::-;12407:85;-1:-1:-1;187:29:1;127:2;195;187:29;:::i;:::-;12506:16:0;:42;12502:279;;;12588:12;;187:29:1;127:2;195;187:29;:::i;:::-;12671:32:0;12690:13;12671:16;:32;:::i;:::-;12670:60;;;;:::i;:::-;12637:94;;:13;:94;:::i;:::-;12614:117;;;;12331:456;:::o;12502:279::-;12769:1;12762:8;;;12331:456;:::o;10325:514::-;10420:7;10443:14;10467:20;10490:13;3259:12:7;;;3172:106;10490:13:0;10467:36;-1:-1:-1;10517:16:0;;10513:142;;10585:12;:10;:12::i;:::-;10559:22;10569:12;10559:7;:22;:::i;:::-;10558:39;;;;:::i;:::-;10549:48;;10513:142;;;10637:7;10628:16;;10513:142;10730:11;10722:58;;;;-1:-1:-1;;;10722:58:0;;28240:2:14;10722:58:0;;;28222:21:14;28279:2;28259:18;;;28252:30;28318:34;28298:18;;;28291:62;-1:-1:-1;;;28369:18:14;;;28362:32;28411:19;;10722:58:0;28212:224:14;10722:58:0;10790:18;10796:3;10801:6;10790:5;:18::i;:::-;-1:-1:-1;10826:6:0;10325:514;-1:-1:-1;;;10325:514:0:o;35851:199::-;35956:7;35996:15;36012:6;35996:23;;;;;-1:-1:-1;;;35996:23:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35996:23:0;-1:-1:-1;;;;;35986:55:0;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;36135:230::-;36231:7;36254:31;36288:10;:35;36299:15;36315:6;36299:23;;;;;-1:-1:-1;;;36299:23:0;;;;;;;;;;;-1:-1:-1;;;;;36299:23:0;36288:35;;;;;;;;;;;36299:23;36288:35;36340:18;;;;36135:230;-1:-1:-1;;;36135:230:0:o;35205:272::-;-1:-1:-1;;;;;35299:21:0;;;;;;:10;:21;;;;;:31;;;35286:9;:44;;35299:31;;35286:9;;:44;;35299:31;;35286:44;:::i;:::-;;;;-1:-1:-1;;;;;;;35340:21:0;;;;;;:10;:21;;;;;:31;;:44;;;35394:9;:23;;35374:10;;35340:21;35394:23;;35374:10;;35394:23;:::i;:::-;;;;-1:-1:-1;;35432:38:0;;31167:25:14;;;-1:-1:-1;;;;;35432:38:0;;;;;31155:2:14;31140:18;35432:38:0;31122:76:14;12793:119:0;12838:7;12881:24;:22;:24::i;:::-;12864:14;:12;:14::i;:::-;:41;;;;:::i;3140:706:10:-;3559:23;3585:69;3613:4;3585:69;;;;;;;;;;;;;;;;;3593:5;-1:-1:-1;;;;;3585:27:10;;;:69;;;;;:::i;:::-;3668:17;;3559:95;;-1:-1:-1;3668:21:10;3664:176;;3763:10;3752:30;;;;;;;;;;;;:::i;:::-;3744:85;;;;-1:-1:-1;;;3744:85:10;;28643:2:14;3744:85:10;;;28625:21:14;28682:2;28662:18;;;28655:30;28721:34;28701:18;;;28694:62;-1:-1:-1;;;28772:18:14;;;28765:40;28822:19;;3744:85:10;28615:232:14;8254:389:7;-1:-1:-1;;;;;8337:21:7;;8329:65;;;;-1:-1:-1;;;8329:65:7;;30504:2:14;8329:65:7;;;30486:21:14;30543:2;30523:18;;;30516:30;30582:33;30562:18;;;30555:61;30633:18;;8329:65:7;30476:181:14;8329:65:7;8481:6;8465:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8497:18:7;;;;;;:9;:18;;;;;:28;;8519:6;;8497:18;:28;;8519:6;;8497:28;:::i;:::-;;;;-1:-1:-1;;8540:37:7;;31167:25:14;;;-1:-1:-1;;;;;8540:37:7;;;8557:1;;8540:37;;31155:2:14;31140:18;8540:37:7;;;;;;;19522:1686:0;;:::o;3461:223:11:-;3594:12;3625:52;3647:6;3655:4;3661:1;3664:12;3625:21;:52::i;:::-;3618:59;3461:223;-1:-1:-1;;;;3461:223:11:o;4548:499::-;4713:12;4770:5;4745:21;:30;;4737:81;;;;-1:-1:-1;;;4737:81:11;;15458:2:14;4737:81:11;;;15440:21:14;15497:2;15477:18;;;15470:30;15536:34;15516:18;;;15509:62;-1:-1:-1;;;15587:18:14;;;15580:36;15633:19;;4737:81:11;15430:228:14;4737:81:11;1034:20;;4828:60;;;;-1:-1:-1;;;4828:60:11;;27129:2:14;4828:60:11;;;27111:21:14;27168:2;27148:18;;;27141:30;27207:31;27187:18;;;27180:59;27256:18;;4828:60:11;27101:179:14;4828:60:11;4900:12;4914:23;4941:6;-1:-1:-1;;;;;4941:11:11;4960:5;4967:4;4941:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4899:73;;;;4989:51;5006:7;5015:10;5027:12;4989:16;:51::i;:::-;4982:58;4548:499;-1:-1:-1;;;;;;;4548:499:11:o;7161:692::-;7307:12;7335:7;7331:516;;;-1:-1:-1;7365:10:11;7358:17;;7331:516;7476:17;;:21;7472:365;;7670:10;7664:17;7730:15;7717:10;7713:2;7709:19;7702:44;7619:145;7809:12;7802:20;;-1:-1:-1;;;7802:20:11;;;;;;;;:::i;14:257:14:-;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;276:261::-;346:6;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;542:398::-;610:6;618;671:2;659:9;650:7;646:23;642:32;639:2;;;692:6;684;677:22;639:2;736:9;723:23;755:31;780:5;755:31;:::i;:::-;805:5;-1:-1:-1;862:2:14;847:18;;834:32;875:33;834:32;875:33;:::i;:::-;927:7;917:17;;;629:311;;;;;:::o;945:466::-;1022:6;1030;1038;1091:2;1079:9;1070:7;1066:23;1062:32;1059:2;;;1112:6;1104;1097:22;1059:2;1156:9;1143:23;1175:31;1200:5;1175:31;:::i;:::-;1225:5;-1:-1:-1;1282:2:14;1267:18;;1254:32;1295:33;1254:32;1295:33;:::i;:::-;1049:362;;1347:7;;-1:-1:-1;;;1401:2:14;1386:18;;;;1373:32;;1049:362::o;1416:325::-;1484:6;1492;1545:2;1533:9;1524:7;1520:23;1516:32;1513:2;;;1566:6;1558;1551:22;1513:2;1610:9;1597:23;1629:31;1654:5;1629:31;:::i;:::-;1679:5;1731:2;1716:18;;;;1703:32;;-1:-1:-1;;;1503:238:14:o;1746:462::-;1832:6;1840;1848;1856;1909:3;1897:9;1888:7;1884:23;1880:33;1877:2;;;1931:6;1923;1916:22;1877:2;1975:9;1962:23;1994:31;2019:5;1994:31;:::i;:::-;2044:5;2096:2;2081:18;;2068:32;;-1:-1:-1;2147:2:14;2132:18;;2119:32;;2198:2;2183:18;2170:32;;-1:-1:-1;1867:341:14;-1:-1:-1;;;1867:341:14:o;2213:665::-;2299:6;2307;2360:2;2348:9;2339:7;2335:23;2331:32;2328:2;;;2381:6;2373;2366:22;2328:2;2426:9;2413:23;2455:18;2496:2;2488:6;2485:14;2482:2;;;2517:6;2509;2502:22;2482:2;2560:6;2549:9;2545:22;2535:32;;2605:7;2598:4;2594:2;2590:13;2586:27;2576:2;;2632:6;2624;2617:22;2576:2;2677;2664:16;2703:2;2695:6;2692:14;2689:2;;;2724:6;2716;2709:22;2689:2;2782:7;2777:2;2767:6;2764:1;2760:14;2756:2;2752:23;2748:32;2745:45;2742:2;;;2808:6;2800;2793:22;2742:2;2844;2836:11;;;;;2866:6;;-1:-1:-1;2318:560:14;;-1:-1:-1;;;;2318:560:14:o;2883:1171::-;2967:6;2998:2;3041;3029:9;3020:7;3016:23;3012:32;3009:2;;;3062:6;3054;3047:22;3009:2;3107:9;3094:23;3136:18;3177:2;3169:6;3166:14;3163:2;;;3198:6;3190;3183:22;3163:2;3241:6;3230:9;3226:22;3216:32;;3286:7;3279:4;3275:2;3271:13;3267:27;3257:2;;3313:6;3305;3298:22;3257:2;3354;3341:16;3376:2;3372;3369:10;3366:2;;;3382:18;;:::i;:::-;3428:2;3425:1;3421:10;3460:2;3454:9;3523:2;3519:7;3514:2;3510;3506:11;3502:25;3494:6;3490:38;3578:6;3566:10;3563:22;3558:2;3546:10;3543:18;3540:46;3537:2;;;3589:18;;:::i;:::-;3625:2;3618:22;3675:18;;;3709:15;;;;-1:-1:-1;3744:11:14;;;3774;;;3770:20;;3767:33;-1:-1:-1;3764:2:14;;;3818:6;3810;3803:22;3764:2;3845:6;3836:15;;3860:163;3874:2;3871:1;3868:9;3860:163;;;3931:17;;3919:30;;3892:1;3885:9;;;;;3969:12;;;;4001;;3860:163;;;-1:-1:-1;4042:6:14;2978:1076;-1:-1:-1;;;;;;;;2978:1076:14:o;4059:251::-;4115:6;4168:2;4156:9;4147:7;4143:23;4139:32;4136:2;;;4189:6;4181;4174:22;4136:2;4233:9;4220:23;4252:28;4274:5;4252:28;:::i;4315:255::-;4382:6;4435:2;4423:9;4414:7;4410:23;4406:32;4403:2;;;4456:6;4448;4441:22;4403:2;4493:9;4487:16;4512:28;4534:5;4512:28;:::i;4575:190::-;4634:6;4687:2;4675:9;4666:7;4662:23;4658:32;4655:2;;;4708:6;4700;4693:22;4655:2;-1:-1:-1;4736:23:14;;4645:120;-1:-1:-1;4645:120:14:o;4770:194::-;4840:6;4893:2;4881:9;4872:7;4868:23;4864:32;4861:2;;;4914:6;4906;4899:22;4861:2;-1:-1:-1;4942:16:14;;4851:113;-1:-1:-1;4851:113:14:o;4969:258::-;5037:6;5045;5098:2;5086:9;5077:7;5073:23;5069:32;5066:2;;;5119:6;5111;5104:22;5066:2;-1:-1:-1;;5147:23:14;;;5217:2;5202:18;;;5189:32;;-1:-1:-1;5056:171:14:o;5232:326::-;5309:6;5317;5325;5378:2;5366:9;5357:7;5353:23;5349:32;5346:2;;;5399:6;5391;5384:22;5346:2;-1:-1:-1;;5427:23:14;;;5497:2;5482:18;;5469:32;;-1:-1:-1;5548:2:14;5533:18;;;5520:32;;5336:222;-1:-1:-1;5336:222:14:o;5563:274::-;5692:3;5730:6;5724:13;5746:53;5792:6;5787:3;5780:4;5772:6;5768:17;5746:53;:::i;:::-;5815:16;;;;;5700:137;-1:-1:-1;;5700:137:14:o;6709:708::-;6890:2;6942:21;;;6915:18;;;6998:22;;;6861:4;;7077:6;7051:2;7036:18;;6861:4;7114:277;7128:6;7125:1;7122:13;7114:277;;;7203:6;7190:20;7223:31;7248:5;7223:31;:::i;:::-;-1:-1:-1;;;;;7279:31:14;7267:44;;7366:15;;;;7331:12;;;;7307:1;7143:9;7114:277;;;-1:-1:-1;7408:3:14;6870:547;-1:-1:-1;;;;;;6870:547:14:o;7877:383::-;8026:2;8015:9;8008:21;7989:4;8058:6;8052:13;8101:6;8096:2;8085:9;8081:18;8074:34;8117:66;8176:6;8171:2;8160:9;8156:18;8151:2;8143:6;8139:15;8117:66;:::i;:::-;8244:2;8223:15;-1:-1:-1;;8219:29:14;8204:45;;;;8251:2;8200:54;;7998:262;-1:-1:-1;;7998:262:14:o;22136:356::-;22338:2;22320:21;;;22357:18;;;22350:30;22416:34;22411:2;22396:18;;22389:62;22483:2;22468:18;;22310:182::o;29194:355::-;29396:2;29378:21;;;29435:2;29415:18;;;29408:30;29474:33;29469:2;29454:18;;29447:61;29540:2;29525:18;;29368:181::o;33562:128::-;33602:3;33633:1;33629:6;33626:1;33623:13;33620:2;;;33639:18;;:::i;:::-;-1:-1:-1;33675:9:14;;33610:80::o;33695:217::-;33735:1;33761;33751:2;;-1:-1:-1;;;33786:31:14;;33840:4;33837:1;33830:15;33868:4;33793:1;33858:15;33751:2;-1:-1:-1;33897:9:14;;33741:171::o;33917:422::-;34006:1;34049:5;34006:1;34063:270;34084:7;34074:8;34071:21;34063:270;;;34143:4;34139:1;34135:6;34131:17;34125:4;34122:27;34119:2;;;34152:18;;:::i;:::-;34202:7;34192:8;34188:22;34185:2;;;34222:16;;;;34185:2;34301:22;;;;34261:15;;;;34063:270;;;34067:3;33981:358;;;;;:::o;34344:131::-;34404:5;34433:36;34460:8;34454:4;34433:36;:::i;34480:140::-;34538:5;34567:47;34608:4;34598:8;34594:19;34588:4;34625:806;34674:5;34704:8;34694:2;;-1:-1:-1;34745:1:14;34759:5;;34694:2;34793:4;34783:2;;-1:-1:-1;34830:1:14;34844:5;;34783:2;34875:4;34893:1;34888:59;;;;34961:1;34956:130;;;;34868:218;;34888:59;34918:1;34909:10;;34932:5;;;34956:130;34993:3;34983:8;34980:17;34977:2;;;35000:18;;:::i;:::-;-1:-1:-1;;35056:1:14;35042:16;;35071:5;;34868:218;;35170:2;35160:8;35157:16;35151:3;35145:4;35142:13;35138:36;35132:2;35122:8;35119:16;35114:2;35108:4;35105:12;35101:35;35098:77;35095:2;;;-1:-1:-1;35207:19:14;;;35239:5;;35095:2;35286:34;35311:8;35305:4;35286:34;:::i;:::-;35356:6;35352:1;35348:6;35344:19;35335:7;35332:32;35329:2;;;35367:18;;:::i;:::-;35405:20;;34684:747;-1:-1:-1;;;34684:747:14:o;35436:168::-;35476:7;35542:1;35538;35534:6;35530:14;35527:1;35524:21;35519:1;35512:9;35505:17;35501:45;35498:2;;;35549:18;;:::i;:::-;-1:-1:-1;35589:9:14;;35488:116::o;35609:125::-;35649:4;35677:1;35674;35671:8;35668:2;;;35682:18;;:::i;:::-;-1:-1:-1;35719:9:14;;35658:76::o;35739:258::-;35811:1;35821:113;35835:6;35832:1;35829:13;35821:113;;;35911:11;;;35905:18;35892:11;;;35885:39;35857:2;35850:10;35821:113;;;35952:6;35949:1;35946:13;35943:2;;;-1:-1:-1;;35987:1:14;35969:16;;35962:27;35792:205::o;36002:380::-;36081:1;36077:12;;;;36124;;;36145:2;;36199:4;36191:6;36187:17;36177:27;;36145:2;36252;36244:6;36241:14;36221:18;36218:38;36215:2;;;36298:10;36293:3;36289:20;36286:1;36279:31;36333:4;36330:1;36323:15;36361:4;36358:1;36351:15;36387:135;36426:3;-1:-1:-1;;36447:17:14;;36444:2;;;36467:18;;:::i;:::-;-1:-1:-1;36514:1:14;36503:13;;36434:88::o;36527:127::-;36588:10;36583:3;36579:20;36576:1;36569:31;36619:4;36616:1;36609:15;36643:4;36640:1;36633:15;36659:127;36720:10;36715:3;36711:20;36708:1;36701:31;36751:4;36748:1;36741:15;36775:4;36772:1;36765:15;36791:131;-1:-1:-1;;;;;36866:31:14;;36856:42;;36846:2;;36912:1;36909;36902:12;36927:118;37013:5;37006:13;36999:21;36992:5;36989:32;36979:2;;37035:1;37032;37025:12
Swarm Source
ipfs://35c6218c3f9cc9df84a695534baddcf673de8e3cf3a702469e6420e67ae7e077
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.