Source Code
Latest 25 from a total of 183 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Harvest | 78783940 | 1053 days ago | IN | 0 ETH | 0.000099128406 | ||||
| Harvest | 78627847 | 1054 days ago | IN | 0 ETH | 0.000094891095 | ||||
| Harvest | 78465771 | 1055 days ago | IN | 0 ETH | 0.000091076412 | ||||
| Harvest | 78258700 | 1056 days ago | IN | 0 ETH | 0.000096062024 | ||||
| Harvest | 78046989 | 1057 days ago | IN | 0 ETH | 0.000110838837 | ||||
| Harvest | 77838340 | 1058 days ago | IN | 0 ETH | 0.000100854234 | ||||
| Harvest | 77644710 | 1059 days ago | IN | 0 ETH | 0.000224402324 | ||||
| Harvest | 77382897 | 1060 days ago | IN | 0 ETH | 0.000094314807 | ||||
| Harvest | 77113777 | 1061 days ago | IN | 0 ETH | 0.000070173591 | ||||
| Harvest | 76824524 | 1062 days ago | IN | 0 ETH | 0.000101913026 | ||||
| Harvest | 76398129 | 1063 days ago | IN | 0 ETH | 0.000150148365 | ||||
| Harvest | 76089535 | 1064 days ago | IN | 0 ETH | 0.000115892358 | ||||
| Harvest | 75826091 | 1065 days ago | IN | 0 ETH | 0.000107080944 | ||||
| Harvest | 75635546 | 1066 days ago | IN | 0 ETH | 0.000336952778 | ||||
| Harvest | 75440000 | 1067 days ago | IN | 0 ETH | 0.000089705643 | ||||
| Harvest | 75216624 | 1068 days ago | IN | 0 ETH | 0.000069691057 | ||||
| Harvest | 74392048 | 1072 days ago | IN | 0 ETH | 0.000128543623 | ||||
| Harvest | 63938251 | 1107 days ago | IN | 0 ETH | 0.000095999449 | ||||
| Harvest | 63214838 | 1108 days ago | IN | 0 ETH | 0.000101430946 | ||||
| Harvest | 62564288 | 1109 days ago | IN | 0 ETH | 0.000067976303 | ||||
| Harvest | 61414397 | 1111 days ago | IN | 0 ETH | 0.000066845471 | ||||
| Harvest | 60737020 | 1112 days ago | IN | 0 ETH | 0.000084812115 | ||||
| Harvest | 60214532 | 1113 days ago | IN | 0 ETH | 0.00008338238 | ||||
| Harvest | 59693696 | 1114 days ago | IN | 0 ETH | 0.000069411941 | ||||
| Harvest | 59191299 | 1115 days ago | IN | 0 ETH | 0.000091750792 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 107558375 | 907 days ago | 0 ETH | ||||
| 107558375 | 907 days ago | 0 ETH | ||||
| 107558375 | 907 days ago | 0 ETH | ||||
| 107558065 | 907 days ago | 0 ETH | ||||
| 107558065 | 907 days ago | 0 ETH | ||||
| 107558065 | 907 days ago | 0 ETH | ||||
| 107557445 | 907 days ago | 0 ETH | ||||
| 107557445 | 907 days ago | 0 ETH | ||||
| 107557445 | 907 days ago | 0 ETH | ||||
| 107556682 | 907 days ago | 0 ETH | ||||
| 107556682 | 907 days ago | 0 ETH | ||||
| 107556682 | 907 days ago | 0 ETH | ||||
| 107556518 | 907 days ago | 0 ETH | ||||
| 107556518 | 907 days ago | 0 ETH | ||||
| 107556518 | 907 days ago | 0 ETH | ||||
| 107556517 | 907 days ago | 0 ETH | ||||
| 107556517 | 907 days ago | 0 ETH | ||||
| 107556517 | 907 days ago | 0 ETH | ||||
| 107556517 | 907 days ago | 0 ETH | ||||
| 107556517 | 907 days ago | 0 ETH | ||||
| 107556517 | 907 days ago | 0 ETH | ||||
| 107555725 | 907 days ago | 0 ETH | ||||
| 107555725 | 907 days ago | 0 ETH | ||||
| 107555725 | 907 days ago | 0 ETH | ||||
| 107555461 | 907 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ReaperAutoCompoundFlashBorrow
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
import "./ReaperBaseStrategyv3.sol";
import "./interfaces/IAaveProtocolDataProvider.sol";
import "./interfaces/IAToken.sol";
import "./interfaces/IFlashLoanReceiver.sol";
import "./interfaces/IPool.sol";
import "./interfaces/IPoolAddressesProvider.sol";
import "./interfaces/IRewardsController.sol";
import "./interfaces/IVeloRouter.sol";
import "./libraries/DataTypes.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
/**
* @dev Implementation of a strategy to get yields from depositing
* the specified asset in a lending pool such as Aave.
*
* Flash loans are utilized during deposit() to achieve max leverage
* without any loops, and during withdraw() to be able to repay first
* without withdrawing anything. withdraw() can also be performed using
* excess collateral.
*/
contract ReaperAutoCompoundFlashBorrow is ReaperBaseStrategyv3, IFlashLoanReceiver {
using SafeERC20 for IERC20;
// 3rd-party contract addresses
address public constant VELO_ROUTER = 0xa132DAB612dB5cB9fC9Ac426A0Cc215A3423F9c9;
address public constant AAVE_ADDRESSES_PROVIDER = 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb;
address public constant AAVE_DATA_PROVIDER = 0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654;
address public constant AAVE_REWARDS_CONTROLLER = 0x929EC64c34a17401F460460D4B9390518E5B473e;
// this strategy's configurable tokens
IAToken public aWant;
IERC20 public want;
uint256 public targetLtv; // in hundredths of percent, 9500 = 95%
uint256 public maxLtv; // in hundredths of percent, 9700 = 97%
uint256 public minLeverageAmount;
uint256 public withdrawSlippageTolerance; // basis points precision, 50 = 0.5%
/**
* 0 - no flash loan in progress
* 1 - deposit()-related flash loan in progress
*/
uint256 private flashLoanStatus;
uint256 private constant NO_FL_IN_PROGRESS = 0;
uint256 private constant DEPOSIT_FL_IN_PROGRESS = 1;
// Misc constants
uint16 private constant LENDER_REFERRAL_CODE_NONE = 0;
uint256 private constant INTEREST_RATE_MODE_VARIABLE = 2;
uint256 private constant LTV_SAFETY_ZONE = 9800; // upper bound for maxLtv is 98% of max allowed LTV
uint256 private constant MAX_WITHDRAW_SLIPPAGE_TOLERANCE = 200;
/**
* @dev Tokens Used:
* {OP} - Reward token
* {USDC} - For charging fees
* {rewardClaimingTokens} - Array containing aWant + corresponding variable debt token,
* used for claiming any oustanding reward tokens.
*/
address public constant OP = 0x4200000000000000000000000000000000000042;
address public constant USDC = 0x7F5c764cBc14f9669B88837ca1490cCa17c31607;
address[] public rewardClaimingTokens;
/**
* @dev Paths used to swap tokens:
* {opToUsdcPath} - to swap {OP} to {USDC} for charging fees
* {opToWantPath} - to swap remaining {OP} to {want}
*/
address[] public opToUsdcPath;
address[] public opToWantPath;
/**
* @dev Initializes the strategy. Sets parameters, saves routes, and gives allowances.
* @notice see documentation for each variable above its respective declaration.
*/
constructor(
address _vault,
address[] memory _feeRemitters,
address[] memory _strategists,
address[] memory _multisigRoles,
IAToken _aWant,
address[] memory _opToWantPath,
uint256 _targetLtv,
uint256 _maxLtv,
uint8 _eModeCategory
) ReaperBaseStrategyv3(_vault, _feeRemitters, _strategists, _multisigRoles) {
aWant = _aWant;
want = IERC20(_aWant.UNDERLYING_ASSET_ADDRESS());
withdrawSlippageTolerance = 10;
minLeverageAmount = 1000;
opToUsdcPath = [OP, USDC];
setOpToWantPath(_opToWantPath);
(, , address vToken) = IAaveProtocolDataProvider(AAVE_DATA_PROVIDER).getReserveTokensAddresses(address(want));
rewardClaimingTokens = [address(_aWant), vToken];
POOL().setUserEMode(_eModeCategory);
_safeUpdateTargetLtv(_targetLtv, _maxLtv);
}
function ADDRESSES_PROVIDER() public pure override returns (IPoolAddressesProvider) {
return IPoolAddressesProvider(AAVE_ADDRESSES_PROVIDER);
}
function POOL() public view override returns (IPool) {
return IPool(ADDRESSES_PROVIDER().getPool());
}
function executeOperation(
address[] calldata,
uint256[] calldata,
uint256[] calldata,
address initiator,
bytes calldata
) external override returns (bool) {
require(msg.sender == address(POOL()), "caller != lending pool");
require(initiator == address(this), "!initiator");
require(flashLoanStatus == DEPOSIT_FL_IN_PROGRESS, "invalid flashLoanStatus");
flashLoanStatus = NO_FL_IN_PROGRESS;
// simply supply everything we have
// lender will automatically open a variable debt position
// since flash loan was requested with interest rate mode VARIABLE
_supply();
return true;
}
/**
* @dev Function that puts the funds to work.
* It gets called whenever someone deposits in the strategy's vault contract.
*/
function _deposit() internal override {
_supply();
(uint256 supply, uint256 borrow) = getSupplyAndBorrow();
uint256 currentLtv = supply != 0 ? (borrow * PERCENT_DIVISOR) / supply : 0;
if (currentLtv > maxLtv) {
_deleverUsingAToken(0);
} else if (currentLtv < targetLtv) {
_leverUpMax();
}
}
/**
* @dev Withdraws funds and sends them back to the vault.
*/
function _withdraw(uint256 _amount) internal override {
uint256 wantBal = want.balanceOf(address(this));
if (_amount <= wantBal) {
want.safeTransfer(vault, _amount);
return;
}
uint256 remaining = _amount - wantBal;
(uint256 supply, uint256 borrow) = getSupplyAndBorrow();
supply -= remaining;
uint256 postWithdrawLtv = supply != 0 ? (borrow * PERCENT_DIVISOR) / supply : 0;
if (postWithdrawLtv > maxLtv) {
_deleverUsingAToken(remaining);
_withdrawAndSendToVault(remaining, _amount);
} else if (postWithdrawLtv < targetLtv) {
_withdrawAndSendToVault(remaining, _amount);
_leverUpMax();
} else {
_withdrawAndSendToVault(remaining, _amount);
}
}
function _deleverUsingAToken(uint256 _amount) internal {
(uint256 supply, uint256 borrow) = getSupplyAndBorrow();
uint256 realSupply = supply - borrow;
require(_amount <= realSupply, "invalid amount");
// calculate amount to reduce borrow by
uint256 newRealSupply = realSupply - _amount;
uint256 newBorrow = (newRealSupply * targetLtv) / (PERCENT_DIVISOR - targetLtv);
uint256 borrowReduction = borrow - newBorrow;
// reduce borrow using aToken and withdraw _amount
POOL().repayWithATokens(address(want), borrowReduction, INTEREST_RATE_MODE_VARIABLE);
}
/**
* @dev Attempts to reach max leverage as per {targetLtv} using a flash loan.
*/
function _leverUpMax() internal {
(uint256 supply, uint256 borrow) = getSupplyAndBorrow();
uint256 realSupply = supply - borrow;
uint256 desiredBorrow = (realSupply * targetLtv) / (PERCENT_DIVISOR - targetLtv);
if (desiredBorrow > borrow + minLeverageAmount) {
_initFlashLoan(desiredBorrow - borrow);
}
}
/**
* @dev Withdraws {_withdrawAmount} from pool and attempts to send {_vaultExpecting} to vault.
*/
function _withdrawAndSendToVault(uint256 _withdrawAmount, uint256 _vaultExpecting) internal {
_withdrawUnderlying(_withdrawAmount);
uint256 wantBal = want.balanceOf(address(this));
if (wantBal < _vaultExpecting) {
require(
wantBal >= (_vaultExpecting * (PERCENT_DIVISOR - withdrawSlippageTolerance)) / PERCENT_DIVISOR,
"withdraw: outside slippage tolerance!"
);
}
want.safeTransfer(vault, Math.min(wantBal, _vaultExpecting));
}
/**
* @dev Attempts to Withdraw {_withdrawAmount} from pool. Withdraws max amount that can be
* safely withdrawn if {_withdrawAmount} is too high.
*/
function _withdrawUnderlying(uint256 _withdrawAmount) internal {
(uint256 supply, uint256 borrow) = getSupplyAndBorrow();
uint256 necessarySupply = maxLtv != 0 ? (borrow * PERCENT_DIVISOR) / maxLtv : 0; // use maxLtv instead of targetLtv here
require(supply > necessarySupply, "can't withdraw anything!");
uint256 withdrawable = supply - necessarySupply;
_withdrawAmount = Math.min(_withdrawAmount, withdrawable);
POOL().withdraw(address(want), _withdrawAmount, address(this));
}
/**
* @dev Internal helper function to supply to lending pool that also gives allowance
*/
function _supply() internal {
uint256 wantBal = want.balanceOf(address(this));
if (wantBal != 0) {
want.safeIncreaseAllowance(address(POOL()), wantBal);
POOL().supply(address(want), wantBal, address(this), LENDER_REFERRAL_CODE_NONE);
}
}
/**
* @dev Core function of the strat, in charge of collecting and re-investing rewards.
*/
function _harvestCore() internal override returns (uint256 callerFee) {
IRewardsController(AAVE_REWARDS_CONTROLLER).claimAllRewardsToSelf(rewardClaimingTokens);
callerFee = _chargePerformanceFees();
_convertOpToWant();
deposit();
}
/**
* @dev Takes out fees from the rewards.
* callFeeToUser is set as a percentage of the fee.
*/
function _chargePerformanceFees() internal returns (uint256 callerFee) {
uint256 opFee = (IERC20(OP).balanceOf(address(this)) * totalFee) / PERCENT_DIVISOR;
if (opFee == 0) {
return 0;
}
IERC20 usdc = IERC20(USDC);
uint256 usdcBalBefore = usdc.balanceOf(address(this));
_swap(opToUsdcPath, opFee);
uint256 usdcFee = usdc.balanceOf(address(this)) - usdcBalBefore;
if (usdcFee != 0) {
callerFee = (usdcFee * callFee) / PERCENT_DIVISOR;
uint256 treasuryFeeToVault = (usdcFee * treasuryFee) / PERCENT_DIVISOR;
uint256 feeToStrategist = (treasuryFeeToVault * strategistFee) / PERCENT_DIVISOR;
treasuryFeeToVault -= feeToStrategist;
usdc.safeTransfer(msg.sender, callerFee);
usdc.safeTransfer(treasury, treasuryFeeToVault);
usdc.safeTransfer(strategistRemitter, feeToStrategist);
}
}
/**
* @dev Converts all of this contract's {OP} balance into {want}.
* Typically called during harvesting to transform assets back into
* {want} for re-depositing.
*/
function _convertOpToWant() internal {
uint256 opBal = IERC20(OP).balanceOf(address(this));
if (opBal != 0) {
_swap(opToWantPath, opBal);
}
}
/// @dev Helper function to swap given a {_path} and an {_amount}.
function _swap(address[] memory _path, uint256 _amount) internal {
IVeloRouter router = IVeloRouter(VELO_ROUTER);
IVeloRouter.route[] memory routes = new IVeloRouter.route[](_path.length - 1);
uint256 prevRouteOutput = _amount;
uint256 output;
bool useStable;
for (uint256 i = 0; i < routes.length; i++) {
(output, useStable) = router.getAmountOut(prevRouteOutput, _path[i], _path[i + 1]);
routes[i] = IVeloRouter.route({from: _path[i], to: _path[i + 1], stable: useStable});
prevRouteOutput = output;
}
IERC20(_path[0]).safeIncreaseAllowance(VELO_ROUTER, _amount);
router.swapExactTokensForTokens(_amount, 0, routes, address(this), block.timestamp);
}
function _initFlashLoan(uint256 _amount) internal {
require(_amount != 0, "FL: invalid amount!");
// asset to be flashed
address[] memory assets = new address[](1);
assets[0] = address(want);
// amount to be flashed
uint256[] memory amounts = new uint256[](1);
amounts[0] = _amount;
// 0 = no debt, 1 = stable, 2 = variable
uint256[] memory modes = new uint256[](1);
modes[0] = INTEREST_RATE_MODE_VARIABLE;
flashLoanStatus = DEPOSIT_FL_IN_PROGRESS;
POOL().flashLoan(address(this), assets, amounts, modes, address(this), "", LENDER_REFERRAL_CODE_NONE);
}
function getSupplyAndBorrow() public view returns (uint256 supply, uint256 borrow) {
(supply, , borrow, , , , , , ) = IAaveProtocolDataProvider(AAVE_DATA_PROVIDER).getUserReserveData(
address(want),
address(this)
);
return (supply, borrow);
}
// Path setters for swaps, needs at least STRATEGIST level access
function setOpToUsdcPath(address[] calldata _path) external {
_atLeastRole(STRATEGIST);
require(_path[0] == OP && _path[_path.length - 1] == USDC, "Invalid opToUsdcPath");
opToUsdcPath = _path;
}
function setOpToWantPath(address[] memory _path) public {
_atLeastRole(STRATEGIST);
require(_path[0] == OP && _path[_path.length - 1] == address(want), "Invalid opToWantPath");
opToWantPath = _path;
}
/**
* @dev Frees up {_amount} of want by manipulating supply/borrow.
*/
function authorizedDelever(uint256 _amount) external {
_atLeastRole(STRATEGIST);
_deleverUsingAToken(_amount);
}
/**
* @dev Attempts to safely withdraw {_amount} from the pool and optionally sends it
* to the vault.
*/
function authorizedWithdrawUnderlying(uint256 _amount) external {
_atLeastRole(STRATEGIST);
_withdrawUnderlying(_amount);
}
/**
* @dev Attempts to safely withdraw {_amount} from the pool and optionally sends it
* to the vault.
*/
function authorizedSendToVault(uint256 _amount) external {
_atLeastRole(STRATEGIST);
want.safeTransfer(vault, _amount);
}
/**
* @dev Function to calculate the total {want} held by the strat.
* It takes into account both the funds in hand, plus the funds in the lendingPool.
*/
function balanceOf() public view override returns (uint256) {
(uint256 supply, uint256 borrow) = getSupplyAndBorrow();
uint256 realSupply = supply - borrow;
return realSupply + want.balanceOf(address(this));
}
/**
* Withdraws all funds leaving rewards behind.
*/
function _reclaimWant() internal override {
(uint256 supply, uint256 borrow) = getSupplyAndBorrow();
uint256 realSupply = supply - borrow;
_deleverUsingAToken(realSupply);
_withdrawUnderlying(realSupply);
}
/**
* @dev Updates target LTV (safely).
* May be called by KEEPER.
*/
function setLTVs(uint256 _newTargetLtv, uint256 _newMaxLtv) external {
_atLeastRole(KEEPER);
_safeUpdateTargetLtv(_newTargetLtv, _newMaxLtv);
}
/**
* @dev Updates slippage tolerance (when withdrawing), and minimum
* amount to lever up with.
* Can only be called by strategist or owner.
*/
function setLeverageParams(uint256 _newWithdrawSlippageTolerance, uint256 _newMinLeverageAmount) external {
_atLeastRole(STRATEGIST);
require(_newWithdrawSlippageTolerance <= MAX_WITHDRAW_SLIPPAGE_TOLERANCE, "invalid slippage!");
withdrawSlippageTolerance = _newWithdrawSlippageTolerance;
minLeverageAmount = _newMinLeverageAmount;
}
function _safeUpdateTargetLtv(uint256 _newTargetLtv, uint256 _newMaxLtv) internal {
uint256 eMode = POOL().getUserEMode(address(this));
uint256 ltv;
if (eMode != 0) {
DataTypes.EModeCategory memory eModeData = POOL().getEModeCategoryData(uint8(eMode));
ltv = eModeData.ltv;
} else {
(, ltv, , , , , , , , ) = IAaveProtocolDataProvider(AAVE_DATA_PROVIDER).getReserveConfigurationData(
address(want)
);
}
require(_newMaxLtv <= (ltv * LTV_SAFETY_ZONE) / PERCENT_DIVISOR, "maxLtv not safe");
require(_newTargetLtv <= _newMaxLtv, "targetLtv must <= maxLtv");
maxLtv = _newMaxLtv;
targetLtv = _newTargetLtv;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./interfaces/IStrategy.sol";
import "./interfaces/IVault.sol";
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
abstract contract ReaperBaseStrategyv3 is IStrategy, AccessControlEnumerable, Pausable {
uint256 public constant PERCENT_DIVISOR = 10_000;
uint256 public constant ONE_YEAR = 365 days;
struct Harvest {
uint256 timestamp;
uint256 vaultSharePrice;
}
Harvest[] public harvestLog;
uint256 public harvestLogCadence;
uint256 public lastHarvestTimestamp;
/**
* Reaper Roles in increasing order of privilege.
* {KEEPER} - Stricly permissioned trustless access for off-chain programs or third party keepers.
* {STRATEGIST} - Role conferred to authors of the strategy, allows for tweaking non-critical params.
* {GUARDIAN} - Multisig requiring 2 signatures for emergency measures such as pausing and panicking.
* {ADMIN}- Multisig requiring 3 signatures for unpausing.
*
* The DEFAULT_ADMIN_ROLE (in-built access control role) will be granted to a multisig requiring 4
* signatures. This role would have the ability to grant any other roles.
*
* Also note that roles are cascading. So any higher privileged role should be able to perform all the functions
* of any lower privileged role.
*/
bytes32 public constant KEEPER = keccak256("KEEPER");
bytes32 public constant STRATEGIST = keccak256("STRATEGIST");
bytes32 public constant GUARDIAN = keccak256("GUARDIAN");
bytes32 public constant ADMIN = keccak256("ADMIN");
bytes32[] private cascadingAccess;
/**
* @dev Reaper contracts:
* {treasury} - Address of the Reaper treasury
* {vault} - Address of the vault that controls the strategy's funds.
* {strategistRemitter} - Address where strategist fee is remitted to.
*/
address public treasury;
address public vault;
address public strategistRemitter;
/**
* Fee related constants:
* {MAX_FEE} - Maximum fee allowed by the strategy. Hard-capped at 10%.
* {STRATEGIST_MAX_FEE} - Maximum strategist fee allowed by the strategy (as % of treasury fee).
* Hard-capped at 50%
*/
uint256 public constant MAX_FEE = 1000;
uint256 public constant STRATEGIST_MAX_FEE = 5000;
/**
* @dev Distribution of fees earned, expressed as % of the profit from each harvest.
* {totalFee} - divided by 10,000 to determine the % fee. Set to 4.5% by default and
* lowered as necessary to provide users with the most competitive APY.
*
* {callFee} - Percent of the totalFee reserved for the harvester (1000 = 10% of total fee: 0.45% by default)
* {treasuryFee} - Percent of the totalFee taken by maintainers of the software (9000 = 90% of total fee: 4.05% by default)
* {strategistFee} - Percent of the treasuryFee taken by strategist (2500 = 25% of treasury fee: 1.0125% by default)
*/
uint256 public totalFee;
uint256 public callFee;
uint256 public treasuryFee;
uint256 public strategistFee;
/**
* {TotalFeeUpdated} Event that is fired each time the total fee is updated.
* {FeesUpdated} Event that is fired each time callFee+treasuryFee+strategistFee are updated.
* {StratHarvest} Event that is fired each time the strategy gets harvested.
* {StrategistRemitterUpdated} Event that is fired each time the strategistRemitter address is updated.
*/
event TotalFeeUpdated(uint256 newFee);
event FeesUpdated(uint256 newCallFee, uint256 newTreasuryFee, uint256 newStrategistFee);
event StratHarvest(address indexed harvester);
event StrategistRemitterUpdated(address newStrategistRemitter);
constructor(
address _vault,
address[] memory _feeRemitters,
address[] memory _strategists,
address[] memory _multisigRoles
) {
harvestLogCadence = 1 minutes;
totalFee = 450;
callFee = 1000;
treasuryFee = 9000;
strategistFee = 0;
vault = _vault;
treasury = _feeRemitters[0];
strategistRemitter = _feeRemitters[1];
for (uint256 i = 0; i < _strategists.length; i++) {
_grantRole(STRATEGIST, _strategists[i]);
}
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(DEFAULT_ADMIN_ROLE, _multisigRoles[0]);
_grantRole(ADMIN, _multisigRoles[1]);
_grantRole(GUARDIAN, _multisigRoles[2]);
cascadingAccess = [DEFAULT_ADMIN_ROLE, ADMIN, GUARDIAN, STRATEGIST, KEEPER];
harvestLog.push(Harvest({timestamp: block.timestamp, vaultSharePrice: IVault(_vault).getPricePerFullShare()}));
}
/**
* @dev Function that puts the funds to work.
* It gets called whenever someone deposits in the strategy's vault contract.
* Deposits go through only when the strategy is not paused.
*/
function deposit() public override whenNotPaused {
_deposit();
}
/**
* @dev Withdraws funds and sends them back to the vault. Can only
* be called by the vault. _amount must be valid and security fee
* is deducted up-front.
*/
function withdraw(uint256 _amount) external override {
require(msg.sender == vault);
require(_amount != 0);
require(_amount <= balanceOf());
_withdraw(_amount);
}
/**
* @dev harvest() function that takes care of logging. Subcontracts should
* override _harvestCore() and implement their specific logic in it.
*/
function harvest() external override whenNotPaused returns (uint256 callerFee) {
callerFee = _harvestCore();
if (block.timestamp >= harvestLog[harvestLog.length - 1].timestamp + harvestLogCadence) {
harvestLog.push(
Harvest({timestamp: block.timestamp, vaultSharePrice: IVault(vault).getPricePerFullShare()})
);
}
lastHarvestTimestamp = block.timestamp;
emit StratHarvest(msg.sender);
}
function harvestLogLength() external view returns (uint256) {
return harvestLog.length;
}
/**
* @dev Traverses the harvest log backwards _n items,
* and returns the average APR calculated across all the included
* log entries. APR is multiplied by PERCENT_DIVISOR to retain precision.
*/
function averageAPRAcrossLastNHarvests(int256 _n) external view returns (int256) {
require(harvestLog.length >= 2);
int256 runningAPRSum;
int256 numLogsProcessed;
for (uint256 i = harvestLog.length - 1; i > 0 && numLogsProcessed < _n; i--) {
runningAPRSum += calculateAPRUsingLogs(i - 1, i);
numLogsProcessed++;
}
return runningAPRSum / numLogsProcessed;
}
/**
* @dev Strategists and roles with higher privilege can edit the log cadence.
*/
function updateHarvestLogCadence(uint256 _newCadenceInSeconds) external {
_atLeastRole(STRATEGIST);
harvestLogCadence = _newCadenceInSeconds;
}
/**
* @dev Function to calculate the total {want} held by the strat.
* It takes into account both the funds in hand, plus the funds in external contracts.
*/
function balanceOf() public view virtual override returns (uint256);
/**
* @dev Pauses deposits. Withdraws all funds leaving rewards behind.
* Guardian and roles with higher privilege can panic.
*/
function panic() external override {
_atLeastRole(GUARDIAN);
_reclaimWant();
pause();
}
/**
* @dev Pauses the strat. Deposits become disabled but users can still
* withdraw. Guardian and roles with higher privilege can pause.
*/
function pause() public override {
_atLeastRole(GUARDIAN);
_pause();
}
/**
* @dev Unpauses the strat. Opens up deposits again and invokes deposit().
* Admin and roles with higher privilege can unpause.
*/
function unpause() external override {
_atLeastRole(ADMIN);
_unpause();
deposit();
}
/**
* @dev updates the total fee, capped at 5%; only DEFAULT_ADMIN_ROLE.
*/
function updateTotalFee(uint256 _totalFee) external {
_atLeastRole(DEFAULT_ADMIN_ROLE);
require(_totalFee <= MAX_FEE);
totalFee = _totalFee;
emit TotalFeeUpdated(totalFee);
}
/**
* @dev updates the call fee, treasury fee, and strategist fee
* call Fee + treasury Fee must add up to PERCENT_DIVISOR
*
* strategist fee is expressed as % of the treasury fee and
* must be no more than STRATEGIST_MAX_FEE
*
* only DEFAULT_ADMIN_ROLE.
*/
function updateFees(
uint256 _callFee,
uint256 _treasuryFee,
uint256 _strategistFee
) external returns (bool) {
_atLeastRole(DEFAULT_ADMIN_ROLE);
require(_callFee + _treasuryFee == PERCENT_DIVISOR);
require(_strategistFee <= STRATEGIST_MAX_FEE);
callFee = _callFee;
treasuryFee = _treasuryFee;
strategistFee = _strategistFee;
emit FeesUpdated(callFee, treasuryFee, strategistFee);
return true;
}
/**
* @dev only DEFAULT_ADMIN_ROLE can update treasury address.
*/
function updateTreasury(address newTreasury) external returns (bool) {
_atLeastRole(DEFAULT_ADMIN_ROLE);
treasury = newTreasury;
return true;
}
/**
* @dev Updates the current strategistRemitter. Only DEFAULT_ADMIN_ROLE may do this.
*/
function updateStrategistRemitter(address _newStrategistRemitter) external {
_atLeastRole(DEFAULT_ADMIN_ROLE);
require(_newStrategistRemitter != address(0));
strategistRemitter = _newStrategistRemitter;
emit StrategistRemitterUpdated(_newStrategistRemitter);
}
/**
* @dev Project an APR using the vault share price change between harvests at the provided indices.
*/
function calculateAPRUsingLogs(uint256 _startIndex, uint256 _endIndex) public view returns (int256) {
Harvest storage start = harvestLog[_startIndex];
Harvest storage end = harvestLog[_endIndex];
bool increasing = true;
if (end.vaultSharePrice < start.vaultSharePrice) {
increasing = false;
}
uint256 unsignedSharePriceChange;
if (increasing) {
unsignedSharePriceChange = end.vaultSharePrice - start.vaultSharePrice;
} else {
unsignedSharePriceChange = start.vaultSharePrice - end.vaultSharePrice;
}
uint256 unsignedPercentageChange = (unsignedSharePriceChange * 1e18) / start.vaultSharePrice;
uint256 timeDifference = end.timestamp - start.timestamp;
uint256 yearlyUnsignedPercentageChange = (unsignedPercentageChange * ONE_YEAR) / timeDifference;
yearlyUnsignedPercentageChange /= 1e14; // restore basis points precision
if (increasing) {
return int256(yearlyUnsignedPercentageChange);
}
return -int256(yearlyUnsignedPercentageChange);
}
/**
* @dev Internal function that checks cascading role privileges. Any higher privileged role
* should be able to perform all the functions of any lower privileged role. This is
* accomplished using the {cascadingAccess} array that lists all roles from most privileged
* to least privileged.
*/
function _atLeastRole(bytes32 role) internal view {
uint256 numRoles = cascadingAccess.length;
uint256 specifiedRoleIndex;
for (uint256 i = 0; i < numRoles; i++) {
if (role == cascadingAccess[i]) {
specifiedRoleIndex = i;
break;
} else if (i == numRoles - 1) {
revert("unauthorized access");
}
}
for (uint256 i = 0; i <= specifiedRoleIndex; i++) {
if (hasRole(cascadingAccess[i], msg.sender)) {
break;
} else if (i == specifiedRoleIndex) {
revert("unauthorized access");
}
}
}
/**
* @dev subclasses should add their custom deposit logic in this function.
*/
function _deposit() internal virtual;
/**
* @dev subclasses should add their custom withdraw logic in this function.
* Note that security fee has already been deducted, so it shouldn't be deducted
* again within this function.
*/
function _withdraw(uint256 _amount) internal virtual;
/**
* @dev subclasses should add their custom harvesting logic in this function
* including charging any fees. The amount of fee that is remitted to the
* caller must be returned.
*/
function _harvestCore() internal virtual returns (uint256);
/**
* @dev subclasses should add their custom logic to withdraw the principal from
* any external contracts in this function. Note that we don't care about rewards,
* we just want to reclaim our principal as much as possible, and as quickly as possible.
* So keep this function lean. Principal should be left in the strategy and not sent to
* the vault.
*/
function _reclaimWant() internal virtual;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IStrategy {
//deposits all funds into the farm
function deposit() external;
//vault only - withdraws funds from the strategy
function withdraw(uint256 _amount) external;
//claims rewards, charges fees, and re-deposits; returns caller fee amount.
function harvest() external returns (uint256);
//returns the balance of all tokens managed by the strategy
function balanceOf() external view returns (uint256);
//pauses deposits, resets allowances, and withdraws all funds from farm
function panic() external;
//pauses deposits and resets allowances
function pause() external;
//unpauses deposits and maxes out allowances again
function unpause() external;
}// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
interface IVault {
function getPricePerFullShare() external view returns (uint256);
}// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
interface IAaveProtocolDataProvider {
struct TokenData {
string symbol;
address tokenAddress;
}
function ADDRESSES_PROVIDER() external view returns (address);
function getATokenTotalSupply(address asset)
external
view
returns (uint256);
function getAllATokens() external view returns (TokenData[] memory);
function getAllReservesTokens() external view returns (TokenData[] memory);
function getDebtCeiling(address asset) external view returns (uint256);
function getDebtCeilingDecimals() external pure returns (uint256);
function getInterestRateStrategyAddress(address asset)
external
view
returns (address irStrategyAddress);
function getLiquidationProtocolFee(address asset)
external
view
returns (uint256);
function getPaused(address asset) external view returns (bool isPaused);
function getReserveCaps(address asset)
external
view
returns (uint256 borrowCap, uint256 supplyCap);
function getReserveConfigurationData(address asset)
external
view
returns (
uint256 decimals,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus,
uint256 reserveFactor,
bool usageAsCollateralEnabled,
bool borrowingEnabled,
bool stableBorrowRateEnabled,
bool isActive,
bool isFrozen
);
function getReserveData(address asset)
external
view
returns (
uint256 unbacked,
uint256 accruedToTreasuryScaled,
uint256 totalAToken,
uint256 totalStableDebt,
uint256 totalVariableDebt,
uint256 liquidityRate,
uint256 variableBorrowRate,
uint256 stableBorrowRate,
uint256 averageStableBorrowRate,
uint256 liquidityIndex,
uint256 variableBorrowIndex,
uint40 lastUpdateTimestamp
);
function getReserveEModeCategory(address asset)
external
view
returns (uint256);
function getReserveTokensAddresses(address asset)
external
view
returns (
address aTokenAddress,
address stableDebtTokenAddress,
address variableDebtTokenAddress
);
function getUnbackedMintCap(address asset) external view returns (uint256);
function getUserReserveData(address asset, address user)
external
view
returns (
uint256 currentATokenBalance,
uint256 currentStableDebt,
uint256 currentVariableDebt,
uint256 principalStableDebt,
uint256 scaledVariableDebt,
uint256 stableBorrowRate,
uint256 liquidityRate,
uint40 stableRateLastUpdated,
bool usageAsCollateralEnabled
);
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IScaledBalanceToken} from "./IScaledBalanceToken.sol";
import {IInitializableAToken} from "./IInitializableAToken.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title IAToken
* @author Aave
* @notice Defines the basic interface for an AToken.
**/
interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken {
/**
* @dev Emitted during the transfer action
* @param from The user whose tokens are being transferred
* @param to The recipient
* @param value The amount being transferred
* @param index The next liquidity index of the reserve
**/
event BalanceTransfer(
address indexed from,
address indexed to,
uint256 value,
uint256 index
);
/**
* @notice Mints `amount` aTokens to `user`
* @param caller The address performing the mint
* @param onBehalfOf The address of the user that will receive the minted aTokens
* @param amount The amount of tokens getting minted
* @param index The next liquidity index of the reserve
* @return `true` if the the previous balance of the user was 0
*/
function mint(
address caller,
address onBehalfOf,
uint256 amount,
uint256 index
) external returns (bool);
/**
* @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`
* @dev In some instances, the mint event could be emitted from a burn transaction
* if the amount to burn is less than the interest that the user accrued
* @param from The address from which the aTokens will be burned
* @param receiverOfUnderlying The address that will receive the underlying
* @param amount The amount being burned
* @param index The next liquidity index of the reserve
**/
function burn(
address from,
address receiverOfUnderlying,
uint256 amount,
uint256 index
) external;
/**
* @notice Mints aTokens to the reserve treasury
* @param amount The amount of tokens getting minted
* @param index The next liquidity index of the reserve
*/
function mintToTreasury(uint256 amount, uint256 index) external;
/**
* @notice Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
* @param from The address getting liquidated, current owner of the aTokens
* @param to The recipient
* @param value The amount of tokens getting transferred
**/
function transferOnLiquidation(
address from,
address to,
uint256 value
) external;
/**
* @notice Transfers the underlying asset to `target`.
* @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan()
* @param user The recipient of the underlying
* @param amount The amount getting transferred
**/
function transferUnderlyingTo(address user, uint256 amount) external;
/**
* @notice Handles the underlying received by the aToken after the transfer has been completed.
* @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the
* transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying
* to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset.
* @param user The user executing the repayment
* @param amount The amount getting repaid
**/
function handleRepayment(address user, uint256 amount) external;
/**
* @notice Allow passing a signed message to approve spending
* @dev implements the permit function as for
* https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md
* @param owner The owner of the funds
* @param spender The spender
* @param value The amount
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)
* @return The address of the underlying asset
**/
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
/**
* @notice Returns the address of the Aave treasury, receiving the fees on this aToken.
* @return Address of the Aave treasury
**/
function RESERVE_TREASURY_ADDRESS() external view returns (address);
/**
* @notice Get the domain separator for the token
* @dev Return cached value if chainId matches cache, otherwise recomputes separator
* @return The domain separator of the token at current chain
*/
function DOMAIN_SEPARATOR() external view returns (bytes32);
/**
* @notice Returns the nonce for owner.
* @param owner The address of the owner
* @return The nonce of the owner
**/
function nonces(address owner) external view returns (uint256);
/**
* @notice Rescue and transfer tokens locked in this contract
* @param token The address of the token
* @param to The address of the recipient
* @param amount The amount of token to transfer
*/
function rescueTokens(
address token,
address to,
uint256 amount
) external;
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
/**
* @title IScaledBalanceToken
* @author Aave
* @notice Defines the basic interface for a scaledbalance token.
**/
interface IScaledBalanceToken {
/**
* @dev Emitted after the mint action
* @param caller The address performing the mint
* @param onBehalfOf The address of the user that will receive the minted scaled balance tokens
* @param value The amount being minted (user entered amount + balance increase from interest)
* @param balanceIncrease The increase in balance since the last action of the user
* @param index The next liquidity index of the reserve
**/
event Mint(
address indexed caller,
address indexed onBehalfOf,
uint256 value,
uint256 balanceIncrease,
uint256 index
);
/**
* @dev Emitted after scaled balance tokens are burned
* @param from The address from which the scaled tokens will be burned
* @param target The address that will receive the underlying, if any
* @param value The amount being burned (user entered amount - balance increase from interest)
* @param balanceIncrease The increase in balance since the last action of the user
* @param index The next liquidity index of the reserve
**/
event Burn(
address indexed from,
address indexed target,
uint256 value,
uint256 balanceIncrease,
uint256 index
);
/**
* @notice Returns the scaled balance of the user.
* @dev The scaled balance is the sum of all the updated stored balance divided by the reserve's liquidity index
* at the moment of the update
* @param user The user whose balance is calculated
* @return The scaled balance of the user
**/
function scaledBalanceOf(address user) external view returns (uint256);
/**
* @notice Returns the scaled balance of the user and the scaled total supply.
* @param user The address of the user
* @return The scaled balance of the user
* @return The scaled total supply
**/
function getScaledUserBalanceAndSupply(address user)
external
view
returns (uint256, uint256);
/**
* @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index)
* @return The scaled total supply
**/
function scaledTotalSupply() external view returns (uint256);
/**
* @notice Returns last index interest was accrued to the user's balance
* @param user The address of the user
* @return The last index interest was accrued to the user's balance, expressed in ray
**/
function getPreviousIndex(address user) external view returns (uint256);
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IAaveIncentivesController} from "./IAaveIncentivesController.sol";
import {IPool} from "./IPool.sol";
/**
* @title IInitializableAToken
* @author Aave
* @notice Interface for the initialize function on AToken
**/
interface IInitializableAToken {
/**
* @dev Emitted when an aToken is initialized
* @param underlyingAsset The address of the underlying asset
* @param pool The address of the associated pool
* @param treasury The address of the treasury
* @param incentivesController The address of the incentives controller for this aToken
* @param aTokenDecimals The decimals of the underlying
* @param aTokenName The name of the aToken
* @param aTokenSymbol The symbol of the aToken
* @param params A set of encoded parameters for additional initialization
**/
event Initialized(
address indexed underlyingAsset,
address indexed pool,
address treasury,
address incentivesController,
uint8 aTokenDecimals,
string aTokenName,
string aTokenSymbol,
bytes params
);
/**
* @notice Initializes the aToken
* @param pool The pool contract that is initializing this contract
* @param treasury The address of the Aave treasury, receiving the fees on this aToken
* @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)
* @param incentivesController The smart contract managing potential incentives distribution
* @param aTokenDecimals The decimals of the aToken, same as the underlying asset's
* @param aTokenName The name of the aToken
* @param aTokenSymbol The symbol of the aToken
* @param params A set of encoded parameters for additional initialization
*/
function initialize(
IPool pool,
address treasury,
address underlyingAsset,
IAaveIncentivesController incentivesController,
uint8 aTokenDecimals,
string calldata aTokenName,
string calldata aTokenSymbol,
bytes calldata params
) external;
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
/**
* @title IAaveIncentivesController
* @author Aave
* @notice Defines the basic interface for an Aave Incentives Controller.
**/
interface IAaveIncentivesController {
/**
* @dev Emitted during `handleAction`, `claimRewards` and `claimRewardsOnBehalf`
* @param user The user that accrued rewards
* @param amount The amount of accrued rewards
*/
event RewardsAccrued(address indexed user, uint256 amount);
event RewardsClaimed(
address indexed user,
address indexed to,
uint256 amount
);
/**
* @dev Emitted during `claimRewards` and `claimRewardsOnBehalf`
* @param user The address that accrued rewards
* @param to The address that will be receiving the rewards
* @param claimer The address that performed the claim
* @param amount The amount of rewards
*/
event RewardsClaimed(
address indexed user,
address indexed to,
address indexed claimer,
uint256 amount
);
/**
* @dev Emitted during `setClaimer`
* @param user The address of the user
* @param claimer The address of the claimer
*/
event ClaimerSet(address indexed user, address indexed claimer);
/**
* @notice Returns the configuration of the distribution for a certain asset
* @param asset The address of the reference asset of the distribution
* @return The asset index
* @return The emission per second
* @return The last updated timestamp
**/
function getAssetData(address asset)
external
view
returns (
uint256,
uint256,
uint256
);
/**
* LEGACY **************************
* @dev Returns the configuration of the distribution for a certain asset
* @param asset The address of the reference asset of the distribution
* @return The asset index, the emission per second and the last updated timestamp
**/
function assets(address asset)
external
view
returns (
uint128,
uint128,
uint256
);
/**
* @notice Whitelists an address to claim the rewards on behalf of another address
* @param user The address of the user
* @param claimer The address of the claimer
*/
function setClaimer(address user, address claimer) external;
/**
* @notice Returns the whitelisted claimer for a certain address (0x0 if not set)
* @param user The address of the user
* @return The claimer address
*/
function getClaimer(address user) external view returns (address);
/**
* @notice Configure assets for a certain rewards emission
* @param assets The assets to incentivize
* @param emissionsPerSecond The emission for each asset
*/
function configureAssets(
address[] calldata assets,
uint256[] calldata emissionsPerSecond
) external;
/**
* @notice Called by the corresponding asset on any update that affects the rewards distribution
* @param asset The address of the user
* @param userBalance The balance of the user of the asset in the pool
* @param totalSupply The total supply of the asset in the pool
**/
function handleAction(
address asset,
uint256 userBalance,
uint256 totalSupply
) external;
/**
* @notice Returns the total of rewards of a user, already accrued + not yet accrued
* @param assets The assets to accumulate rewards for
* @param user The address of the user
* @return The rewards
**/
function getRewardsBalance(address[] calldata assets, address user)
external
view
returns (uint256);
/**
* @notice Claims reward for a user, on the assets of the pool, accumulating the pending rewards
* @param assets The assets to accumulate rewards for
* @param amount Amount of rewards to claim
* @param to Address that will be receiving the rewards
* @return Rewards claimed
**/
function claimRewards(
address[] calldata assets,
uint256 amount,
address to
) external returns (uint256);
/**
* @notice Claims reward for a user on its behalf, on the assets of the pool, accumulating the pending rewards.
* @dev The caller must be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager
* @param assets The assets to accumulate rewards for
* @param amount The amount of rewards to claim
* @param user The address to check and claim rewards
* @param to The address that will be receiving the rewards
* @return The amount of rewards claimed
**/
function claimRewardsOnBehalf(
address[] calldata assets,
uint256 amount,
address user,
address to
) external returns (uint256);
/**
* @notice Returns the unclaimed rewards of the user
* @param user The address of the user
* @return The unclaimed user rewards
*/
function getUserUnclaimedRewards(address user)
external
view
returns (uint256);
/**
* @notice Returns the user index for a specific asset
* @param user The address of the user
* @param asset The asset to incentivize
* @return The user index for the asset
*/
function getUserAssetData(address user, address asset)
external
view
returns (uint256);
/**
* @notice for backward compatibility with previous implementation of the Incentives controller
* @return The address of the reward token
*/
function REWARD_TOKEN() external view returns (address);
/**
* @notice for backward compatibility with previous implementation of the Incentives controller
* @return The precision used in the incentives controller
*/
function PRECISION() external view returns (uint8);
/**
* @dev Gets the distribution end timestamp of the emissions
*/
function DISTRIBUTION_END() external view returns (uint256);
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IPoolAddressesProvider} from "./IPoolAddressesProvider.sol";
import {DataTypes} from "../libraries/DataTypes.sol";
/**
* @title IPool
* @author Aave
* @notice Defines the basic interface for an Aave Pool.
**/
interface IPool {
/**
* @dev Emitted on mintUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens
* @param amount The amount of supplied assets
* @param referralCode The referral code used
**/
event MintUnbacked(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on backUnbacked()
* @param reserve The address of the underlying asset of the reserve
* @param backer The address paying for the backing
* @param amount The amount added as backing
* @param fee The amount paid in fees
**/
event BackUnbacked(
address indexed reserve,
address indexed backer,
uint256 amount,
uint256 fee
);
/**
* @dev Emitted on supply()
* @param reserve The address of the underlying asset of the reserve
* @param user The address initiating the supply
* @param onBehalfOf The beneficiary of the supply, receiving the aTokens
* @param amount The amount supplied
* @param referralCode The referral code used
**/
event Supply(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
uint16 indexed referralCode
);
/**
* @dev Emitted on withdraw()
* @param reserve The address of the underlying asset being withdrawn
* @param user The address initiating the withdrawal, owner of aTokens
* @param to The address that will receive the underlying
* @param amount The amount to be withdrawn
**/
event Withdraw(
address indexed reserve,
address indexed user,
address indexed to,
uint256 amount
);
/**
* @dev Emitted on borrow() and flashLoan() when debt needs to be opened
* @param reserve The address of the underlying asset being borrowed
* @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
* initiator of the transaction on flashLoan()
* @param onBehalfOf The address that will be getting the debt
* @param amount The amount borrowed out
* @param interestRateMode The rate mode: 1 for Stable, 2 for Variable
* @param borrowRate The numeric rate at which the user has borrowed, expressed in ray
* @param referralCode The referral code used
**/
event Borrow(
address indexed reserve,
address user,
address indexed onBehalfOf,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 borrowRate,
uint16 indexed referralCode
);
/**
* @dev Emitted on repay()
* @param reserve The address of the underlying asset of the reserve
* @param user The beneficiary of the repayment, getting his debt reduced
* @param repayer The address of the user initiating the repay(), providing the funds
* @param amount The amount repaid
* @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly
**/
event Repay(
address indexed reserve,
address indexed user,
address indexed repayer,
uint256 amount,
bool useATokens
);
/**
* @dev Emitted on swapBorrowRateMode()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user swapping his rate mode
* @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable
**/
event SwapBorrowRateMode(
address indexed reserve,
address indexed user,
DataTypes.InterestRateMode interestRateMode
);
/**
* @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets
* @param asset The address of the underlying asset of the reserve
* @param totalDebt The total isolation mode debt for the reserve
*/
event IsolationModeTotalDebtUpdated(
address indexed asset,
uint256 totalDebt
);
/**
* @dev Emitted when the user selects a certain asset category for eMode
* @param user The address of the user
* @param categoryId The category id
**/
event UserEModeSet(address indexed user, uint8 categoryId);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
**/
event ReserveUsedAsCollateralEnabled(
address indexed reserve,
address indexed user
);
/**
* @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user enabling the usage as collateral
**/
event ReserveUsedAsCollateralDisabled(
address indexed reserve,
address indexed user
);
/**
* @dev Emitted on rebalanceStableBorrowRate()
* @param reserve The address of the underlying asset of the reserve
* @param user The address of the user for which the rebalance has been executed
**/
event RebalanceStableBorrowRate(
address indexed reserve,
address indexed user
);
/**
* @dev Emitted on flashLoan()
* @param target The address of the flash loan receiver contract
* @param initiator The address initiating the flash loan
* @param asset The address of the asset being flash borrowed
* @param amount The amount flash borrowed
* @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt
* @param premium The fee flash borrowed
* @param referralCode The referral code used
**/
event FlashLoan(
address indexed target,
address initiator,
address indexed asset,
uint256 amount,
DataTypes.InterestRateMode interestRateMode,
uint256 premium,
uint16 indexed referralCode
);
/**
* @dev Emitted when a borrower is liquidated.
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param liquidatedCollateralAmount The amount of collateral received by the liquidator
* @param liquidator The address of the liquidator
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
**/
event LiquidationCall(
address indexed collateralAsset,
address indexed debtAsset,
address indexed user,
uint256 debtToCover,
uint256 liquidatedCollateralAmount,
address liquidator,
bool receiveAToken
);
/**
* @dev Emitted when the state of a reserve is updated.
* @param reserve The address of the underlying asset of the reserve
* @param liquidityRate The next liquidity rate
* @param stableBorrowRate The next stable borrow rate
* @param variableBorrowRate The next variable borrow rate
* @param liquidityIndex The next liquidity index
* @param variableBorrowIndex The next variable borrow index
**/
event ReserveDataUpdated(
address indexed reserve,
uint256 liquidityRate,
uint256 stableBorrowRate,
uint256 variableBorrowRate,
uint256 liquidityIndex,
uint256 variableBorrowIndex
);
/**
* @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest.
* @param reserve The address of the reserve
* @param amountMinted The amount minted to the treasury
**/
event MintedToTreasury(address indexed reserve, uint256 amountMinted);
/**
* @dev Mints an `amount` of aTokens to the `onBehalfOf`
* @param asset The address of the underlying asset to mint
* @param amount The amount to mint
* @param onBehalfOf The address that will receive the aTokens
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/
function mintUnbacked(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
/**
* @dev Back the current unbacked underlying with `amount` and pay `fee`.
* @param asset The address of the underlying asset to back
* @param amount The amount to back
* @param fee The amount paid in fees
**/
function backUnbacked(
address asset,
uint256 amount,
uint256 fee
) external;
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/
function supply(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
/**
* @notice Supply with transfer approval of asset to be supplied done via permit function
* see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param deadline The deadline timestamp that the permit is valid
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param permitV The V parameter of ERC712 permit sig
* @param permitR The R parameter of ERC712 permit sig
* @param permitS The S parameter of ERC712 permit sig
**/
function supplyWithPermit(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode,
uint256 deadline,
uint8 permitV,
bytes32 permitR,
bytes32 permitS
) external;
/**
* @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
* E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
* @param asset The address of the underlying asset to withdraw
* @param amount The underlying amount to be withdrawn
* - Send the value type(uint256).max in order to withdraw the whole aToken balance
* @param to The address that will receive the underlying, same as msg.sender if the user
* wants to receive it on his own wallet, or a different address if the beneficiary is a
* different wallet
* @return The final amount withdrawn
**/
function withdraw(
address asset,
uint256 amount,
address to
) external returns (uint256);
/**
* @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
* already supplied enough collateral, or he was given enough allowance by a credit delegator on the
* corresponding debt token (StableDebtToken or VariableDebtToken)
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* and 100 stable/variable debt tokens, depending on the `interestRateMode`
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself
* calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
* if he has been given credit delegation allowance
**/
function borrow(
address asset,
uint256 amount,
uint256 interestRateMode,
uint16 referralCode,
address onBehalfOf
) external;
/**
* @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
* - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @return The final amount repaid
**/
function repay(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf
) external returns (uint256);
/**
* @notice Repay with transfer approval of asset to be repaid done via permit function
* see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
* @param deadline The deadline timestamp that the permit is valid
* @param permitV The V parameter of ERC712 permit sig
* @param permitR The R parameter of ERC712 permit sig
* @param permitS The S parameter of ERC712 permit sig
* @return The final amount repaid
**/
function repayWithPermit(
address asset,
uint256 amount,
uint256 interestRateMode,
address onBehalfOf,
uint256 deadline,
uint8 permitV,
bytes32 permitR,
bytes32 permitS
) external returns (uint256);
/**
* @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the
* equivalent debt tokens
* - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens
* @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken
* balance is not enough to cover the whole debt
* @param asset The address of the borrowed underlying asset previously borrowed
* @param amount The amount to repay
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @return The final amount repaid
**/
function repayWithATokens(
address asset,
uint256 amount,
uint256 interestRateMode
) external returns (uint256);
/**
* @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa
* @param asset The address of the underlying asset borrowed
* @param interestRateMode The rate mode that the user wants to swap to: 1 for Stable, 2 for Variable
**/
function swapBorrowRateMode(address asset, uint256 interestRateMode)
external;
/**
* @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
* - Users can be rebalanced if the following conditions are satisfied:
* 1. Usage ratio is above 95%
* 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too
* much has been borrowed at a stable rate and suppliers are not earning enough
* @param asset The address of the underlying asset borrowed
* @param user The address of the user to be rebalanced
**/
function rebalanceStableBorrowRate(address asset, address user) external;
/**
* @notice Allows suppliers to enable/disable a specific supplied asset as collateral
* @param asset The address of the underlying asset supplied
* @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise
**/
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
external;
/**
* @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user The address of the borrower getting liquidated
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
**/
function liquidationCall(
address collateralAsset,
address debtAsset,
address user,
uint256 debtToCover,
bool receiveAToken
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://developers.aave.com
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface
* @param assets The addresses of the assets being flash-borrowed
* @param amounts The amounts of the assets being flash-borrowed
* @param interestRateModes Types of the debt to open if the flash loan is not returned:
* 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
* 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/
function flashLoan(
address receiverAddress,
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata interestRateModes,
address onBehalfOf,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned.
* @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
* into consideration. For further details please visit https://developers.aave.com
* @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface
* @param asset The address of the asset being flash-borrowed
* @param amount The amount of the asset being flash-borrowed
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode The code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/
function flashLoanSimple(
address receiverAddress,
address asset,
uint256 amount,
bytes calldata params,
uint16 referralCode
) external;
/**
* @notice Returns the user account data across all the reserves
* @param user The address of the user
* @return totalCollateralBase The total collateral of the user in the base currency used by the price feed
* @return totalDebtBase The total debt of the user in the base currency used by the price feed
* @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed
* @return currentLiquidationThreshold The liquidation threshold of the user
* @return ltv The loan to value of The user
* @return healthFactor The current health factor of the user
**/
function getUserAccountData(address user)
external
view
returns (
uint256 totalCollateralBase,
uint256 totalDebtBase,
uint256 availableBorrowsBase,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
);
/**
* @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an
* interest rate strategy
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param aTokenAddress The address of the aToken that will be assigned to the reserve
* @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve
* @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve
* @param interestRateStrategyAddress The address of the interest rate strategy contract
**/
function initReserve(
address asset,
address aTokenAddress,
address stableDebtAddress,
address variableDebtAddress,
address interestRateStrategyAddress
) external;
/**
* @notice Drop a reserve
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
**/
function dropReserve(address asset) external;
/**
* @notice Updates the address of the interest rate strategy contract
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param rateStrategyAddress The address of the interest rate strategy contract
**/
function setReserveInterestRateStrategyAddress(
address asset,
address rateStrategyAddress
) external;
/**
* @notice Sets the configuration bitmap of the reserve as a whole
* @dev Only callable by the PoolConfigurator contract
* @param asset The address of the underlying asset of the reserve
* @param configuration The new configuration bitmap
**/
function setConfiguration(
address asset,
DataTypes.ReserveConfigurationMap calldata configuration
) external;
/**
* @notice Returns the configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The configuration of the reserve
**/
function getConfiguration(address asset)
external
view
returns (DataTypes.ReserveConfigurationMap memory);
/**
* @notice Returns the configuration of the user across all the reserves
* @param user The user address
* @return The configuration of the user
**/
function getUserConfiguration(address user)
external
view
returns (DataTypes.UserConfigurationMap memory);
/**
* @notice Returns the normalized income normalized income of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve's normalized income
*/
function getReserveNormalizedIncome(address asset)
external
view
returns (uint256);
/**
* @notice Returns the normalized variable debt per unit of asset
* @param asset The address of the underlying asset of the reserve
* @return The reserve normalized variable debt
*/
function getReserveNormalizedVariableDebt(address asset)
external
view
returns (uint256);
/**
* @notice Returns the state and configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The state and configuration data of the reserve
**/
function getReserveData(address asset)
external
view
returns (DataTypes.ReserveData memory);
/**
* @notice Validates and finalizes an aToken transfer
* @dev Only callable by the overlying aToken of the `asset`
* @param asset The address of the underlying asset of the aToken
* @param from The user from which the aTokens are transferred
* @param to The user receiving the aTokens
* @param amount The amount being transferred/withdrawn
* @param balanceFromBefore The aToken balance of the `from` user before the transfer
* @param balanceToBefore The aToken balance of the `to` user before the transfer
*/
function finalizeTransfer(
address asset,
address from,
address to,
uint256 amount,
uint256 balanceFromBefore,
uint256 balanceToBefore
) external;
/**
* @notice Returns the list of the initialized reserves
* @dev It does not include dropped reserves
* @return The addresses of the reserves
**/
function getReservesList() external view returns (address[] memory);
/**
* @notice Returns the PoolAddressesProvider connected to this contract
* @return The address of the PoolAddressesProvider
**/
function ADDRESSES_PROVIDER()
external
view
returns (IPoolAddressesProvider);
/**
* @notice Updates the protocol fee on the bridging
* @param bridgeProtocolFee The part of the premium sent to the protocol treasury
*/
function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external;
/**
* @notice Updates flash loan premiums. Flash loan premium consists of two parts:
* - A part is sent to aToken holders as extra, one time accumulated interest
* - A part is collected by the protocol treasury
* @dev The total premium is calculated on the total borrowed amount
* @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal`
* @dev Only callable by the PoolConfigurator contract
* @param flashLoanPremiumTotal The total premium, expressed in bps
* @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps
*/
function updateFlashloanPremiums(
uint128 flashLoanPremiumTotal,
uint128 flashLoanPremiumToProtocol
) external;
/**
* @notice Configures a new category for the eMode.
* @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category.
* The category 0 is reserved as it's the default for volatile assets
* @param id The id of the category
* @param config The configuration of the category
*/
function configureEModeCategory(
uint8 id,
DataTypes.EModeCategory memory config
) external;
/**
* @notice Returns the data of an eMode category
* @param id The id of the category
* @return The configuration data of the category
*/
function getEModeCategoryData(uint8 id)
external
view
returns (DataTypes.EModeCategory memory);
/**
* @notice Allows a user to use the protocol in eMode
* @param categoryId The id of the category
*/
function setUserEMode(uint8 categoryId) external;
/**
* @notice Returns the eMode the user is using
* @param user The address of the user
* @return The eMode id
*/
function getUserEMode(address user) external view returns (uint256);
/**
* @notice Resets the isolation mode total debt of the given asset to zero
* @dev It requires the given asset has zero debt ceiling
* @param asset The address of the underlying asset to reset the isolationModeTotalDebt
*/
function resetIsolationModeTotalDebt(address asset) external;
/**
* @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate
* @return The percentage of available liquidity to borrow, expressed in bps
*/
function MAX_STABLE_RATE_BORROW_SIZE_PERCENT()
external
view
returns (uint256);
/**
* @notice Returns the total fee on flash loans
* @return The total fee on flashloans
*/
function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);
/**
* @notice Returns the part of the bridge fees sent to protocol
* @return The bridge fee sent to the protocol treasury
*/
function BRIDGE_PROTOCOL_FEE() external view returns (uint256);
/**
* @notice Returns the part of the flashloan fees sent to protocol
* @return The flashloan fee sent to the protocol treasury
*/
function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128);
/**
* @notice Returns the maximum number of reserves supported to be listed in this Pool
* @return The maximum number of reserves supported
*/
function MAX_NUMBER_RESERVES() external view returns (uint16);
/**
* @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens
* @param assets The list of reserves for which the minting needs to be executed
**/
function mintToTreasury(address[] calldata assets) external;
/**
* @notice Rescue and transfer tokens locked in this contract
* @param token The address of the token
* @param to The address of the recipient
* @param amount The amount of token to transfer
*/
function rescueTokens(
address token,
address to,
uint256 amount
) external;
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @dev Deprecated: Use the `supply` function instead
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/
function deposit(
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
/**
* @title IPoolAddressesProvider
* @author Aave
* @notice Defines the basic interface for a Pool Addresses Provider.
**/
interface IPoolAddressesProvider {
/**
* @dev Emitted when the market identifier is updated.
* @param oldMarketId The old id of the market
* @param newMarketId The new id of the market
*/
event MarketIdSet(string indexed oldMarketId, string indexed newMarketId);
/**
* @dev Emitted when the pool is updated.
* @param oldAddress The old address of the Pool
* @param newAddress The new address of the Pool
*/
event PoolUpdated(address indexed oldAddress, address indexed newAddress);
/**
* @dev Emitted when the pool configurator is updated.
* @param oldAddress The old address of the PoolConfigurator
* @param newAddress The new address of the PoolConfigurator
*/
event PoolConfiguratorUpdated(
address indexed oldAddress,
address indexed newAddress
);
/**
* @dev Emitted when the price oracle is updated.
* @param oldAddress The old address of the PriceOracle
* @param newAddress The new address of the PriceOracle
*/
event PriceOracleUpdated(
address indexed oldAddress,
address indexed newAddress
);
/**
* @dev Emitted when the ACL manager is updated.
* @param oldAddress The old address of the ACLManager
* @param newAddress The new address of the ACLManager
*/
event ACLManagerUpdated(
address indexed oldAddress,
address indexed newAddress
);
/**
* @dev Emitted when the ACL admin is updated.
* @param oldAddress The old address of the ACLAdmin
* @param newAddress The new address of the ACLAdmin
*/
event ACLAdminUpdated(
address indexed oldAddress,
address indexed newAddress
);
/**
* @dev Emitted when the price oracle sentinel is updated.
* @param oldAddress The old address of the PriceOracleSentinel
* @param newAddress The new address of the PriceOracleSentinel
*/
event PriceOracleSentinelUpdated(
address indexed oldAddress,
address indexed newAddress
);
/**
* @dev Emitted when the pool data provider is updated.
* @param oldAddress The old address of the PoolDataProvider
* @param newAddress The new address of the PoolDataProvider
*/
event PoolDataProviderUpdated(
address indexed oldAddress,
address indexed newAddress
);
/**
* @dev Emitted when a new proxy is created.
* @param id The identifier of the proxy
* @param proxyAddress The address of the created proxy contract
* @param implementationAddress The address of the implementation contract
*/
event ProxyCreated(
bytes32 indexed id,
address indexed proxyAddress,
address indexed implementationAddress
);
/**
* @dev Emitted when a new non-proxied contract address is registered.
* @param id The identifier of the contract
* @param oldAddress The address of the old contract
* @param newAddress The address of the new contract
*/
event AddressSet(
bytes32 indexed id,
address indexed oldAddress,
address indexed newAddress
);
/**
* @dev Emitted when the implementation of the proxy registered with id is updated
* @param id The identifier of the contract
* @param proxyAddress The address of the proxy contract
* @param oldImplementationAddress The address of the old implementation contract
* @param newImplementationAddress The address of the new implementation contract
*/
event AddressSetAsProxy(
bytes32 indexed id,
address indexed proxyAddress,
address oldImplementationAddress,
address indexed newImplementationAddress
);
/**
* @notice Returns the id of the Aave market to which this contract points to.
* @return The market id
**/
function getMarketId() external view returns (string memory);
/**
* @notice Associates an id with a specific PoolAddressesProvider.
* @dev This can be used to create an onchain registry of PoolAddressesProviders to
* identify and validate multiple Aave markets.
* @param newMarketId The market id
*/
function setMarketId(string calldata newMarketId) external;
/**
* @notice Returns an address by its identifier.
* @dev The returned address might be an EOA or a contract, potentially proxied
* @dev It returns ZERO if there is no registered address with the given id
* @param id The id
* @return The address of the registered for the specified id
*/
function getAddress(bytes32 id) external view returns (address);
/**
* @notice General function to update the implementation of a proxy registered with
* certain `id`. If there is no proxy registered, it will instantiate one and
* set as implementation the `newImplementationAddress`.
* @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit
* setter function, in order to avoid unexpected consequences
* @param id The id
* @param newImplementationAddress The address of the new implementation
*/
function setAddressAsProxy(bytes32 id, address newImplementationAddress)
external;
/**
* @notice Sets an address for an id replacing the address saved in the addresses map.
* @dev IMPORTANT Use this function carefully, as it will do a hard replacement
* @param id The id
* @param newAddress The address to set
*/
function setAddress(bytes32 id, address newAddress) external;
/**
* @notice Returns the address of the Pool proxy.
* @return The Pool proxy address
**/
function getPool() external view returns (address);
/**
* @notice Updates the implementation of the Pool, or creates a proxy
* setting the new `pool` implementation when the function is called for the first time.
* @param newPoolImpl The new Pool implementation
**/
function setPoolImpl(address newPoolImpl) external;
/**
* @notice Returns the address of the PoolConfigurator proxy.
* @return The PoolConfigurator proxy address
**/
function getPoolConfigurator() external view returns (address);
/**
* @notice Updates the implementation of the PoolConfigurator, or creates a proxy
* setting the new `PoolConfigurator` implementation when the function is called for the first time.
* @param newPoolConfiguratorImpl The new PoolConfigurator implementation
**/
function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external;
/**
* @notice Returns the address of the price oracle.
* @return The address of the PriceOracle
*/
function getPriceOracle() external view returns (address);
/**
* @notice Updates the address of the price oracle.
* @param newPriceOracle The address of the new PriceOracle
*/
function setPriceOracle(address newPriceOracle) external;
/**
* @notice Returns the address of the ACL manager.
* @return The address of the ACLManager
*/
function getACLManager() external view returns (address);
/**
* @notice Updates the address of the ACL manager.
* @param newAclManager The address of the new ACLManager
**/
function setACLManager(address newAclManager) external;
/**
* @notice Returns the address of the ACL admin.
* @return The address of the ACL admin
*/
function getACLAdmin() external view returns (address);
/**
* @notice Updates the address of the ACL admin.
* @param newAclAdmin The address of the new ACL admin
*/
function setACLAdmin(address newAclAdmin) external;
/**
* @notice Returns the address of the price oracle sentinel.
* @return The address of the PriceOracleSentinel
*/
function getPriceOracleSentinel() external view returns (address);
/**
* @notice Updates the address of the price oracle sentinel.
* @param newPriceOracleSentinel The address of the new PriceOracleSentinel
**/
function setPriceOracleSentinel(address newPriceOracleSentinel) external;
/**
* @notice Returns the address of the data provider.
* @return The address of the DataProvider
*/
function getPoolDataProvider() external view returns (address);
/**
* @notice Updates the address of the data provider.
* @param newDataProvider The address of the new DataProvider
**/
function setPoolDataProvider(address newDataProvider) external;
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
library DataTypes {
struct ReserveData {
//stores the reserve configuration
ReserveConfigurationMap configuration;
//the liquidity index. Expressed in ray
uint128 liquidityIndex;
//the current supply rate. Expressed in ray
uint128 currentLiquidityRate;
//variable borrow index. Expressed in ray
uint128 variableBorrowIndex;
//the current variable borrow rate. Expressed in ray
uint128 currentVariableBorrowRate;
//the current stable borrow rate. Expressed in ray
uint128 currentStableBorrowRate;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//aToken address
address aTokenAddress;
//stableDebtToken address
address stableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
//address of the interest rate strategy
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
//the outstanding unbacked aTokens minted through the bridging feature
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
}
struct ReserveConfigurationMap {
//bit 0-15: LTV
//bit 16-31: Liq. threshold
//bit 32-47: Liq. bonus
//bit 48-55: Decimals
//bit 56: reserve is active
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: stable rate borrowing enabled
//bit 60: asset is paused
//bit 61: borrowing in isolation mode is enabled
//bit 62-63: reserved
//bit 64-79: reserve factor
//bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap
//bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap
//bit 152-167 liquidation protocol fee
//bit 168-175 eMode category
//bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
//bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
//bit 252-255 unused
uint256 data;
}
struct UserConfigurationMap {
/**
* @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset.
* The first bit indicates if an asset is used as collateral by the user, the second whether an
* asset is borrowed by the user.
*/
uint256 data;
}
struct EModeCategory {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
// each eMode category may or may not have a custom oracle to override the individual assets price oracles
address priceSource;
string label;
}
enum InterestRateMode {
NONE,
STABLE,
VARIABLE
}
struct ReserveCache {
uint256 currScaledVariableDebt;
uint256 nextScaledVariableDebt;
uint256 currPrincipalStableDebt;
uint256 currAvgStableBorrowRate;
uint256 currTotalStableDebt;
uint256 nextAvgStableBorrowRate;
uint256 nextTotalStableDebt;
uint256 currLiquidityIndex;
uint256 nextLiquidityIndex;
uint256 currVariableBorrowIndex;
uint256 nextVariableBorrowIndex;
uint256 currLiquidityRate;
uint256 currVariableBorrowRate;
uint256 reserveFactor;
ReserveConfigurationMap reserveConfiguration;
address aTokenAddress;
address stableDebtTokenAddress;
address variableDebtTokenAddress;
uint40 reserveLastUpdateTimestamp;
uint40 stableDebtLastUpdateTimestamp;
}
struct ExecuteLiquidationCallParams {
uint256 reservesCount;
uint256 debtToCover;
address collateralAsset;
address debtAsset;
address user;
bool receiveAToken;
address priceOracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteSupplyParams {
address asset;
uint256 amount;
address onBehalfOf;
uint16 referralCode;
}
struct ExecuteBorrowParams {
address asset;
address user;
address onBehalfOf;
uint256 amount;
InterestRateMode interestRateMode;
uint16 referralCode;
bool releaseUnderlying;
uint256 maxStableRateBorrowSizePercent;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteRepayParams {
address asset;
uint256 amount;
InterestRateMode interestRateMode;
address onBehalfOf;
bool useATokens;
}
struct ExecuteWithdrawParams {
address asset;
uint256 amount;
address to;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
}
struct ExecuteSetUserEModeParams {
uint256 reservesCount;
address oracle;
uint8 categoryId;
}
struct FinalizeTransferParams {
address asset;
address from;
address to;
uint256 amount;
uint256 balanceFromBefore;
uint256 balanceToBefore;
uint256 reservesCount;
address oracle;
uint8 fromEModeCategory;
}
struct FlashloanParams {
address receiverAddress;
address[] assets;
uint256[] amounts;
uint256[] interestRateModes;
address onBehalfOf;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
uint256 maxStableRateBorrowSizePercent;
uint256 reservesCount;
address addressesProvider;
uint8 userEModeCategory;
bool isAuthorizedFlashBorrower;
}
struct FlashloanSimpleParams {
address receiverAddress;
address asset;
uint256 amount;
bytes params;
uint16 referralCode;
uint256 flashLoanPremiumToProtocol;
uint256 flashLoanPremiumTotal;
}
struct FlashLoanRepaymentParams {
uint256 amount;
uint256 totalPremium;
uint256 flashLoanPremiumToProtocol;
address asset;
address receiverAddress;
uint16 referralCode;
}
struct CalculateUserAccountDataParams {
UserConfigurationMap userConfig;
uint256 reservesCount;
address user;
address oracle;
uint8 userEModeCategory;
}
struct ValidateBorrowParams {
ReserveCache reserveCache;
UserConfigurationMap userConfig;
address asset;
address userAddress;
uint256 amount;
InterestRateMode interestRateMode;
uint256 maxStableLoanPercent;
uint256 reservesCount;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
bool isolationModeActive;
address isolationModeCollateralAddress;
uint256 isolationModeDebtCeiling;
}
struct ValidateLiquidationCallParams {
ReserveCache debtReserveCache;
uint256 totalDebt;
uint256 healthFactor;
address priceOracleSentinel;
}
struct CalculateInterestRatesParams {
uint256 unbacked;
uint256 liquidityAdded;
uint256 liquidityTaken;
uint256 totalStableDebt;
uint256 totalVariableDebt;
uint256 averageStableBorrowRate;
uint256 reserveFactor;
address reserve;
address aToken;
}
struct InitReserveParams {
address asset;
address aTokenAddress;
address stableDebtAddress;
address variableDebtAddress;
address interestRateStrategyAddress;
uint16 reservesCount;
uint16 maxNumberReserves;
}
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IPoolAddressesProvider} from "./IPoolAddressesProvider.sol";
import {IPool} from "./IPool.sol";
/**
* @title IFlashLoanReceiver
* @author Aave
* @notice Defines the basic interface of a flashloan-receiver contract.
* @dev Implement this interface to develop a flashloan-compatible flashLoanReceiver contract
**/
interface IFlashLoanReceiver {
/**
* @notice Executes an operation after receiving the flash-borrowed assets
* @dev Ensure that the contract can return the debt + premium, e.g., has
* enough funds to repay and has approved the Pool to pull the total amount
* @param assets The addresses of the flash-borrowed assets
* @param amounts The amounts of the flash-borrowed assets
* @param premiums The fee of each flash-borrowed asset
* @param initiator The address of the flashloan initiator
* @param params The byte-encoded params passed when initiating the flashloan
* @return True if the execution of the operation succeeds, false otherwise
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
) external returns (bool);
function ADDRESSES_PROVIDER()
external
view
returns (IPoolAddressesProvider);
function POOL() external view returns (IPool);
}// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
import {IRewardsDistributor} from "./IRewardsDistributor.sol";
import {ITransferStrategyBase} from "./ITransferStrategyBase.sol";
import {IEACAggregatorProxy} from "./IEACAggregatorProxy.sol";
import {RewardsDistributorTypes} from "../libraries/RewardsDistributorTypes.sol";
interface IRewardsController is IRewardsDistributor {
event ClaimerSet(address indexed user, address indexed claimer);
event RewardsClaimed(
address indexed user,
address indexed reward,
address indexed to,
address claimer,
uint256 amount
);
event TransferStrategyInstalled(
address indexed reward,
address indexed transferStrategy
);
event RewardOracleUpdated(
address indexed reward,
address indexed rewardOracle
);
/**
* @dev Whitelists an address to claim the rewards on behalf of another address
* @param user The address of the user
* @param claimer The address of the claimer
*/
function setClaimer(address user, address claimer) external;
/**
* @dev Sets a TransferStrategy logic contract that determines the logic of the rewards transfer
* @param reward The address of the reward token
* @param transferStrategy The address of the TransferStrategy logic contract
*/
function setTransferStrategy(
address reward,
ITransferStrategyBase transferStrategy
) external;
/**
* @dev Sets an Aave Oracle contract to enforce rewards with a source of value.
* @notice At the moment of reward configuration, the Incentives Controller performs
* a check to see if the reward asset oracle is compatible with IEACAggregator proxy.
* This check is enforced for integrators to be able to show incentives at
* the current Aave UI without the need to setup an external price registry
* @param reward The address of the reward to set the price aggregator
* @param rewardOracle The address of price aggregator that follows IEACAggregatorProxy interface
*/
function setRewardOracle(address reward, IEACAggregatorProxy rewardOracle)
external;
/**
* @dev Get the price aggregator oracle address
* @param reward The address of the reward
* @return The price oracle of the reward
*/
function getRewardOracle(address reward) external view returns (address);
/**
* @dev Returns the whitelisted claimer for a certain address (0x0 if not set)
* @param user The address of the user
* @return The claimer address
*/
function getClaimer(address user) external view returns (address);
/**
* @dev Returns the Transfer Strategy implementation contract address being used for a reward address
* @param reward The address of the reward
* @return The address of the TransferStrategy contract
*/
function getTransferStrategy(address reward)
external
view
returns (address);
/**
* @dev Configure assets to incentivize with an emission of rewards per second until the end of distribution.
* @param config The assets configuration input, the list of structs contains the following fields:
* uint104 emissionPerSecond: The emission per second following rewards unit decimals.
* uint256 totalSupply: The total supply of the asset to incentivize
* uint40 distributionEnd: The end of the distribution of the incentives for an asset
* address asset: The asset address to incentivize
* address reward: The reward token address
* ITransferStrategy transferStrategy: The TransferStrategy address with the install hook and claim logic.
* IEACAggregatorProxy rewardOracle: The Price Oracle of a reward to visualize the incentives at the UI Frontend.
* Must follow Chainlink Aggregator IEACAggregatorProxy interface to be compatible.
*/
function configureAssets(
RewardsDistributorTypes.RewardsConfigInput[] memory config
) external;
/**
* @dev Called by the corresponding asset on any update that affects the rewards distribution
* @param user The address of the user
* @param userBalance The user balance of the asset
* @param totalSupply The total supply of the asset
**/
function handleAction(
address user,
uint256 userBalance,
uint256 totalSupply
) external;
/**
* @dev Claims reward for an user to the desired address, on all the assets of the lending pool, accumulating the pending rewards
* @param assets List of assets to check eligible distributions before claiming rewards
* @param amount Amount of rewards to claim
* @param to Address that will be receiving the rewards
* @param reward Address of the reward token
* @return Rewards claimed
**/
function claimRewards(
address[] calldata assets,
uint256 amount,
address to,
address reward
) external returns (uint256);
/**
* @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must
* be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager
* @param assets List of assets to check eligible distributions before claiming rewards
* @param amount Amount of rewards to claim
* @param user Address to check and claim rewards
* @param to Address that will be receiving the rewards
* @param reward Address of the reward token
* @return Rewards claimed
**/
function claimRewardsOnBehalf(
address[] calldata assets,
uint256 amount,
address user,
address to,
address reward
) external returns (uint256);
/**
* @dev Claims reward for msg.sender, on all the assets of the lending pool, accumulating the pending rewards
* @param assets List of assets to check eligible distributions before claiming rewards
* @param amount Amount of rewards to claim
* @param reward Address of the reward token
* @return Rewards claimed
**/
function claimRewardsToSelf(
address[] calldata assets,
uint256 amount,
address reward
) external returns (uint256);
/**
* @dev Claims all rewards for an user to the desired address, on all the assets of the lending pool, accumulating the pending rewards
* @param assets List of assets to check eligible distributions before claiming rewards
* @param to Address that will be receiving the rewards
* @return rewardsList List of addresses of the reward tokens and claimedAmounts, the list that contains the claimed amount per reward, following same order as "rewardList"
* @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardList"
**/
function claimAllRewards(address[] calldata assets, address to)
external
returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
/**
* @dev Claims all rewards for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must
* be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager
* @param assets List of assets to check eligible distributions before claiming rewards
* @param user Address to check and claim rewards
* @param to Address that will be receiving the rewards
* @return rewardsList List of addresses of the reward tokens and claimedAmounts, the list that contains the claimed amount per reward, following same order as "rewardList"
* @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList"
**/
function claimAllRewardsOnBehalf(
address[] calldata assets,
address user,
address to
)
external
returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
/**
* @dev Claims all reward for msg.sender, on all the assets of the lending pool, accumulating the pending rewards
* @param assets List of assets to check eligible distributions before claiming rewards
* @return rewardsList List of addresses of the reward tokens and claimedAmounts, the list that contains the claimed amount per reward, following same order as "rewardList"
* @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardsList"
**/
function claimAllRewardsToSelf(address[] calldata assets)
external
returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
}// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
import {RewardsDistributorTypes} from "../libraries/RewardsDistributorTypes.sol";
interface IRewardsDistributor {
event AssetConfigUpdated(
address indexed asset,
address indexed reward,
uint256 emission,
uint256 distributionEnd
);
event AssetIndexUpdated(
address indexed asset,
address indexed reward,
uint256 index
);
event UserIndexUpdated(
address indexed user,
address indexed asset,
address indexed reward,
uint256 index
);
event RewardsAccrued(
address indexed user,
address indexed reward,
uint256 amount
);
/**
* @dev Sets the end date for the distribution
* @param asset The asset to incentivize
* @param reward The reward token that incentives the asset
* @param distributionEnd The end date of the incentivization, in unix time format
**/
function setDistributionEnd(
address asset,
address reward,
uint32 distributionEnd
) external;
/**
* @dev Gets the end date for the distribution
* @param asset The incentivized asset
* @param reward The reward token of the incentivized asset
* @return The timestamp with the end of the distribution, in unix time format
**/
function getDistributionEnd(address asset, address reward)
external
view
returns (uint256);
/**
* @dev Returns the index of an user on a reward distribution
* @param user Address of the user
* @param asset The incentivized asset
* @param reward The reward token of the incentivized asset
* @return The current user asset index in storage, not including new distributions
**/
function getUserAssetData(
address user,
address asset,
address reward
) external view returns (uint256);
/**
* @dev Returns the configuration of the distribution for a certain asset
* @param asset The incentivized asset
* @param reward The reward token of the incentivized asset
* @return The asset index, the emission per second, the last updated timestamp and the distribution end timestamp
**/
function getRewardsData(address asset, address reward)
external
view
returns (
uint256,
uint256,
uint256,
uint256
);
/**
* @dev Returns the list of available reward token addresses of an incentivized asset
* @param asset The incentivized asset
* @return List of rewards addresses of the input asset
**/
function getRewardsByAsset(address asset)
external
view
returns (address[] memory);
/**
* @dev Returns the list of available reward addresses
* @return List of rewards supported in this contract
**/
function getRewardsList() external view returns (address[] memory);
/**
* @dev Returns a single rewards balance of an user from contract storage state, not including virtually accrued rewards since last distribution.
* @param user The address of the user
* @param reward The address of the reward token
* @return Unclaimed rewards, from storage
**/
function getUserUnclaimedRewardsFromStorage(address user, address reward)
external
view
returns (uint256);
/**
* @dev Returns a single rewards balance of an user, including virtually accrued and unrealized claimable rewards.
* @param assets List of incentivized assets to check eligible distributions
* @param user The address of the user
* @param reward The address of the reward token
* @return The rewards amount
**/
function getUserRewardsBalance(
address[] calldata assets,
address user,
address reward
) external view returns (uint256);
/**
* @dev Returns a list all rewards of an user, including already accrued and unrealized claimable rewards
* @param assets List of incentivized assets to check eligible distributions
* @param user The address of the user
* @return The function returns a Tuple of rewards list and the unclaimed rewards list
**/
function getAllUserRewardsBalance(address[] calldata assets, address user)
external
view
returns (address[] memory, uint256[] memory);
/**
* @dev Returns the decimals of an asset to calculate the distribution delta
* @param asset The address to retrieve decimals saved at storage
* @return The decimals of an underlying asset
*/
function getAssetDecimals(address asset) external view returns (uint8);
}// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
import {ITransferStrategyBase} from "../interfaces/ITransferStrategyBase.sol";
import {IEACAggregatorProxy} from "../interfaces/IEACAggregatorProxy.sol";
library RewardsDistributorTypes {
struct RewardsConfigInput {
uint88 emissionPerSecond;
uint256 totalSupply;
uint32 distributionEnd;
address asset;
address reward;
ITransferStrategyBase transferStrategy;
IEACAggregatorProxy rewardOracle;
}
struct UserAssetStatsInput {
address underlyingAsset;
uint256 userBalance;
uint256 totalSupply;
}
}// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
interface ITransferStrategyBase {
event EmergencyWithdrawal(
address indexed caller,
address indexed token,
address indexed to,
uint256 amount
);
/**
* @dev Perform custom transfer logic via delegate call from source contract to a TransferStrategy implementation
* @param to Account to transfer rewards
* @param reward Address of the reward token
* @param amount Amount to transfer to the "to" address parameter
* @return Returns true bool if transfer logic succeeds
*/
function performTransfer(
address to,
address reward,
uint256 amount
) external returns (bool);
/**
* @return Returns the address of the Incentives Controller
*/
function getIncentivesController() external view returns (address);
/**
* @return Returns the address of the Rewards admin
*/
function getRewardsAdmin() external view returns (address);
/**
* @dev Perform an emergency token withdrawal only callable by the Rewards admin
* @param token Address of the token to withdraw funds from this contract
* @param to Address of the recipient of the withdrawal
* @param amount Amount of the withdrawal
*/
function emergencyWithdrawal(
address token,
address to,
uint256 amount
) external;
}// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;
interface IEACAggregatorProxy {
function decimals() external view returns (uint8);
function latestAnswer() external view returns (int256);
function latestTimestamp() external view returns (uint256);
function latestRound() external view returns (uint256);
function getAnswer(uint256 roundId) external view returns (int256);
function getTimestamp(uint256 roundId) external view returns (uint256);
event AnswerUpdated(
int256 indexed current,
uint256 indexed roundId,
uint256 timestamp
);
event NewRound(uint256 indexed roundId, address indexed startedBy);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IRouter {
function pairFor(
address tokenA,
address tokenB,
bool stable
) external view returns (address pair);
}
interface IWETH {
function deposit() external payable returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function withdraw(uint256) external returns (uint256);
}
interface IVeloRouter is IRouter {
struct route {
address from;
address to;
bool stable;
}
function factory() external view returns (address);
function weth() external view returns (IWETH);
function sortTokens(address tokenA, address tokenB) external pure returns (address token0, address token1);
function pairFor(
address tokenA,
address tokenB,
bool stable
) external view returns (address pair);
function getReserves(
address tokenA,
address tokenB,
bool stable
) external view returns (uint256 reserveA, uint256 reserveB);
function getAmountOut(
uint256 amountIn,
address tokenIn,
address tokenOut
) external view returns (uint256 amount, bool stable);
function getAmountsOut(uint256 amountIn, route[] memory routes) external view returns (uint256[] memory amounts);
function isPair(address pair) external view returns (bool);
function quoteAddLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 amountADesired,
uint256 amountBDesired
)
external
view
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function quoteRemoveLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 liquidity
) external view returns (uint256 amountA, uint256 amountB);
function addLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function addLiquidityETH(
address token,
bool stable,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETH(
address token,
bool stable,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
bool stable,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETHWithPermit(
address token,
bool stable,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline,
bool approveMax,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 amountToken, uint256 amountETH);
function swapExactTokensForTokensSimple(
uint256 amountIn,
uint256 amountOutMin,
address tokenFrom,
address tokenTo,
bool stable,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
route[] calldata routes,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactETHForTokens(
uint256 amountOutMin,
route[] calldata routes,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
route[] calldata routes,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function UNSAFE_swapExactTokensForTokens(
uint256[] memory amounts,
route[] calldata routes,
address to,
uint256 deadline
) external returns (uint256[] memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
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
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
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
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
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
// OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol)
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
// OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControlEnumerable.sol";
import "./AccessControl.sol";
import "../utils/structs/EnumerableSet.sol";
/**
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
*/
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
return _roleMembers[role].at(index);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
return _roleMembers[role].length();
}
/**
* @dev Overload {_grantRole} to track enumerable memberships
*/
function _grantRole(bytes32 role, address account) internal virtual override {
super._grantRole(role, account);
_roleMembers[role].add(account);
}
/**
* @dev Overload {_revokeRole} to track enumerable memberships
*/
function _revokeRole(bytes32 role, address account) internal virtual override {
super._revokeRole(role, account);
_roleMembers[role].remove(account);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
*/
interface IAccessControlEnumerable is IAccessControl {
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role, _msgSender());
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
return _values(set._inner);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}{
"metadata": {
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address[]","name":"_feeRemitters","type":"address[]"},{"internalType":"address[]","name":"_strategists","type":"address[]"},{"internalType":"address[]","name":"_multisigRoles","type":"address[]"},{"internalType":"contract IAToken","name":"_aWant","type":"address"},{"internalType":"address[]","name":"_opToWantPath","type":"address[]"},{"internalType":"uint256","name":"_targetLtv","type":"uint256"},{"internalType":"uint256","name":"_maxLtv","type":"uint256"},{"internalType":"uint8","name":"_eModeCategory","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newCallFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTreasuryFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newStrategistFee","type":"uint256"}],"name":"FeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"harvester","type":"address"}],"name":"StratHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStrategistRemitter","type":"address"}],"name":"StrategistRemitterUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"TotalFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"AAVE_ADDRESSES_PROVIDER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AAVE_DATA_PROVIDER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AAVE_REWARDS_CONTROLLER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADDRESSES_PROVIDER","outputs":[{"internalType":"contract IPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GUARDIAN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KEEPER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL","outputs":[{"internalType":"contract IPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STRATEGIST","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STRATEGIST_MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VELO_ROUTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aWant","outputs":[{"internalType":"contract IAToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"authorizedDelever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"authorizedSendToVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"authorizedWithdrawUnderlying","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"_n","type":"int256"}],"name":"averageAPRAcrossLastNHarvests","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"calculateAPRUsingLogs","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSupplyAndBorrow","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"borrow","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvest","outputs":[{"internalType":"uint256","name":"callerFee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"harvestLog","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"vaultSharePrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestLogCadence","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestLogLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastHarvestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLtv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minLeverageAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"opToUsdcPath","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"opToWantPath","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"panic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardClaimingTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTargetLtv","type":"uint256"},{"internalType":"uint256","name":"_newMaxLtv","type":"uint256"}],"name":"setLTVs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newWithdrawSlippageTolerance","type":"uint256"},{"internalType":"uint256","name":"_newMinLeverageAmount","type":"uint256"}],"name":"setLeverageParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_path","type":"address[]"}],"name":"setOpToUsdcPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_path","type":"address[]"}],"name":"setOpToWantPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategistFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategistRemitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetLtv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_callFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"},{"internalType":"uint256","name":"_strategistFee","type":"uint256"}],"name":"updateFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCadenceInSeconds","type":"uint256"}],"name":"updateHarvestLogCadence","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newStrategistRemitter","type":"address"}],"name":"updateStrategistRemitter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalFee","type":"uint256"}],"name":"updateTotalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury","type":"address"}],"name":"updateTreasury","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawSlippageTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200528138038062005281833981016040819052620000349162000e4c565b6002805460ff19169055603c6004556101c2600a556103e8600b55612328600c556000600d819055600880546001600160a01b0319166001600160a01b038c1617905588518a918a918a918a9184919062000093576200009362000f52565b6020026020010151600760006101000a8154816001600160a01b0302191690836001600160a01b0316021790555082600181518110620000d757620000d762000f52565b6020026020010151600960006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060005b825181101562000164576200014f600080516020620052618339815191528483815181106200013b576200013b62000f52565b60200260200101516200057960201b60201c565b806200015b8162000f7e565b91505062000108565b506200017260003362000579565b620001906000801b826000815181106200013b576200013b62000f52565b620001ba60008051602062005241833981519152826001815181106200013b576200013b62000f52565b620001f57f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe8826002815181106200013b576200013b62000f52565b6040805160a081018252600081526000805160206200524183398151915260208201527f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe8918101919091526000805160206200526183398151915260608201527f71a9859d7dd21b24504a6f306077ffc2d510b4d4b61128e931fe937441ad183660808201526200028b90600690600562000c49565b5060036040518060400160405280428152602001866001600160a01b03166377c7b8fc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000304919062000f9c565b90528154600180820184556000938452602093849020835160029093020191825591830151910155600e80546001600160a01b0319166001600160a01b038c16908117909155604080516358b50cef60e11b8152905191965063b16a19de9550600480820195509293509091908290030181865afa1580156200038b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b1919062000fb6565b600f80546001600160a01b0319166001600160a01b0392909216919091179055600a6013556103e8601255604080518082019091527342000000000000000000000000000000000000428152737f5c764cbc14f9669b88837ca1490cca17c3160760208201526200042790601690600262000c99565b506200043384620005bc565b600f546040516334924edb60e21b81526001600160a01b0390911660048201526000907369fa688f1dc47d4b5d8029d5a35fb7a5483106549063d2493b6c90602401606060405180830381865afa15801562000493573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004b9919062000fdd565b604080518082019091526001600160a01b03808b16825282166020820152909350620004ec925060159150600262000c99565b50620004f7620006d6565b6040516328530a4760e01b815260ff841660048201526001600160a01b0391909116906328530a4790602401600060405180830381600087803b1580156200053e57600080fd5b505af115801562000553573d6000803e3d6000fd5b505050506200056984846200075660201b60201c565b5050505050505050505062001295565b620005908282620009b660201b620016441760201c565b6000828152600160209081526040909120620005b7918390620016c862000a56821b17901c565b505050565b620005d66000805160206200526183398151915262000a76565b7342000000000000000000000000000000000000426001600160a01b0316816000815181106200060a576200060a62000f52565b60200260200101516001600160a01b03161480156200066b5750600f5481516001600160a01b03909116908290620006459060019062001031565b8151811062000658576200065862000f52565b60200260200101516001600160a01b0316145b620006bd5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964206f70546f57616e745061746800000000000000000000000060448201526064015b60405180910390fd5b8051620006d290601790602084019062000c99565b5050565b600073a97684ead0e402dc232d5a977953df7ecbab3cdb6001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000751919062000fb6565b905090565b600062000762620006d6565b60405163eddf1b7960e01b81523060048201526001600160a01b03919091169063eddf1b7990602401602060405180830381865afa158015620007a9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007cf919062000f9c565b90506000811562000869576000620007e6620006d6565b604051636c6f6ae160e01b815260ff851660048201526001600160a01b039190911690636c6f6ae190602401600060405180830381865afa15801562000830573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200085a91908101906200105e565b5161ffff169150620008fa9050565b600f54604051633e15014160e01b81526001600160a01b0390911660048201527369fa688f1dc47d4b5d8029d5a35fb7a54831065490633e1501419060240161014060405180830381865afa158015620008c7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620008ed9190620011ae565b5096985050505050505050505b6127106200090b6126488362001250565b62000917919062001272565b8311156200095a5760405162461bcd60e51b815260206004820152600f60248201526e6d61784c7476206e6f74207361666560881b6044820152606401620006b4565b82841115620009ac5760405162461bcd60e51b815260206004820152601860248201527f7461726765744c7476206d757374203c3d206d61784c747600000000000000006044820152606401620006b4565b5050601155601055565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16620006d2576000828152602081815260408083206001600160a01b03851684529091529020805460ff1916600117905562000a123390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000a6d836001600160a01b03841662000bf7565b90505b92915050565b6006546000805b8281101562000b21576006818154811062000a9c5762000a9c62000f52565b906000526020600020015484141562000ab85780915062000b21565b62000ac560018462001031565b81141562000b0c5760405162461bcd60e51b8152602060048201526013602482015272756e617574686f72697a65642061636365737360681b6044820152606401620006b4565b8062000b188162000f7e565b91505062000a7d565b5060005b81811162000bc85762000b5f6006828154811062000b475762000b4762000f52565b90600052602060002001543362000bce60201b60201c565b1562000b6b5762000bc8565b8181141562000bb35760405162461bcd60e51b8152602060048201526013602482015272756e617574686f72697a65642061636365737360681b6044820152606401620006b4565b8062000bbf8162000f7e565b91505062000b25565b50505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600081815260018301602052604081205462000c405750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000a70565b50600062000a70565b82805482825590600052602060002090810192821562000c87579160200282015b8281111562000c8757825182559160200191906001019062000c6a565b5062000c9592915062000cf1565b5090565b82805482825590600052602060002090810192821562000c87579160200282015b8281111562000c8757825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000cba565b5b8082111562000c95576000815560010162000cf2565b6001600160a01b038116811462000d1e57600080fd5b50565b805162000d2e8162000d08565b919050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b038111828210171562000d6e5762000d6e62000d33565b60405290565b604051601f8201601f191681016001600160401b038111828210171562000d9f5762000d9f62000d33565b604052919050565b600082601f83011262000db957600080fd5b815160206001600160401b0382111562000dd75762000dd762000d33565b8160051b62000de882820162000d74565b928352848101820192828101908785111562000e0357600080fd5b83870192505b8483101562000e2f57825162000e1f8162000d08565b8252918301919083019062000e09565b979650505050505050565b805160ff8116811462000d2e57600080fd5b60008060008060008060008060006101208a8c03121562000e6c57600080fd5b62000e778a62000d21565b60208b01519099506001600160401b038082111562000e9557600080fd5b62000ea38d838e0162000da7565b995060408c015191508082111562000eba57600080fd5b62000ec88d838e0162000da7565b985060608c015191508082111562000edf57600080fd5b62000eed8d838e0162000da7565b975062000efd60808d0162000d21565b965060a08c015191508082111562000f1457600080fd5b5062000f238c828d0162000da7565b94505060c08a0151925060e08a0151915062000f436101008b0162000e3a565b90509295985092959850929598565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141562000f955762000f9562000f68565b5060010190565b60006020828403121562000faf57600080fd5b5051919050565b60006020828403121562000fc957600080fd5b815162000fd68162000d08565b9392505050565b60008060006060848603121562000ff357600080fd5b8351620010008162000d08565b6020850151909350620010138162000d08565b6040850151909250620010268162000d08565b809150509250925092565b60008282101562001046576200104662000f68565b500390565b805161ffff8116811462000d2e57600080fd5b600060208083850312156200107257600080fd5b82516001600160401b03808211156200108a57600080fd5b9084019060a082870312156200109f57600080fd5b620010a962000d49565b620010b4836200104b565b8152620010c38484016200104b565b84820152620010d5604084016200104b565b60408201526060830151620010ea8162000d08565b60608201526080830151828111156200110257600080fd5b80840193505086601f8401126200111857600080fd5b8251828111156200112d576200112d62000d33565b62001141601f8201601f1916860162000d74565b925080835287858286010111156200115857600080fd5b60005b81811015620011785784810186015184820187015285016200115b565b818111156200118a5760008683860101525b5050608081019190915295945050505050565b8051801515811462000d2e57600080fd5b6000806000806000806000806000806101408b8d031215620011cf57600080fd5b8a51995060208b0151985060408b0151975060608b0151965060808b01519550620011fd60a08c016200119d565b94506200120d60c08c016200119d565b93506200121d60e08c016200119d565b92506200122e6101008c016200119d565b91506200123f6101208c016200119d565b90509295989b9194979a5092959850565b60008160001904831182151516156200126d576200126d62000f68565b500290565b6000826200129057634e487b7160e01b600052601260045260246000fd5b500490565b613f9c80620012a56000396000f3fe608060405234801561001057600080fd5b50600436106104075760003560e01c806372c95e5611610220578063b8b63adc11610130578063d547741f116100b8578063ecf173ff11610087578063ecf173ff1461089c578063f37ae328146108a5578063f4852a81146108b8578063fb355494146108cb578063fbfa77cf146108de57600080fd5b8063d547741f1461085a578063e46257d21461086d578063ec90b12214610880578063ec921dc11461089357600080fd5b8063cb7faf19116100ff578063cb7faf191461081a578063cc32d1761461082d578063d0e30db014610836578063d2f129051461083e578063d32b96041461084757600080fd5b8063b8b63adc146107e2578063bc063e1a146107f5578063c191464e146107fe578063ca15c8731461080757600080fd5b806389a30271116101b357806391d148541161018257806391d148541461078c578063920f5c841461079f5780639cfdede3146107b2578063a217fddf146107c7578063abdcadbe146107cf57600080fd5b806389a30271146107425780638cf558821461075d5780639010d07c1461077057806390321e1a1461078357600080fd5b80637f51bb1f116101ef5780637f51bb1f146106ed5780638456cb5914610700578063862a179e146107085780638888f9f61461072f57600080fd5b806372c95e56146106b35780637535d246146106bc5780637c9c3472146106c45780637e0bce10146106d257600080fd5b8063398d4e1a1161031b5780634b73de96116102ae57806363a8910d1161027d57806363a8910d146106435780636c9010d8146106565780637002783914610669578063722713f714610684578063724c184c1461068c57600080fd5b80634b73de96146105ff578063526e10801461061c5780635c975abb1461062557806361d027b31461063057600080fd5b80634234214c116102ea5780634234214c146105d35780634641257d146105e65780634700d305146105ee5780634870dd9a146105f657600080fd5b8063398d4e1a146105945780633a12c6da146105a75780633a6d2652146105b05780633f4ba83a146105cb57600080fd5b80632257a7381161039e5780632d6f4baa1161036d5780632d6f4baa1461053e5780632e1a7d4d146105465780632e2a25971461055b5780632f2ff15d1461056e57806336568abe1461058157600080fd5b80632257a738146104d8578063248a9ca3146104e15780632a0acc6a146105045780632ac081151461052b57600080fd5b806316d3bfbb116103da57806316d3bfbb146104905780631df4ccfc146104a95780631f1fcd51146104b257806322429085146104c557600080fd5b806301ffc9a71461040c5780630542975c146104345780630a399d2c1461046257806311b2e10e14610475575b600080fd5b61041f61041a3660046132fd565b6108f1565b60405190151581526020015b60405180910390f35b73a97684ead0e402dc232d5a977953df7ecbab3cdb5b6040516001600160a01b03909116815260200161042b565b61044a610470366004613327565b61091c565b61044a73a97684ead0e402dc232d5a977953df7ecbab3cdb81565b61049b6301e1338081565b60405190815260200161042b565b61049b600a5481565b600f5461044a906001600160a01b031681565b61041f6104d3366004613340565b610946565b61049b60055481565b61049b6104ef366004613327565b60009081526020819052604090206001015490565b61049b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b600e5461044a906001600160a01b031681565b60035461049b565b610559610554366004613327565b6109d2565b005b61044a610569366004613327565b610a13565b61055961057c366004613381565b610a23565b61055961058f366004613381565b610a4e565b61044a6105a2366004613327565b610ad1565b61049b60115481565b61044a73929ec64c34a17401f460460d4b9390518e5b473e81565b610559610ae1565b6105596105e13660046133b1565b610b1c565b61049b610b83565b610559610cd8565b61049b61271081565b610607610d11565b6040805192835260208301919091520161042b565b61049b600d5481565b60025460ff1661041f565b60075461044a906001600160a01b031681565b610559610651366004613327565b610dae565b6105596106643660046133b1565b610de2565b61044a73a132dab612db5cb9fc9ac426a0cc215a3423f9c981565b61049b610e15565b61049b7f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe881565b61049b60045481565b61044a610eb2565b61044a6042602160991b0181565b61044a7369fa688f1dc47d4b5d8029d5a35fb7a54831065481565b61041f6106fb3660046133d3565b610f2f565b610559610f60565b61049b7f71a9859d7dd21b24504a6f306077ffc2d510b4d4b61128e931fe937441ad183681565b60095461044a906001600160a01b031681565b61044a737f5c764cbc14f9669b88837ca1490cca17c3160781565b61049b61076b3660046133b1565b610f91565b61044a61077e3660046133b1565b6110c4565b61049b600b5481565b61041f61079a366004613381565b6110dc565b61041f6107ad36600461343c565b611105565b61049b600080516020613f4783398151915281565b61049b600081565b6105596107dd366004613327565b61121c565b6105596107f03660046135d5565b61123c565b61049b6103e881565b61049b60135481565b61049b610815366004613327565b611328565b610559610828366004613669565b61133f565b61049b600c5481565b610559611435565b61049b60125481565b610559610855366004613327565b611460565b610559610868366004613381565b6114b5565b61055961087b3660046133d3565b6114db565b61055961088e366004613327565b611546565b61049b60105481565b61049b61138881565b6106076108b3366004613327565b611562565b61049b6108c6366004613327565b611590565b6105596108d9366004613327565b611624565b60085461044a906001600160a01b031681565b60006001600160e01b03198216635a05180f60e01b14806109165750610916826116dd565b92915050565b6015818154811061092c57600080fd5b6000918252602090912001546001600160a01b0316905081565b600061095181611712565b61271061095e84866136c1565b1461096857600080fd5b61138882111561097757600080fd5b600b849055600c839055600d82905560408051858152602081018590529081018390527fcf8a1e1d5f09cf3c97dbb653cd9a4d7aace9292fbc1bb8211febf2d400febbdd9060600160405180910390a15060015b9392505050565b6008546001600160a01b031633146109e957600080fd5b806109f357600080fd5b6109fb610e15565b811115610a0757600080fd5b610a108161184a565b50565b6017818154811061092c57600080fd5b600082815260208190526040902060010154610a3f813361197e565b610a4983836119e2565b505050565b6001600160a01b0381163314610ac35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b610acd8282611a04565b5050565b6016818154811061092c57600080fd5b610b0a7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42611712565b610b12611a26565b610b1a611435565b565b610b33600080516020613f47833981519152611712565b60c8821115610b785760405162461bcd60e51b8152602060048201526011602482015270696e76616c696420736c6970706167652160781b6044820152606401610aba565b601391909155601255565b6000610b9160025460ff1690565b15610bae5760405162461bcd60e51b8152600401610aba906136d9565b610bb6611ab9565b905060045460036001600380549050610bcf9190613703565b81548110610bdf57610bdf61371a565b906000526020600020906002020160000154610bfb91906136c1565b4210610ca6576040805180820182524281526008548251631df1ee3f60e21b815292516003936020808501936001600160a01b0316926377c7b8fc9260048082019392918290030181865afa158015610c58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7c9190613730565b90528154600181810184556000938452602093849020835160029093020191825592909101519101555b4260055560405133907f577a37fdb49a88d66684922c6f913df5239b4f214b2b97c53ef8e3bbb2034cb590600090a290565b610d017f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe8611712565b610d09611b5a565b610b1a610f60565b600f546040516328dd2d0160e01b81526001600160a01b03909116600482015230602482015260009081907369fa688f1dc47d4b5d8029d5a35fb7a548310654906328dd2d019060440161012060405180830381865afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9d919061375e565b509699949850939650505050505050565b610dc5600080516020613f47833981519152611712565b600854600f54610a10916001600160a01b03918216911683611b8a565b610e0b7f71a9859d7dd21b24504a6f306077ffc2d510b4d4b61128e931fe937441ad1836611712565b610acd8282611bed565b6000806000610e22610d11565b90925090506000610e338284613703565b600f546040516370a0823160e01b81523060048201529192506001600160a01b0316906370a0823190602401602060405180830381865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea09190613730565b610eaa90826136c1565b935050505090565b600073a97684ead0e402dc232d5a977953df7ecbab3cdb6001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2a91906137e1565b905090565b6000610f3a81611712565b50600780546001600160a01b0319166001600160a01b0392909216919091179055600190565b610f897f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe8611712565b610b1a611e36565b60008060038481548110610fa757610fa761371a565b90600052602060002090600202019050600060038481548110610fcc57610fcc61371a565b90600052602060002090600202019050600060019050826001015482600101541015610ff6575060005b6000811561101957836001015483600101546110129190613703565b9050611030565b8260010154846001015461102d9190613703565b90505b600184015460009061104a83670de0b6b3a76400006137fe565b6110549190613833565b855485549192506000916110689190613703565b905060008161107b6301e13380856137fe565b6110859190613833565b9050611097655af3107a400082613833565b905084156110ad57965061091695505050505050565b6110b681613847565b9a9950505050505050505050565b60008281526001602052604081206109cb9083611e8e565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600061110f610eb2565b6001600160a01b0316336001600160a01b0316146111685760405162461bcd60e51b815260206004820152601660248201527518d85b1b195c88084f481b195b991a5b99c81c1bdbdb60521b6044820152606401610aba565b6001600160a01b03841630146111ad5760405162461bcd60e51b815260206004820152600a60248201526910b4b734ba34b0ba37b960b11b6044820152606401610aba565b6001601454146111ff5760405162461bcd60e51b815260206004820152601760248201527f696e76616c696420666c6173684c6f616e5374617475730000000000000000006044820152606401610aba565b600060145561120c611e9a565b5060019998505050505050505050565b611233600080516020613f47833981519152611712565b610a1081611faa565b611253600080516020613f47833981519152611712565b6042602160991b016001600160a01b0316816000815181106112775761127761371a565b60200260200101516001600160a01b03161480156112d25750600f5481516001600160a01b039091169082906112af90600190613703565b815181106112bf576112bf61371a565b60200260200101516001600160a01b0316145b6113155760405162461bcd60e51b8152602060048201526014602482015273092dcecc2d8d2c840dee0a8deaec2dce8a0c2e8d60631b6044820152606401610aba565b8051610acd906017906020840190613230565b6000818152600160205260408120610916906120d5565b611356600080516020613f47833981519152611712565b6042602160991b01828260008161136f5761136f61371a565b905060200201602081019061138491906133d3565b6001600160a01b03161480156113e65750737f5c764cbc14f9669b88837ca1490cca17c3160782826113b7600182613703565b8181106113c6576113c661371a565b90506020020160208101906113db91906133d3565b6001600160a01b0316145b6114295760405162461bcd60e51b8152602060048201526014602482015273092dcecc2d8d2c840dee0a8deaae6c8c6a0c2e8d60631b6044820152606401610aba565b610a4960168383613295565b60025460ff16156114585760405162461bcd60e51b8152600401610aba906136d9565b610b1a6120df565b61146a6000611712565b6103e881111561147957600080fd5b600a8190556040518181527f2e59d502792bca3d730c472cd3acfbc16d0f9fe6ce0cddbdf0f80830251dfaca906020015b60405180910390a150565b6000828152602081905260409020600101546114d1813361197e565b610a498383611a04565b6114e56000611712565b6001600160a01b0381166114f857600080fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fa11c447ac90d9534769dc85d422963d67c1d8d899de887301417cedf4dec738d906020016114aa565b61155d600080516020613f47833981519152611712565b600455565b6003818154811061157257600080fd5b60009182526020909120600290910201805460019091015490915082565b600354600090600211156115a357600080fd5b600080600060016003805490506115ba9190613703565b90505b6000811180156115cc57508482125b15611611576115e56115df600183613703565b82610f91565b6115ef9084613864565b9250816115fb816138a5565b9250508080611609906138c5565b9150506115bd565b5061161c81836138dc565b949350505050565b61163b600080516020613f47833981519152611712565b610a1081612147565b61164e82826110dc565b610acd576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116843390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006109cb836001600160a01b03841661227c565b60006001600160e01b03198216637965db0b60e01b148061091657506301ffc9a760e01b6001600160e01b0319831614610916565b6006546000805b828110156117b057600681815481106117345761173461371a565b906000526020600020015484141561174e578091506117b0565b611759600184613703565b81141561179e5760405162461bcd60e51b8152602060048201526013602482015272756e617574686f72697a65642061636365737360681b6044820152606401610aba565b806117a88161390a565b915050611719565b5060005b818111611844576117e2600682815481106117d1576117d161371a565b9060005260206000200154336110dc565b156117ec57611844565b818114156118325760405162461bcd60e51b8152602060048201526013602482015272756e617574686f72697a65642061636365737360681b6044820152606401610aba565b8061183c8161390a565b9150506117b4565b50505050565b600f546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b79190613730565b90508082116118dd57600854600f54610acd916001600160a01b03918216911684611b8a565b60006118e98284613703565b90506000806118f6610d11565b90925090506119058383613703565b915060008261191557600061192c565b82611922612710846137fe565b61192c9190613833565b90506011548111156119505761194184612147565b61194b84876122cb565b611976565b60105481101561196c5761196484876122cb565b61194b6123fc565b61197684876122cb565b505050505050565b61198882826110dc565b610acd576119a0816001600160a01b0316601461246c565b6119ab83602061246c565b6040516020016119bc92919061394a565b60408051601f198184030181529082905262461bcd60e51b8252610aba916004016139bf565b6119ec8282611644565b6000828152600160205260409020610a4990826116c8565b611a0e8282612608565b6000828152600160205260409020610a49908261266d565b60025460ff16611a6f5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610aba565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b604051635fc87b1d60e11b815260009073929ec64c34a17401f460460d4b9390518e5b473e9063bf90f63a90611af4906015906004016139f2565b6000604051808303816000875af1158015611b13573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b3b9190810190613aa8565b5050611b45612682565b9050611b4f61292e565b611b57611435565b90565b600080611b65610d11565b90925090506000611b768284613703565b9050611b8181612147565b610a4981611faa565b6040516001600160a01b038316602482015260448101829052610a4990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a03565b6000611bf7610eb2565b60405163eddf1b7960e01b81523060048201526001600160a01b03919091169063eddf1b7990602401602060405180830381865afa158015611c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c619190613730565b905060008115611cf4576000611c75610eb2565b604051636c6f6ae160e01b815260ff851660048201526001600160a01b039190911690636c6f6ae190602401600060405180830381865afa158015611cbe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ce69190810190613b7f565b5161ffff169150611d829050565b600f54604051633e15014160e01b81526001600160a01b0390911660048201527369fa688f1dc47d4b5d8029d5a35fb7a54831065490633e1501419060240161014060405180830381865afa158015611d51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d759190613c86565b5096985050505050505050505b612710611d91612648836137fe565b611d9b9190613833565b831115611ddc5760405162461bcd60e51b815260206004820152600f60248201526e6d61784c7476206e6f74207361666560881b6044820152606401610aba565b82841115611e2c5760405162461bcd60e51b815260206004820152601860248201527f7461726765744c7476206d757374203c3d206d61784c747600000000000000006044820152606401610aba565b5050601155601055565b60025460ff1615611e595760405162461bcd60e51b8152600401610aba906136d9565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a9c3390565b60006109cb8383612ad5565b600f546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611ee3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f079190613730565b90508015610a1057611f2d611f1a610eb2565b600f546001600160a01b03169083612aff565b611f35610eb2565b600f5460405163617ba03760e01b81526001600160a01b039182166004820152602481018490523060448201526000606482015291169063617ba03790608401600060405180830381600087803b158015611f8f57600080fd5b505af1158015611fa3573d6000803e3d6000fd5b5050505050565b600080611fb5610d11565b91509150600060115460001415611fcd576000611fe6565b601154611fdc612710846137fe565b611fe69190613833565b90508083116120375760405162461bcd60e51b815260206004820152601860248201527f63616e277420776974686472617720616e797468696e672100000000000000006044820152606401610aba565b60006120438285613703565b905061204f8582612bb1565b9450612059610eb2565b600f54604051631a4ca37b60e21b81526001600160a01b039182166004820152602481018890523060448201529116906369328dec906064016020604051808303816000875af11580156120b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119769190613730565b6000610916825490565b6120e7611e9a565b6000806120f2610d11565b915091506000826000141561210857600061211f565b82612115612710846137fe565b61211f9190613833565b905060115481111561213557610a496000612147565b601054811015610a4957610a496123fc565b600080612152610d11565b909250905060006121638284613703565b9050808411156121a65760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610aba565b60006121b28583613703565b905060006010546127106121c69190613703565b6010546121d390846137fe565b6121dd9190613833565b905060006121eb8286613703565b90506121f5610eb2565b600f54604051630b6b65f560e21b81526001600160a01b0391821660048201526024810184905260026044820152911690632dad97d4906064016020604051808303816000875af115801561224e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122729190613730565b5050505050505050565b60008181526001830160205260408120546122c357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610916565b506000610916565b6122d482611faa565b600f546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561231d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123419190613730565b9050818110156123cf5761271060135461271061235e9190613703565b61236890846137fe565b6123729190613833565b8110156123cf5760405162461bcd60e51b815260206004820152602560248201527f77697468647261773a206f75747369646520736c69707061676520746f6c6572604482015264616e63652160d81b6064820152608401610aba565b600854610a49906001600160a01b03166123e98385612bb1565b600f546001600160a01b03169190611b8a565b600080612407610d11565b909250905060006124188284613703565b9050600060105461271061242c9190613703565b60105461243990846137fe565b6124439190613833565b90506012548361245391906136c1565b811115611844576118446124678483613703565b612bc7565b6060600061247b8360026137fe565b6124869060026136c1565b67ffffffffffffffff81111561249e5761249e613541565b6040519080825280601f01601f1916602001820160405280156124c8576020820181803683370190505b509050600360fc1b816000815181106124e3576124e361371a565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106125125761251261371a565b60200101906001600160f81b031916908160001a90535060006125368460026137fe565b6125419060016136c1565b90505b60018111156125b9576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106125755761257561371a565b1a60f81b82828151811061258b5761258b61371a565b60200101906001600160f81b031916908160001a90535060049490941c936125b2816138c5565b9050612544565b5083156109cb5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610aba565b61261282826110dc565b15610acd576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006109cb836001600160a01b038416612d5d565b600a546040516370a0823160e01b8152306004820152600091829161271091906042602160991b01906370a0823190602401602060405180830381865afa1580156126d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f59190613730565b6126ff91906137fe565b6127099190613833565b90508061271857600091505090565b6040516370a0823160e01b8152306004820152737f5c764cbc14f9669b88837ca1490cca17c316079060009082906370a0823190602401602060405180830381865afa15801561276c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127909190613730565b90506127f660168054806020026020016040519081016040528092919081815260200182805480156127eb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116127cd575b505050505084612e50565b6040516370a0823160e01b815230600482015260009082906001600160a01b038516906370a0823190602401602060405180830381865afa15801561283f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128639190613730565b61286d9190613703565b9050801561292757612710600b548261288691906137fe565b6128909190613833565b94506000612710600c54836128a591906137fe565b6128af9190613833565b90506000612710600d54836128c491906137fe565b6128ce9190613833565b90506128da8183613703565b91506128f06001600160a01b0386163389611b8a565b60075461290a906001600160a01b03878116911684611b8a565b600954612924906001600160a01b03878116911683611b8a565b50505b5050505090565b6040516370a0823160e01b81523060048201526000906042602160991b01906370a0823190602401602060405180830381865afa158015612973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129979190613730565b90508015610a1057610a1060178054806020026020016040519081016040528092919081815260200182805480156129f857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116129da575b505050505082612e50565b6000612a58826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131259092919063ffffffff16565b805190915015610a495780806020019051810190612a769190613d1d565b610a495760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610aba565b6000826000018281548110612aec57612aec61371a565b9060005260206000200154905092915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612b50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b749190613730565b612b7e91906136c1565b6040516001600160a01b03851660248201526044810182905290915061184490859063095ea7b360e01b90606401611bb6565b6000818310612bc057816109cb565b5090919050565b80612c0a5760405162461bcd60e51b8152602060048201526013602482015272464c3a20696e76616c696420616d6f756e742160681b6044820152606401610aba565b604080516001808252818301909252600091602080830190803683375050600f5482519293506001600160a01b031691839150600090612c4c57612c4c61371a565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508281600081518110612c9d57612c9d61371a565b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050600281600081518110612ce157612ce161371a565b60209081029190910101526001601455612cf9610eb2565b6001600160a01b031663ab9c4b5d308585853060006040518763ffffffff1660e01b8152600401612d2f96959493929190613d73565b600060405180830381600087803b158015612d4957600080fd5b505af1158015612272573d6000803e3d6000fd5b60008181526001830160205260408120548015612e46576000612d81600183613703565b8554909150600090612d9590600190613703565b9050818114612dfa576000866000018281548110612db557612db561371a565b9060005260206000200154905080876000018481548110612dd857612dd861371a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e0b57612e0b613e1e565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610916565b6000915050610916565b815173a132dab612db5cb9fc9ac426a0cc215a3423f9c990600090612e7790600190613703565b67ffffffffffffffff811115612e8f57612e8f613541565b604051908082528060200260200182016040528015612eda57816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181612ead5790505b50905082600080805b845181101561305c57856001600160a01b0316635e1e6325858a8481518110612f0e57612f0e61371a565b60200260200101518b856001612f2491906136c1565b81518110612f3457612f3461371a565b60200260200101516040518463ffffffff1660e01b8152600401612f74939291909283526001600160a01b03918216602084015216604082015260600190565b6040805180830381865afa158015612f90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb49190613e34565b80935081945050506040518060600160405280898381518110612fd957612fd961371a565b60200260200101516001600160a01b0316815260200189836001612ffd91906136c1565b8151811061300d5761300d61371a565b60200260200101516001600160a01b0316815260200183151581525085828151811061303b5761303b61371a565b602002602001018190525082935080806130549061390a565b915050612ee3565b506130a973a132dab612db5cb9fc9ac426a0cc215a3423f9c987896000815181106130895761308961371a565b60200260200101516001600160a01b0316612aff9092919063ffffffff16565b604051631e82ecdb60e31b81526001600160a01b0386169063f41766d8906130de908990600090899030904290600401613e60565b6000604051808303816000875af11580156130fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122729190810190613ef5565b606061161c848460008585843b61317e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aba565b600080866001600160a01b0316858760405161319a9190613f2a565b60006040518083038185875af1925050503d80600081146131d7576040519150601f19603f3d011682016040523d82523d6000602084013e6131dc565b606091505b50915091506131ec8282866131f7565b979650505050505050565b606083156132065750816109cb565b8251156132165782518084602001fd5b8160405162461bcd60e51b8152600401610aba91906139bf565b828054828255906000526020600020908101928215613285579160200282015b8281111561328557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613250565b506132919291506132e8565b5090565b828054828255906000526020600020908101928215613285579160200282015b828111156132855781546001600160a01b0319166001600160a01b038435161782556020909201916001909101906132b5565b5b8082111561329157600081556001016132e9565b60006020828403121561330f57600080fd5b81356001600160e01b0319811681146109cb57600080fd5b60006020828403121561333957600080fd5b5035919050565b60008060006060848603121561335557600080fd5b505081359360208301359350604090920135919050565b6001600160a01b0381168114610a1057600080fd5b6000806040838503121561339457600080fd5b8235915060208301356133a68161336c565b809150509250929050565b600080604083850312156133c457600080fd5b50508035926020909101359150565b6000602082840312156133e557600080fd5b81356109cb8161336c565b60008083601f84011261340257600080fd5b50813567ffffffffffffffff81111561341a57600080fd5b6020830191508360208260051b850101111561343557600080fd5b9250929050565b600080600080600080600080600060a08a8c03121561345a57600080fd5b893567ffffffffffffffff8082111561347257600080fd5b61347e8d838e016133f0565b909b50995060208c013591508082111561349757600080fd5b6134a38d838e016133f0565b909950975060408c01359150808211156134bc57600080fd5b6134c88d838e016133f0565b909750955060608c013591506134dd8261336c565b90935060808b013590808211156134f357600080fd5b818c0191508c601f83011261350757600080fd5b81358181111561351657600080fd5b8d602082850101111561352857600080fd5b6020830194508093505050509295985092959850929598565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561357a5761357a613541565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156135a9576135a9613541565b604052919050565b600067ffffffffffffffff8211156135cb576135cb613541565b5060051b60200190565b600060208083850312156135e857600080fd5b823567ffffffffffffffff8111156135ff57600080fd5b8301601f8101851361361057600080fd5b803561362361361e826135b1565b613580565b81815260059190911b8201830190838101908783111561364257600080fd5b928401925b828410156131ec57833561365a8161336c565b82529284019290840190613647565b6000806020838503121561367c57600080fd5b823567ffffffffffffffff81111561369357600080fd5b61369f858286016133f0565b90969095509350505050565b634e487b7160e01b600052601160045260246000fd5b600082198211156136d4576136d46136ab565b500190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b600082821015613715576137156136ab565b500390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561374257600080fd5b5051919050565b8051801515811461375957600080fd5b919050565b60008060008060008060008060006101208a8c03121561377d57600080fd5b8951985060208a0151975060408a0151965060608a0151955060808a0151945060a08a0151935060c08a0151925060e08a015164ffffffffff811681146137c357600080fd5b91506137d26101008b01613749565b90509295985092959850929598565b6000602082840312156137f357600080fd5b81516109cb8161336c565b6000816000190483118215151615613818576138186136ab565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826138425761384261381d565b500490565b6000600160ff1b82141561385d5761385d6136ab565b5060000390565b600080821280156001600160ff1b0384900385131615613886576138866136ab565b600160ff1b839003841281161561389f5761389f6136ab565b50500190565b60006001600160ff1b038214156138be576138be6136ab565b5060010190565b6000816138d4576138d46136ab565b506000190190565b6000826138eb576138eb61381d565b600160ff1b821460001984141615613905576139056136ab565b500590565b60006000198214156138be576138be6136ab565b60005b83811015613939578181015183820152602001613921565b838111156118445750506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161398281601785016020880161391e565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516139b381602884016020880161391e565b01602801949350505050565b60208152600082518060208401526139de81604085016020870161391e565b601f01601f19169190910160400192915050565b6020808252825482820181905260008481528281209092916040850190845b81811015613a365783546001600160a01b031683526001938401939285019201613a11565b50909695505050505050565b600082601f830112613a5357600080fd5b81516020613a6361361e836135b1565b82815260059290921b84018101918181019086841115613a8257600080fd5b8286015b84811015613a9d5780518352918301918301613a86565b509695505050505050565b60008060408385031215613abb57600080fd5b825167ffffffffffffffff80821115613ad357600080fd5b818501915085601f830112613ae757600080fd5b81516020613af761361e836135b1565b82815260059290921b84018101918181019089841115613b1657600080fd5b948201945b83861015613b3d578551613b2e8161336c565b82529482019490820190613b1b565b91880151919650909350505080821115613b5657600080fd5b50613b6385828601613a42565b9150509250929050565b805161ffff8116811461375957600080fd5b60006020808385031215613b9257600080fd5b825167ffffffffffffffff80821115613baa57600080fd5b9084019060a08287031215613bbe57600080fd5b613bc6613557565b613bcf83613b6d565b8152613bdc848401613b6d565b84820152613bec60408401613b6d565b60408201526060830151613bff8161336c565b6060820152608083015182811115613c1657600080fd5b80840193505086601f840112613c2b57600080fd5b825182811115613c3d57613c3d613541565b613c4f601f8201601f19168601613580565b92508083528785828601011115613c6557600080fd5b613c748186850187870161391e565b50608081019190915295945050505050565b6000806000806000806000806000806101408b8d031215613ca657600080fd5b8a51995060208b0151985060408b0151975060608b0151965060808b01519550613cd260a08c01613749565b9450613ce060c08c01613749565b9350613cee60e08c01613749565b9250613cfd6101008c01613749565b9150613d0c6101208c01613749565b90509295989b9194979a5092959850565b600060208284031215613d2f57600080fd5b6109cb82613749565b600081518084526020808501945080840160005b83811015613d6857815187529582019590820190600101613d4c565b509495945050505050565b6001600160a01b03878116825260e06020808401829052885191840182905260009289820192909190610100860190855b81811015613dc2578551851683529483019491830191600101613da4565b50508581036040870152613dd6818b613d38565b93505050508281036060840152613ded8187613d38565b6001600160a01b038616608085015283810360a08501526000815261ffff851660c085015260200191506131ec9050565b634e487b7160e01b600052603160045260246000fd5b60008060408385031215613e4757600080fd5b82519150613e5760208401613749565b90509250929050565b600060a0820187835260208781850152604060a08186015282885180855260c087019150838a01945060005b81811015613ec957855180516001600160a01b03908116855286820151168685015284015115158484015294840194606090920191600101613e8c565b50506001600160a01b03881660608701529350613ee592505050565b8260808301529695505050505050565b600060208284031215613f0757600080fd5b815167ffffffffffffffff811115613f1e57600080fd5b61161c84828501613a42565b60008251613f3c81846020870161391e565b919091019291505056feb17d0a42cc710456bf9c3efb785dcd0cb93a0ac358113307b5c64b285b516b5ca2646970667358221220981d059dfaa6c075b82a22a796b5a234884ad2a520dc2a196ffd10dfeecf69cb64736f6c634300080b0033df8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42b17d0a42cc710456bf9c3efb785dcd0cb93a0ac358113307b5c64b285b516b5c000000000000000000000000df2d2c477078d2cd563648abbb913da3db247c00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000e50fa9b3c56ffb159cb0fca61f5c9d750e8128c800000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000001e140000000000000000000000000000000000000000000000000000000000001e7800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000eb9c9b785aa7818b2ebc8f9842926c4b9f707e4b0000000000000000000000002b394b228908fb7dacaff5f340f1b442a39b056c00000000000000000000000000000000000000000000000000000000000000030000000000000000000000001e71aee6081f62053123140aacc7a06021d7734800000000000000000000000081876677843d00a7d792e1617459ac2e932025760000000000000000000000001a20d7a31e5b3bc5f02c8a146ef6f394502a10c400000000000000000000000000000000000000000000000000000000000000030000000000000000000000003aa60c3ae4b94515fa1fd0ffee77d02b6a0609f3000000000000000000000000eb9c9b785aa7818b2ebc8f9842926c4b9f707e4b000000000000000000000000b0c9d5851def8a2aac4a23031ca2610f8c3483f9000000000000000000000000000000000000000000000000000000000000000200000000000000000000000042000000000000000000000000000000000000420000000000000000000000004200000000000000000000000000000000000006
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104075760003560e01c806372c95e5611610220578063b8b63adc11610130578063d547741f116100b8578063ecf173ff11610087578063ecf173ff1461089c578063f37ae328146108a5578063f4852a81146108b8578063fb355494146108cb578063fbfa77cf146108de57600080fd5b8063d547741f1461085a578063e46257d21461086d578063ec90b12214610880578063ec921dc11461089357600080fd5b8063cb7faf19116100ff578063cb7faf191461081a578063cc32d1761461082d578063d0e30db014610836578063d2f129051461083e578063d32b96041461084757600080fd5b8063b8b63adc146107e2578063bc063e1a146107f5578063c191464e146107fe578063ca15c8731461080757600080fd5b806389a30271116101b357806391d148541161018257806391d148541461078c578063920f5c841461079f5780639cfdede3146107b2578063a217fddf146107c7578063abdcadbe146107cf57600080fd5b806389a30271146107425780638cf558821461075d5780639010d07c1461077057806390321e1a1461078357600080fd5b80637f51bb1f116101ef5780637f51bb1f146106ed5780638456cb5914610700578063862a179e146107085780638888f9f61461072f57600080fd5b806372c95e56146106b35780637535d246146106bc5780637c9c3472146106c45780637e0bce10146106d257600080fd5b8063398d4e1a1161031b5780634b73de96116102ae57806363a8910d1161027d57806363a8910d146106435780636c9010d8146106565780637002783914610669578063722713f714610684578063724c184c1461068c57600080fd5b80634b73de96146105ff578063526e10801461061c5780635c975abb1461062557806361d027b31461063057600080fd5b80634234214c116102ea5780634234214c146105d35780634641257d146105e65780634700d305146105ee5780634870dd9a146105f657600080fd5b8063398d4e1a146105945780633a12c6da146105a75780633a6d2652146105b05780633f4ba83a146105cb57600080fd5b80632257a7381161039e5780632d6f4baa1161036d5780632d6f4baa1461053e5780632e1a7d4d146105465780632e2a25971461055b5780632f2ff15d1461056e57806336568abe1461058157600080fd5b80632257a738146104d8578063248a9ca3146104e15780632a0acc6a146105045780632ac081151461052b57600080fd5b806316d3bfbb116103da57806316d3bfbb146104905780631df4ccfc146104a95780631f1fcd51146104b257806322429085146104c557600080fd5b806301ffc9a71461040c5780630542975c146104345780630a399d2c1461046257806311b2e10e14610475575b600080fd5b61041f61041a3660046132fd565b6108f1565b60405190151581526020015b60405180910390f35b73a97684ead0e402dc232d5a977953df7ecbab3cdb5b6040516001600160a01b03909116815260200161042b565b61044a610470366004613327565b61091c565b61044a73a97684ead0e402dc232d5a977953df7ecbab3cdb81565b61049b6301e1338081565b60405190815260200161042b565b61049b600a5481565b600f5461044a906001600160a01b031681565b61041f6104d3366004613340565b610946565b61049b60055481565b61049b6104ef366004613327565b60009081526020819052604090206001015490565b61049b7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec4281565b600e5461044a906001600160a01b031681565b60035461049b565b610559610554366004613327565b6109d2565b005b61044a610569366004613327565b610a13565b61055961057c366004613381565b610a23565b61055961058f366004613381565b610a4e565b61044a6105a2366004613327565b610ad1565b61049b60115481565b61044a73929ec64c34a17401f460460d4b9390518e5b473e81565b610559610ae1565b6105596105e13660046133b1565b610b1c565b61049b610b83565b610559610cd8565b61049b61271081565b610607610d11565b6040805192835260208301919091520161042b565b61049b600d5481565b60025460ff1661041f565b60075461044a906001600160a01b031681565b610559610651366004613327565b610dae565b6105596106643660046133b1565b610de2565b61044a73a132dab612db5cb9fc9ac426a0cc215a3423f9c981565b61049b610e15565b61049b7f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe881565b61049b60045481565b61044a610eb2565b61044a6042602160991b0181565b61044a7369fa688f1dc47d4b5d8029d5a35fb7a54831065481565b61041f6106fb3660046133d3565b610f2f565b610559610f60565b61049b7f71a9859d7dd21b24504a6f306077ffc2d510b4d4b61128e931fe937441ad183681565b60095461044a906001600160a01b031681565b61044a737f5c764cbc14f9669b88837ca1490cca17c3160781565b61049b61076b3660046133b1565b610f91565b61044a61077e3660046133b1565b6110c4565b61049b600b5481565b61041f61079a366004613381565b6110dc565b61041f6107ad36600461343c565b611105565b61049b600080516020613f4783398151915281565b61049b600081565b6105596107dd366004613327565b61121c565b6105596107f03660046135d5565b61123c565b61049b6103e881565b61049b60135481565b61049b610815366004613327565b611328565b610559610828366004613669565b61133f565b61049b600c5481565b610559611435565b61049b60125481565b610559610855366004613327565b611460565b610559610868366004613381565b6114b5565b61055961087b3660046133d3565b6114db565b61055961088e366004613327565b611546565b61049b60105481565b61049b61138881565b6106076108b3366004613327565b611562565b61049b6108c6366004613327565b611590565b6105596108d9366004613327565b611624565b60085461044a906001600160a01b031681565b60006001600160e01b03198216635a05180f60e01b14806109165750610916826116dd565b92915050565b6015818154811061092c57600080fd5b6000918252602090912001546001600160a01b0316905081565b600061095181611712565b61271061095e84866136c1565b1461096857600080fd5b61138882111561097757600080fd5b600b849055600c839055600d82905560408051858152602081018590529081018390527fcf8a1e1d5f09cf3c97dbb653cd9a4d7aace9292fbc1bb8211febf2d400febbdd9060600160405180910390a15060015b9392505050565b6008546001600160a01b031633146109e957600080fd5b806109f357600080fd5b6109fb610e15565b811115610a0757600080fd5b610a108161184a565b50565b6017818154811061092c57600080fd5b600082815260208190526040902060010154610a3f813361197e565b610a4983836119e2565b505050565b6001600160a01b0381163314610ac35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b610acd8282611a04565b5050565b6016818154811061092c57600080fd5b610b0a7fdf8b4c520ffe197c5343c6f5aec59570151ef9a492f2c624fd45ddde6135ec42611712565b610b12611a26565b610b1a611435565b565b610b33600080516020613f47833981519152611712565b60c8821115610b785760405162461bcd60e51b8152602060048201526011602482015270696e76616c696420736c6970706167652160781b6044820152606401610aba565b601391909155601255565b6000610b9160025460ff1690565b15610bae5760405162461bcd60e51b8152600401610aba906136d9565b610bb6611ab9565b905060045460036001600380549050610bcf9190613703565b81548110610bdf57610bdf61371a565b906000526020600020906002020160000154610bfb91906136c1565b4210610ca6576040805180820182524281526008548251631df1ee3f60e21b815292516003936020808501936001600160a01b0316926377c7b8fc9260048082019392918290030181865afa158015610c58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7c9190613730565b90528154600181810184556000938452602093849020835160029093020191825592909101519101555b4260055560405133907f577a37fdb49a88d66684922c6f913df5239b4f214b2b97c53ef8e3bbb2034cb590600090a290565b610d017f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe8611712565b610d09611b5a565b610b1a610f60565b600f546040516328dd2d0160e01b81526001600160a01b03909116600482015230602482015260009081907369fa688f1dc47d4b5d8029d5a35fb7a548310654906328dd2d019060440161012060405180830381865afa158015610d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9d919061375e565b509699949850939650505050505050565b610dc5600080516020613f47833981519152611712565b600854600f54610a10916001600160a01b03918216911683611b8a565b610e0b7f71a9859d7dd21b24504a6f306077ffc2d510b4d4b61128e931fe937441ad1836611712565b610acd8282611bed565b6000806000610e22610d11565b90925090506000610e338284613703565b600f546040516370a0823160e01b81523060048201529192506001600160a01b0316906370a0823190602401602060405180830381865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea09190613730565b610eaa90826136c1565b935050505090565b600073a97684ead0e402dc232d5a977953df7ecbab3cdb6001600160a01b031663026b1d5f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2a91906137e1565b905090565b6000610f3a81611712565b50600780546001600160a01b0319166001600160a01b0392909216919091179055600190565b610f897f8b5b16d04624687fcf0d0228f19993c9157c1ed07b41d8d430fd9100eb099fe8611712565b610b1a611e36565b60008060038481548110610fa757610fa761371a565b90600052602060002090600202019050600060038481548110610fcc57610fcc61371a565b90600052602060002090600202019050600060019050826001015482600101541015610ff6575060005b6000811561101957836001015483600101546110129190613703565b9050611030565b8260010154846001015461102d9190613703565b90505b600184015460009061104a83670de0b6b3a76400006137fe565b6110549190613833565b855485549192506000916110689190613703565b905060008161107b6301e13380856137fe565b6110859190613833565b9050611097655af3107a400082613833565b905084156110ad57965061091695505050505050565b6110b681613847565b9a9950505050505050505050565b60008281526001602052604081206109cb9083611e8e565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600061110f610eb2565b6001600160a01b0316336001600160a01b0316146111685760405162461bcd60e51b815260206004820152601660248201527518d85b1b195c88084f481b195b991a5b99c81c1bdbdb60521b6044820152606401610aba565b6001600160a01b03841630146111ad5760405162461bcd60e51b815260206004820152600a60248201526910b4b734ba34b0ba37b960b11b6044820152606401610aba565b6001601454146111ff5760405162461bcd60e51b815260206004820152601760248201527f696e76616c696420666c6173684c6f616e5374617475730000000000000000006044820152606401610aba565b600060145561120c611e9a565b5060019998505050505050505050565b611233600080516020613f47833981519152611712565b610a1081611faa565b611253600080516020613f47833981519152611712565b6042602160991b016001600160a01b0316816000815181106112775761127761371a565b60200260200101516001600160a01b03161480156112d25750600f5481516001600160a01b039091169082906112af90600190613703565b815181106112bf576112bf61371a565b60200260200101516001600160a01b0316145b6113155760405162461bcd60e51b8152602060048201526014602482015273092dcecc2d8d2c840dee0a8deaec2dce8a0c2e8d60631b6044820152606401610aba565b8051610acd906017906020840190613230565b6000818152600160205260408120610916906120d5565b611356600080516020613f47833981519152611712565b6042602160991b01828260008161136f5761136f61371a565b905060200201602081019061138491906133d3565b6001600160a01b03161480156113e65750737f5c764cbc14f9669b88837ca1490cca17c3160782826113b7600182613703565b8181106113c6576113c661371a565b90506020020160208101906113db91906133d3565b6001600160a01b0316145b6114295760405162461bcd60e51b8152602060048201526014602482015273092dcecc2d8d2c840dee0a8deaae6c8c6a0c2e8d60631b6044820152606401610aba565b610a4960168383613295565b60025460ff16156114585760405162461bcd60e51b8152600401610aba906136d9565b610b1a6120df565b61146a6000611712565b6103e881111561147957600080fd5b600a8190556040518181527f2e59d502792bca3d730c472cd3acfbc16d0f9fe6ce0cddbdf0f80830251dfaca906020015b60405180910390a150565b6000828152602081905260409020600101546114d1813361197e565b610a498383611a04565b6114e56000611712565b6001600160a01b0381166114f857600080fd5b600980546001600160a01b0319166001600160a01b0383169081179091556040519081527fa11c447ac90d9534769dc85d422963d67c1d8d899de887301417cedf4dec738d906020016114aa565b61155d600080516020613f47833981519152611712565b600455565b6003818154811061157257600080fd5b60009182526020909120600290910201805460019091015490915082565b600354600090600211156115a357600080fd5b600080600060016003805490506115ba9190613703565b90505b6000811180156115cc57508482125b15611611576115e56115df600183613703565b82610f91565b6115ef9084613864565b9250816115fb816138a5565b9250508080611609906138c5565b9150506115bd565b5061161c81836138dc565b949350505050565b61163b600080516020613f47833981519152611712565b610a1081612147565b61164e82826110dc565b610acd576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116843390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006109cb836001600160a01b03841661227c565b60006001600160e01b03198216637965db0b60e01b148061091657506301ffc9a760e01b6001600160e01b0319831614610916565b6006546000805b828110156117b057600681815481106117345761173461371a565b906000526020600020015484141561174e578091506117b0565b611759600184613703565b81141561179e5760405162461bcd60e51b8152602060048201526013602482015272756e617574686f72697a65642061636365737360681b6044820152606401610aba565b806117a88161390a565b915050611719565b5060005b818111611844576117e2600682815481106117d1576117d161371a565b9060005260206000200154336110dc565b156117ec57611844565b818114156118325760405162461bcd60e51b8152602060048201526013602482015272756e617574686f72697a65642061636365737360681b6044820152606401610aba565b8061183c8161390a565b9150506117b4565b50505050565b600f546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b79190613730565b90508082116118dd57600854600f54610acd916001600160a01b03918216911684611b8a565b60006118e98284613703565b90506000806118f6610d11565b90925090506119058383613703565b915060008261191557600061192c565b82611922612710846137fe565b61192c9190613833565b90506011548111156119505761194184612147565b61194b84876122cb565b611976565b60105481101561196c5761196484876122cb565b61194b6123fc565b61197684876122cb565b505050505050565b61198882826110dc565b610acd576119a0816001600160a01b0316601461246c565b6119ab83602061246c565b6040516020016119bc92919061394a565b60408051601f198184030181529082905262461bcd60e51b8252610aba916004016139bf565b6119ec8282611644565b6000828152600160205260409020610a4990826116c8565b611a0e8282612608565b6000828152600160205260409020610a49908261266d565b60025460ff16611a6f5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610aba565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b604051635fc87b1d60e11b815260009073929ec64c34a17401f460460d4b9390518e5b473e9063bf90f63a90611af4906015906004016139f2565b6000604051808303816000875af1158015611b13573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b3b9190810190613aa8565b5050611b45612682565b9050611b4f61292e565b611b57611435565b90565b600080611b65610d11565b90925090506000611b768284613703565b9050611b8181612147565b610a4981611faa565b6040516001600160a01b038316602482015260448101829052610a4990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a03565b6000611bf7610eb2565b60405163eddf1b7960e01b81523060048201526001600160a01b03919091169063eddf1b7990602401602060405180830381865afa158015611c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c619190613730565b905060008115611cf4576000611c75610eb2565b604051636c6f6ae160e01b815260ff851660048201526001600160a01b039190911690636c6f6ae190602401600060405180830381865afa158015611cbe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ce69190810190613b7f565b5161ffff169150611d829050565b600f54604051633e15014160e01b81526001600160a01b0390911660048201527369fa688f1dc47d4b5d8029d5a35fb7a54831065490633e1501419060240161014060405180830381865afa158015611d51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d759190613c86565b5096985050505050505050505b612710611d91612648836137fe565b611d9b9190613833565b831115611ddc5760405162461bcd60e51b815260206004820152600f60248201526e6d61784c7476206e6f74207361666560881b6044820152606401610aba565b82841115611e2c5760405162461bcd60e51b815260206004820152601860248201527f7461726765744c7476206d757374203c3d206d61784c747600000000000000006044820152606401610aba565b5050601155601055565b60025460ff1615611e595760405162461bcd60e51b8152600401610aba906136d9565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a9c3390565b60006109cb8383612ad5565b600f546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611ee3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f079190613730565b90508015610a1057611f2d611f1a610eb2565b600f546001600160a01b03169083612aff565b611f35610eb2565b600f5460405163617ba03760e01b81526001600160a01b039182166004820152602481018490523060448201526000606482015291169063617ba03790608401600060405180830381600087803b158015611f8f57600080fd5b505af1158015611fa3573d6000803e3d6000fd5b5050505050565b600080611fb5610d11565b91509150600060115460001415611fcd576000611fe6565b601154611fdc612710846137fe565b611fe69190613833565b90508083116120375760405162461bcd60e51b815260206004820152601860248201527f63616e277420776974686472617720616e797468696e672100000000000000006044820152606401610aba565b60006120438285613703565b905061204f8582612bb1565b9450612059610eb2565b600f54604051631a4ca37b60e21b81526001600160a01b039182166004820152602481018890523060448201529116906369328dec906064016020604051808303816000875af11580156120b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119769190613730565b6000610916825490565b6120e7611e9a565b6000806120f2610d11565b915091506000826000141561210857600061211f565b82612115612710846137fe565b61211f9190613833565b905060115481111561213557610a496000612147565b601054811015610a4957610a496123fc565b600080612152610d11565b909250905060006121638284613703565b9050808411156121a65760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b6044820152606401610aba565b60006121b28583613703565b905060006010546127106121c69190613703565b6010546121d390846137fe565b6121dd9190613833565b905060006121eb8286613703565b90506121f5610eb2565b600f54604051630b6b65f560e21b81526001600160a01b0391821660048201526024810184905260026044820152911690632dad97d4906064016020604051808303816000875af115801561224e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122729190613730565b5050505050505050565b60008181526001830160205260408120546122c357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610916565b506000610916565b6122d482611faa565b600f546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561231d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123419190613730565b9050818110156123cf5761271060135461271061235e9190613703565b61236890846137fe565b6123729190613833565b8110156123cf5760405162461bcd60e51b815260206004820152602560248201527f77697468647261773a206f75747369646520736c69707061676520746f6c6572604482015264616e63652160d81b6064820152608401610aba565b600854610a49906001600160a01b03166123e98385612bb1565b600f546001600160a01b03169190611b8a565b600080612407610d11565b909250905060006124188284613703565b9050600060105461271061242c9190613703565b60105461243990846137fe565b6124439190613833565b90506012548361245391906136c1565b811115611844576118446124678483613703565b612bc7565b6060600061247b8360026137fe565b6124869060026136c1565b67ffffffffffffffff81111561249e5761249e613541565b6040519080825280601f01601f1916602001820160405280156124c8576020820181803683370190505b509050600360fc1b816000815181106124e3576124e361371a565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106125125761251261371a565b60200101906001600160f81b031916908160001a90535060006125368460026137fe565b6125419060016136c1565b90505b60018111156125b9576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106125755761257561371a565b1a60f81b82828151811061258b5761258b61371a565b60200101906001600160f81b031916908160001a90535060049490941c936125b2816138c5565b9050612544565b5083156109cb5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610aba565b61261282826110dc565b15610acd576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006109cb836001600160a01b038416612d5d565b600a546040516370a0823160e01b8152306004820152600091829161271091906042602160991b01906370a0823190602401602060405180830381865afa1580156126d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f59190613730565b6126ff91906137fe565b6127099190613833565b90508061271857600091505090565b6040516370a0823160e01b8152306004820152737f5c764cbc14f9669b88837ca1490cca17c316079060009082906370a0823190602401602060405180830381865afa15801561276c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127909190613730565b90506127f660168054806020026020016040519081016040528092919081815260200182805480156127eb57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116127cd575b505050505084612e50565b6040516370a0823160e01b815230600482015260009082906001600160a01b038516906370a0823190602401602060405180830381865afa15801561283f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128639190613730565b61286d9190613703565b9050801561292757612710600b548261288691906137fe565b6128909190613833565b94506000612710600c54836128a591906137fe565b6128af9190613833565b90506000612710600d54836128c491906137fe565b6128ce9190613833565b90506128da8183613703565b91506128f06001600160a01b0386163389611b8a565b60075461290a906001600160a01b03878116911684611b8a565b600954612924906001600160a01b03878116911683611b8a565b50505b5050505090565b6040516370a0823160e01b81523060048201526000906042602160991b01906370a0823190602401602060405180830381865afa158015612973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129979190613730565b90508015610a1057610a1060178054806020026020016040519081016040528092919081815260200182805480156129f857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116129da575b505050505082612e50565b6000612a58826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131259092919063ffffffff16565b805190915015610a495780806020019051810190612a769190613d1d565b610a495760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610aba565b6000826000018281548110612aec57612aec61371a565b9060005260206000200154905092915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612b50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b749190613730565b612b7e91906136c1565b6040516001600160a01b03851660248201526044810182905290915061184490859063095ea7b360e01b90606401611bb6565b6000818310612bc057816109cb565b5090919050565b80612c0a5760405162461bcd60e51b8152602060048201526013602482015272464c3a20696e76616c696420616d6f756e742160681b6044820152606401610aba565b604080516001808252818301909252600091602080830190803683375050600f5482519293506001600160a01b031691839150600090612c4c57612c4c61371a565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508281600081518110612c9d57612c9d61371a565b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050600281600081518110612ce157612ce161371a565b60209081029190910101526001601455612cf9610eb2565b6001600160a01b031663ab9c4b5d308585853060006040518763ffffffff1660e01b8152600401612d2f96959493929190613d73565b600060405180830381600087803b158015612d4957600080fd5b505af1158015612272573d6000803e3d6000fd5b60008181526001830160205260408120548015612e46576000612d81600183613703565b8554909150600090612d9590600190613703565b9050818114612dfa576000866000018281548110612db557612db561371a565b9060005260206000200154905080876000018481548110612dd857612dd861371a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612e0b57612e0b613e1e565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610916565b6000915050610916565b815173a132dab612db5cb9fc9ac426a0cc215a3423f9c990600090612e7790600190613703565b67ffffffffffffffff811115612e8f57612e8f613541565b604051908082528060200260200182016040528015612eda57816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181612ead5790505b50905082600080805b845181101561305c57856001600160a01b0316635e1e6325858a8481518110612f0e57612f0e61371a565b60200260200101518b856001612f2491906136c1565b81518110612f3457612f3461371a565b60200260200101516040518463ffffffff1660e01b8152600401612f74939291909283526001600160a01b03918216602084015216604082015260600190565b6040805180830381865afa158015612f90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb49190613e34565b80935081945050506040518060600160405280898381518110612fd957612fd961371a565b60200260200101516001600160a01b0316815260200189836001612ffd91906136c1565b8151811061300d5761300d61371a565b60200260200101516001600160a01b0316815260200183151581525085828151811061303b5761303b61371a565b602002602001018190525082935080806130549061390a565b915050612ee3565b506130a973a132dab612db5cb9fc9ac426a0cc215a3423f9c987896000815181106130895761308961371a565b60200260200101516001600160a01b0316612aff9092919063ffffffff16565b604051631e82ecdb60e31b81526001600160a01b0386169063f41766d8906130de908990600090899030904290600401613e60565b6000604051808303816000875af11580156130fd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122729190810190613ef5565b606061161c848460008585843b61317e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aba565b600080866001600160a01b0316858760405161319a9190613f2a565b60006040518083038185875af1925050503d80600081146131d7576040519150601f19603f3d011682016040523d82523d6000602084013e6131dc565b606091505b50915091506131ec8282866131f7565b979650505050505050565b606083156132065750816109cb565b8251156132165782518084602001fd5b8160405162461bcd60e51b8152600401610aba91906139bf565b828054828255906000526020600020908101928215613285579160200282015b8281111561328557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613250565b506132919291506132e8565b5090565b828054828255906000526020600020908101928215613285579160200282015b828111156132855781546001600160a01b0319166001600160a01b038435161782556020909201916001909101906132b5565b5b8082111561329157600081556001016132e9565b60006020828403121561330f57600080fd5b81356001600160e01b0319811681146109cb57600080fd5b60006020828403121561333957600080fd5b5035919050565b60008060006060848603121561335557600080fd5b505081359360208301359350604090920135919050565b6001600160a01b0381168114610a1057600080fd5b6000806040838503121561339457600080fd5b8235915060208301356133a68161336c565b809150509250929050565b600080604083850312156133c457600080fd5b50508035926020909101359150565b6000602082840312156133e557600080fd5b81356109cb8161336c565b60008083601f84011261340257600080fd5b50813567ffffffffffffffff81111561341a57600080fd5b6020830191508360208260051b850101111561343557600080fd5b9250929050565b600080600080600080600080600060a08a8c03121561345a57600080fd5b893567ffffffffffffffff8082111561347257600080fd5b61347e8d838e016133f0565b909b50995060208c013591508082111561349757600080fd5b6134a38d838e016133f0565b909950975060408c01359150808211156134bc57600080fd5b6134c88d838e016133f0565b909750955060608c013591506134dd8261336c565b90935060808b013590808211156134f357600080fd5b818c0191508c601f83011261350757600080fd5b81358181111561351657600080fd5b8d602082850101111561352857600080fd5b6020830194508093505050509295985092959850929598565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff8111828210171561357a5761357a613541565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156135a9576135a9613541565b604052919050565b600067ffffffffffffffff8211156135cb576135cb613541565b5060051b60200190565b600060208083850312156135e857600080fd5b823567ffffffffffffffff8111156135ff57600080fd5b8301601f8101851361361057600080fd5b803561362361361e826135b1565b613580565b81815260059190911b8201830190838101908783111561364257600080fd5b928401925b828410156131ec57833561365a8161336c565b82529284019290840190613647565b6000806020838503121561367c57600080fd5b823567ffffffffffffffff81111561369357600080fd5b61369f858286016133f0565b90969095509350505050565b634e487b7160e01b600052601160045260246000fd5b600082198211156136d4576136d46136ab565b500190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b600082821015613715576137156136ab565b500390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561374257600080fd5b5051919050565b8051801515811461375957600080fd5b919050565b60008060008060008060008060006101208a8c03121561377d57600080fd5b8951985060208a0151975060408a0151965060608a0151955060808a0151945060a08a0151935060c08a0151925060e08a015164ffffffffff811681146137c357600080fd5b91506137d26101008b01613749565b90509295985092959850929598565b6000602082840312156137f357600080fd5b81516109cb8161336c565b6000816000190483118215151615613818576138186136ab565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826138425761384261381d565b500490565b6000600160ff1b82141561385d5761385d6136ab565b5060000390565b600080821280156001600160ff1b0384900385131615613886576138866136ab565b600160ff1b839003841281161561389f5761389f6136ab565b50500190565b60006001600160ff1b038214156138be576138be6136ab565b5060010190565b6000816138d4576138d46136ab565b506000190190565b6000826138eb576138eb61381d565b600160ff1b821460001984141615613905576139056136ab565b500590565b60006000198214156138be576138be6136ab565b60005b83811015613939578181015183820152602001613921565b838111156118445750506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161398281601785016020880161391e565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516139b381602884016020880161391e565b01602801949350505050565b60208152600082518060208401526139de81604085016020870161391e565b601f01601f19169190910160400192915050565b6020808252825482820181905260008481528281209092916040850190845b81811015613a365783546001600160a01b031683526001938401939285019201613a11565b50909695505050505050565b600082601f830112613a5357600080fd5b81516020613a6361361e836135b1565b82815260059290921b84018101918181019086841115613a8257600080fd5b8286015b84811015613a9d5780518352918301918301613a86565b509695505050505050565b60008060408385031215613abb57600080fd5b825167ffffffffffffffff80821115613ad357600080fd5b818501915085601f830112613ae757600080fd5b81516020613af761361e836135b1565b82815260059290921b84018101918181019089841115613b1657600080fd5b948201945b83861015613b3d578551613b2e8161336c565b82529482019490820190613b1b565b91880151919650909350505080821115613b5657600080fd5b50613b6385828601613a42565b9150509250929050565b805161ffff8116811461375957600080fd5b60006020808385031215613b9257600080fd5b825167ffffffffffffffff80821115613baa57600080fd5b9084019060a08287031215613bbe57600080fd5b613bc6613557565b613bcf83613b6d565b8152613bdc848401613b6d565b84820152613bec60408401613b6d565b60408201526060830151613bff8161336c565b6060820152608083015182811115613c1657600080fd5b80840193505086601f840112613c2b57600080fd5b825182811115613c3d57613c3d613541565b613c4f601f8201601f19168601613580565b92508083528785828601011115613c6557600080fd5b613c748186850187870161391e565b50608081019190915295945050505050565b6000806000806000806000806000806101408b8d031215613ca657600080fd5b8a51995060208b0151985060408b0151975060608b0151965060808b01519550613cd260a08c01613749565b9450613ce060c08c01613749565b9350613cee60e08c01613749565b9250613cfd6101008c01613749565b9150613d0c6101208c01613749565b90509295989b9194979a5092959850565b600060208284031215613d2f57600080fd5b6109cb82613749565b600081518084526020808501945080840160005b83811015613d6857815187529582019590820190600101613d4c565b509495945050505050565b6001600160a01b03878116825260e06020808401829052885191840182905260009289820192909190610100860190855b81811015613dc2578551851683529483019491830191600101613da4565b50508581036040870152613dd6818b613d38565b93505050508281036060840152613ded8187613d38565b6001600160a01b038616608085015283810360a08501526000815261ffff851660c085015260200191506131ec9050565b634e487b7160e01b600052603160045260246000fd5b60008060408385031215613e4757600080fd5b82519150613e5760208401613749565b90509250929050565b600060a0820187835260208781850152604060a08186015282885180855260c087019150838a01945060005b81811015613ec957855180516001600160a01b03908116855286820151168685015284015115158484015294840194606090920191600101613e8c565b50506001600160a01b03881660608701529350613ee592505050565b8260808301529695505050505050565b600060208284031215613f0757600080fd5b815167ffffffffffffffff811115613f1e57600080fd5b61161c84828501613a42565b60008251613f3c81846020870161391e565b919091019291505056feb17d0a42cc710456bf9c3efb785dcd0cb93a0ac358113307b5c64b285b516b5ca2646970667358221220981d059dfaa6c075b82a22a796b5a234884ad2a520dc2a196ffd10dfeecf69cb64736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000df2d2c477078d2cd563648abbb913da3db247c00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000e50fa9b3c56ffb159cb0fca61f5c9d750e8128c800000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000001e140000000000000000000000000000000000000000000000000000000000001e7800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000eb9c9b785aa7818b2ebc8f9842926c4b9f707e4b0000000000000000000000002b394b228908fb7dacaff5f340f1b442a39b056c00000000000000000000000000000000000000000000000000000000000000030000000000000000000000001e71aee6081f62053123140aacc7a06021d7734800000000000000000000000081876677843d00a7d792e1617459ac2e932025760000000000000000000000001a20d7a31e5b3bc5f02c8a146ef6f394502a10c400000000000000000000000000000000000000000000000000000000000000030000000000000000000000003aa60c3ae4b94515fa1fd0ffee77d02b6a0609f3000000000000000000000000eb9c9b785aa7818b2ebc8f9842926c4b9f707e4b000000000000000000000000b0c9d5851def8a2aac4a23031ca2610f8c3483f9000000000000000000000000000000000000000000000000000000000000000200000000000000000000000042000000000000000000000000000000000000420000000000000000000000004200000000000000000000000000000000000006
-----Decoded View---------------
Arg [0] : _vault (address): 0xdf2D2c477078D2cD563648abbb913dA3Db247c00
Arg [1] : _feeRemitters (address[]): 0xeb9C9b785aA7818B2EBC8f9842926c4B9f707e4B,0x2b394b228908fb7DAcafF5F340f1b442a39B056C
Arg [2] : _strategists (address[]): 0x1E71AEE6081f62053123140aacC7a06021D77348,0x81876677843D00a7D792E1617459aC2E93202576,0x1A20D7A31e5B3Bc5f02c8A146EF6f394502a10c4
Arg [3] : _multisigRoles (address[]): 0x3aa60C3ae4b94515Fa1FD0fFEe77d02B6a0609f3,0xeb9C9b785aA7818B2EBC8f9842926c4B9f707e4B,0xb0C9D5851deF8A2Aac4A23031CA2610f8C3483F9
Arg [4] : _aWant (address): 0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8
Arg [5] : _opToWantPath (address[]): 0x4200000000000000000000000000000000000042,0x4200000000000000000000000000000000000006
Arg [6] : _targetLtv (uint256): 7700
Arg [7] : _maxLtv (uint256): 7800
Arg [8] : _eModeCategory (uint8): 0
-----Encoded View---------------
23 Constructor Arguments found :
Arg [0] : 000000000000000000000000df2d2c477078d2cd563648abbb913da3db247c00
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [4] : 000000000000000000000000e50fa9b3c56ffb159cb0fca61f5c9d750e8128c8
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000280
Arg [6] : 0000000000000000000000000000000000000000000000000000000000001e14
Arg [7] : 0000000000000000000000000000000000000000000000000000000000001e78
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [10] : 000000000000000000000000eb9c9b785aa7818b2ebc8f9842926c4b9f707e4b
Arg [11] : 0000000000000000000000002b394b228908fb7dacaff5f340f1b442a39b056c
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [13] : 0000000000000000000000001e71aee6081f62053123140aacc7a06021d77348
Arg [14] : 00000000000000000000000081876677843d00a7d792e1617459ac2e93202576
Arg [15] : 0000000000000000000000001a20d7a31e5b3bc5f02c8a146ef6f394502a10c4
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [17] : 0000000000000000000000003aa60c3ae4b94515fa1fd0ffee77d02b6a0609f3
Arg [18] : 000000000000000000000000eb9c9b785aa7818b2ebc8f9842926c4b9f707e4b
Arg [19] : 000000000000000000000000b0c9d5851def8a2aac4a23031ca2610f8c3483f9
Arg [20] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [21] : 0000000000000000000000004200000000000000000000000000000000000042
Arg [22] : 0000000000000000000000004200000000000000000000000000000000000006
Deployed Bytecode Sourcemap
928:15804:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;619:212:20;;;;;;:::i;:::-;;:::i;:::-;;;470:14:33;;463:22;445:41;;433:2;418:18;619:212:20;;;;;;;;4200:155:0;1222:42;4200:155;;;-1:-1:-1;;;;;692:32:33;;;674:51;;662:2;647:18;4200:155:0;497:234:33;2814:37:0;;;;;;:::i;:::-;;:::i;1172:92::-;;1222:42;1172:92;;402:43:1;;437:8;402:43;;;;;1384:25:33;;;1372:2;1357:18;402:43:1;1238:177:33;3085:23:1;;;;;;1531:18:0;;;;;-1:-1:-1;;;;;1531:18:0;;;8911:492:1;;;;;;:::i;:::-;;:::i;611:35::-;;;;;;3977:121:19;;;;;;:::i;:::-;4043:7;4069:12;;;;;;;;;;:22;;;;3977:121;1636:50:1;;1668:18;1636:50;;1505:20:0;;;;;-1:-1:-1;;;;;1505:20:0;;;6169:101:1;6246:10;:17;6169:101;;5313:199;;;;;;:::i;:::-;;:::i;:::-;;3070:29:0;;;;;;:::i;:::-;;:::i;4348:145:19:-;;;;;;:::i;:::-;;:::i;5365:214::-;;;;;;:::i;:::-;;:::i;3035:29:0:-;;;;;;:::i;:::-;;:::i;1626:21::-;;;;;;1363:92;;1413:42;1363:92;;8165:112:1;;;:::i;15611:370:0:-;;;;;;:::i;:::-;;:::i;5691:472:1:-;;;:::i;7625:115::-;;;:::i;348:48::-;;390:6;348:48;;12824:294:0;;;:::i;:::-;;;;3438:25:33;;;3494:2;3479:18;;3472:34;;;;3411:18;12824:294:0;3264:248:33;3174:28:1;;;;;;1098:84:23;1168:7;;;;1098:84;;1978:23:1;;;;;-1:-1:-1;;;;;1978:23:1;;;14290:141:0;;;;;;:::i;:::-;;:::i;15263:163::-;;;;;;:::i;:::-;;:::i;1086:80::-;;1124:42;1086:80;;14611:237;;;:::i;1574:56:1:-;;1609:21;1574:56;;573:32;;;;;;4361:114:0;;;:::i;2658:71::-;;-1:-1:-1;;;;;2658:71:0;;1270:87;;1315:42;1270:87;;9490:171:1;;;;;;:::i;:::-;;:::i;7911:90::-;;;:::i;1450:52::-;;1483:19;1450:52;;2033:33;;;;;-1:-1:-1;;;;;2033:33:1;;;2735:73:0;;2766:42;2735:73;;10194:1124:1;;;;;;:::i;:::-;;:::i;1416:143:20:-;;;;;;:::i;:::-;;:::i;3114:22:1:-;;;;;;2894:137:19;;;;;;:::i;:::-;;:::i;4481:700:0:-;;;;;;:::i;:::-;;:::i;1508:60:1:-;;-1:-1:-1;;;;;;;;;;;1508:60:1;;2012:49:19;;2057:4;2012:49;;14011:143:0;;;;;;:::i;:::-;;:::i;13423:228::-;;;;;;:::i;:::-;;:::i;2345:38:1:-;;2379:4;2345:38;;1731:40:0;;;;;;1727:132:20;;;;;;:::i;:::-;;:::i;13194:223:0:-;;;;;;:::i;:::-;;:::i;3142:26:1:-;;;;;;5035:76;;;:::i;1693:32:0:-;;;;;;8373:210:1;;;;;;:::i;:::-;;:::i;4727:147:19:-;;;;;;:::i;:::-;;:::i;9772:296:1:-;;;;;;:::i;:::-;;:::i;7047:163::-;;;;;;:::i;:::-;;:::i;1556:24:0:-;;;;;;2389:49:1;;2434:4;2389:49;;540:27;;;;;;:::i;:::-;;:::i;6508:435::-;;;;;;:::i;:::-;;:::i;13743:132:0:-;;;;;;:::i;:::-;;:::i;2007:20:1:-;;;;;-1:-1:-1;;;;;2007:20:1;;;619:212:20;704:4;-1:-1:-1;;;;;;727:57:20;;-1:-1:-1;;;727:57:20;;:97;;;788:36;812:11;788:23;:36::i;:::-;720:104;619:212;-1:-1:-1;;619:212:20:o;2814:37:0:-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2814:37:0;;-1:-1:-1;2814:37:0;:::o;8911:492:1:-;9043:4;9059:32;9043:4;9059:12;:32::i;:::-;390:6;9109:23;9120:12;9109:8;:23;:::i;:::-;:42;9101:51;;;;;;2434:4;9170:14;:36;;9162:45;;;;;;9218:7;:18;;;9246:11;:26;;;9282:13;:30;;;9327:48;;;9396:25:33;;;9452:2;9437:18;;9430:34;;;9480:18;;;9473:34;;;9327:48:1;;9384:2:33;9369:18;9327:48:1;;;;;;;-1:-1:-1;9392:4:1;8911:492;;;;;;:::o;5313:199::-;5398:5;;-1:-1:-1;;;;;5398:5:1;5384:10;:19;5376:28;;;;;;5422:12;5414:21;;;;;;5464:11;:9;:11::i;:::-;5453:7;:22;;5445:31;;;;;;5487:18;5497:7;5487:9;:18::i;:::-;5313:199;:::o;3070:29:0:-;;;;;;;;;;;;4348:145:19;4043:7;4069:12;;;;;;;;;;:22;;;2490:30;2501:4;719:10:27;2490::19;:30::i;:::-;4461:25:::1;4472:4;4478:7;4461:10;:25::i;:::-;4348:145:::0;;;:::o;5365:214::-;-1:-1:-1;;;;;5460:23:19;;719:10:27;5460:23:19;5452:83;;;;-1:-1:-1;;;5452:83:19;;9862:2:33;5452:83:19;;;9844:21:33;9901:2;9881:18;;;9874:30;9940:34;9920:18;;;9913:62;-1:-1:-1;;;9991:18:33;;;9984:45;10046:19;;5452:83:19;;;;;;;;;5546:26;5558:4;5564:7;5546:11;:26::i;:::-;5365:214;;:::o;3035:29:0:-;;;;;;;;;;;;8165:112:1;8212:19;1668:18;8212:12;:19::i;:::-;8241:10;:8;:10::i;:::-;8261:9;:7;:9::i;:::-;8165:112::o;15611:370:0:-;15727:24;-1:-1:-1;;;;;;;;;;;15727:12:0;:24::i;:::-;2374:3;15770:29;:64;;15762:94;;;;-1:-1:-1;;;15762:94:0;;10278:2:33;15762:94:0;;;10260:21:33;10317:2;10297:18;;;10290:30;-1:-1:-1;;;10336:18:33;;;10329:47;10393:18;;15762:94:0;10076:341:33;15762:94:0;15866:25;:57;;;;15933:17;:41;15611:370::o;5691:472:1:-;5751:17;1412:8:23;1168:7;;;;;1098:84;1412:8;1411:9;1403:38;;;;-1:-1:-1;;;1403:38:23;;;;;;;:::i;:::-;5792:14:1::1;:12;:14::i;:::-;5780:26;;5886:17;;5840:10;5871:1;5851:10;:17;;;;:21;;;;:::i;:::-;5840:33;;;;;;;;:::i;:::-;;;;;;;;;;;:43;;;:63;;;;:::i;:::-;5821:15;:82;5817:252;;5952:92;::::0;;;;::::1;::::0;;5972:15:::1;5952:92:::0;;6013:5:::1;::::0;6006:36;;-1:-1:-1;;;6006:36:1;;;;5919:10:::1;::::0;5952:92:::1;::::0;;::::1;::::0;-1:-1:-1;;;;;6013:5:1::1;::::0;6006:34:::1;::::0;:36:::1;::::0;;::::1;::::0;5952:92;6006:36;;;;;;6013:5;6006:36:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5952:92:::0;;5919:139;;::::1;::::0;;::::1;::::0;;-1:-1:-1;5919:139:1;;;::::1;::::0;;;;;;::::1;::::0;;::::1;;::::0;;;;;;::::1;::::0;;::::1;::::0;5817:252:::1;6102:15;6079:20;:38:::0;6132:24:::1;::::0;6145:10:::1;::::0;6132:24:::1;::::0;;;::::1;5691:472:::0;:::o;7625:115::-;7670:22;1609:21;7670:12;:22::i;:::-;7702:14;:12;:14::i;:::-;7726:7;:5;:7::i;12824:294:0:-;13036:4;;12950:128;;-1:-1:-1;;;12950:128:0;;-1:-1:-1;;;;;13036:4:0;;;12950:128;;;11430:34:33;13063:4:0;11480:18:33;;;11473:43;12875:14:0;;;;1315:42;;12950:64;;11365:18:33;;12950:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;12917:161:0;;;;-1:-1:-1;12824:294:0;;-1:-1:-1;;;;;;;12824:294:0:o;14290:141::-;14357:24;-1:-1:-1;;;;;;;;;;;14357:12:0;:24::i;:::-;14409:5;;14391:4;;:33;;-1:-1:-1;;;;;14391:4:0;;;;14409:5;14416:7;14391:17;:33::i;15263:163::-;15342:20;1483:19:1;15342:12:0;:20::i;:::-;15372:47;15393:13;15408:10;15372:20;:47::i;14611:237::-;14662:7;14682:14;14698;14716:20;:18;:20::i;:::-;14681:55;;-1:-1:-1;14681:55:0;-1:-1:-1;14746:18:0;14767:15;14681:55;;14767:15;:::i;:::-;14812:4;;:29;;-1:-1:-1;;;14812:29:0;;14835:4;14812:29;;;674:51:33;14746:36:0;;-1:-1:-1;;;;;;14812:4:0;;:14;;647:18:33;;14812:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14799:42;;:10;:42;:::i;:::-;14792:49;;;;;14611:237;:::o;4361:114::-;4407:5;1222:42;-1:-1:-1;;;;;4437:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4424:44;;4361:114;:::o;9490:171:1:-;9553:4;9569:32;9553:4;9569:12;:32::i;:::-;-1:-1:-1;9611:8:1;:22;;-1:-1:-1;;;;;;9611:22:1;-1:-1:-1;;;;;9611:22:1;;;;;;;;;;-1:-1:-1;;9490:171:1:o;7911:90::-;7954:22;1609:21;7954:12;:22::i;:::-;7986:8;:6;:8::i;10194:1124::-;10286:6;10304:21;10328:10;10339:11;10328:23;;;;;;;;:::i;:::-;;;;;;;;;;;10304:47;;10361:19;10383:10;10394:9;10383:21;;;;;;;;:::i;:::-;;;;;;;;;;;10361:43;;10414:15;10432:4;10414:22;;10472:5;:21;;;10450:3;:19;;;:43;10446:92;;;-1:-1:-1;10522:5:1;10446:92;10548:32;10594:10;10590:212;;;10669:5;:21;;;10647:3;:19;;;:43;;;;:::i;:::-;10620:70;;10590:212;;;10772:3;:19;;;10748:5;:21;;;:43;;;;:::i;:::-;10721:70;;10590:212;10883:21;;;;10812:32;;10848:31;:24;10875:4;10848:31;:::i;:::-;10847:57;;;;:::i;:::-;10955:15;;10939:13;;10812:92;;-1:-1:-1;10914:22:1;;10939:31;;10955:15;10939:31;:::i;:::-;10914:56;-1:-1:-1;10981:38:1;10914:56;11023:35;437:8;11023:24;:35;:::i;:::-;11022:54;;;;:::i;:::-;10981:95;-1:-1:-1;11086:38:1;11120:4;10981:95;11086:38;:::i;:::-;;;11173:10;11169:86;;;11213:30;-1:-1:-1;11199:45:1;;-1:-1:-1;;;;;;11199:45:1;11169:86;11272:39;11280:30;11272:39;:::i;:::-;11265:46;10194:1124;-1:-1:-1;;;;;;;;;;10194:1124:1:o;1416:143:20:-;1498:7;1524:18;;;:12;:18;;;;;:28;;1546:5;1524:21;:28::i;2894:137:19:-;2972:4;2995:12;;;;;;;;;;;-1:-1:-1;;;;;2995:29:19;;;;;;;;;;;;;;;2894:137::o;4481:700:0:-;4675:4;4721:6;:4;:6::i;:::-;-1:-1:-1;;;;;4699:29:0;:10;-1:-1:-1;;;;;4699:29:0;;4691:64;;;;-1:-1:-1;;;4691:64:0;;13524:2:33;4691:64:0;;;13506:21:33;13563:2;13543:18;;;13536:30;-1:-1:-1;;;13582:18:33;;;13575:52;13644:18;;4691:64:0;13322:346:33;4691:64:0;-1:-1:-1;;;;;4773:26:0;;4794:4;4773:26;4765:49;;;;-1:-1:-1;;;4765:49:0;;13875:2:33;4765:49:0;;;13857:21:33;13914:2;13894:18;;;13887:30;-1:-1:-1;;;13933:18:33;;;13926:40;13983:18;;4765:49:0;13673:334:33;4765:49:0;2059:1;4832:15;;:41;4824:77;;;;-1:-1:-1;;;4824:77:0;;14214:2:33;4824:77:0;;;14196:21:33;14253:2;14233:18;;;14226:30;14292:25;14272:18;;;14265:53;14335:18;;4824:77:0;14012:347:33;4824:77:0;2002:1;4911:15;:35;5143:9;:7;:9::i;:::-;-1:-1:-1;5170:4:0;4481:700;;;;;;;;;;;:::o;14011:143::-;14085:24;-1:-1:-1;;;;;;;;;;;14085:12:0;:24::i;:::-;14119:28;14139:7;14119:19;:28::i;13423:228::-;13489:24;-1:-1:-1;;;;;;;;;;;13489:12:0;:24::i;:::-;-1:-1:-1;;;;;;;;;;13531:14:0;:5;13537:1;13531:8;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;13531:14:0;;:58;;;;-1:-1:-1;13584:4:0;;13555:12;;-1:-1:-1;;;;;13584:4:0;;;;13549:5;;13555:16;;13584:4;;13555:16;:::i;:::-;13549:23;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;13549:40:0;;13531:58;13523:91;;;;-1:-1:-1;;;13523:91:0;;14566:2:33;13523:91:0;;;14548:21:33;14605:2;14585:18;;;14578:30;-1:-1:-1;;;14624:18:33;;;14617:50;14684:18;;13523:91:0;14364:344:33;13523:91:0;13624:20;;;;:12;;:20;;;;;:::i;1727:132:20:-;1799:7;1825:18;;;:12;:18;;;;;:27;;:25;:27::i;13194:223:0:-;13264:24;-1:-1:-1;;;;;;;;;;;13264:12:0;:24::i;:::-;-1:-1:-1;;;;;13306:5:0;;13312:1;13306:8;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;13306:14:0;;:49;;;;-1:-1:-1;2766:42:0;13324:5;;13330:16;13345:1;13324:5;13330:16;:::i;:::-;13324:23;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;13324:31:0;;13306:49;13298:82;;;;-1:-1:-1;;;13298:82:0;;14915:2:33;13298:82:0;;;14897:21:33;14954:2;14934:18;;;14927:30;-1:-1:-1;;;14973:18:33;;;14966:50;15033:18;;13298:82:0;14713:344:33;13298:82:0;13390:20;:12;13405:5;;13390:20;:::i;5035:76:1:-;1168:7:23;;;;1411:9;1403:38;;;;-1:-1:-1;;;1403:38:23;;;;;;;:::i;:::-;5094:10:1::1;:8;:10::i;8373:210::-:0;8435:32;2057:4:19;8435:12:1;:32::i;:::-;2379:4;8485:9;:20;;8477:29;;;;;;8516:8;:20;;;8551:25;;1384::33;;;8551::1;;1372:2:33;1357:18;8551:25:1;;;;;;;;8373:210;:::o;4727:147:19:-;4043:7;4069:12;;;;;;;;;;:22;;;2490:30;2501:4;719:10:27;2490::19;:30::i;:::-;4841:26:::1;4853:4;4859:7;4841:11;:26::i;9772:296:1:-:0;9857:32;2057:4:19;9857:12:1;:32::i;:::-;-1:-1:-1;;;;;9907:36:1;;9899:45;;;;;;9954:18;:43;;-1:-1:-1;;;;;;9954:43:1;-1:-1:-1;;;;;9954:43:1;;;;;;;;10012:49;;674:51:33;;;10012:49:1;;662:2:33;647:18;10012:49:1;497:234:33;7047:163:1;7129:24;-1:-1:-1;;;;;;;;;;;7129:12:1;:24::i;:::-;7163:17;:40;7047:163::o;540:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;540:27:1;:::o;6508:435::-;6607:10;:17;6581:6;;6628:1;-1:-1:-1;6607:22:1;6599:31;;;;;;6641:20;6671:23;6710:9;6742:1;6722:10;:17;;;;:21;;;;:::i;:::-;6710:33;;6705:182;6749:1;6745;:5;:30;;;;;6773:2;6754:16;:21;6745:30;6705:182;;;6813:31;6835:5;6839:1;6835;:5;:::i;:::-;6842:1;6813:21;:31::i;:::-;6796:48;;;;:::i;:::-;;-1:-1:-1;6858:18:1;;;;:::i;:::-;;;;6777:3;;;;;:::i;:::-;;;;6705:182;;;-1:-1:-1;6904:32:1;6920:16;6904:13;:32;:::i;:::-;6897:39;6508:435;-1:-1:-1;;;;6508:435:1:o;13743:132:0:-;13806:24;-1:-1:-1;;;;;;;;;;;13806:12:0;:24::i;:::-;13840:28;13860:7;13840:19;:28::i;6822:233:19:-;6905:22;6913:4;6919:7;6905;:22::i;:::-;6900:149;;6943:6;:12;;;;;;;;;;;-1:-1:-1;;;;;6943:29:19;;;;;;;;;:36;;-1:-1:-1;;6943:36:19;6975:4;6943:36;;;7025:12;719:10:27;;640:96;7025:12:19;-1:-1:-1;;;;;6998:40:19;7016:7;-1:-1:-1;;;;;6998:40:19;7010:4;6998:40;;;;;;;;;;6822:233;;:::o;7612:150:32:-;7682:4;7705:50;7710:3;-1:-1:-1;;;;;7730:23:32;;7705:4;:50::i;2605:202:19:-;2690:4;-1:-1:-1;;;;;;2713:47:19;;-1:-1:-1;;;2713:47:19;;:87;;-1:-1:-1;;;;;;;;;;937:40:29;;;2764:36:19;829:155:29;11649:681:1;11728:15;:22;11709:16;;11796:264;11820:8;11816:1;:12;11796:264;;;11861:15;11877:1;11861:18;;;;;;;;:::i;:::-;;;;;;;;;11853:4;:26;11849:201;;;11920:1;11899:22;;11939:5;;11849:201;11974:12;11985:1;11974:8;:12;:::i;:::-;11969:1;:17;11965:85;;;12006:29;;-1:-1:-1;;;12006:29:1;;16025:2:33;12006:29:1;;;16007:21:33;16064:2;16044:18;;;16037:30;-1:-1:-1;;;16083:18:33;;;16076:49;16142:18;;12006:29:1;15823:343:33;11965:85:1;11830:3;;;;:::i;:::-;;;;11796:264;;;;12075:9;12070:254;12095:18;12090:1;:23;12070:254;;12138:39;12146:15;12162:1;12146:18;;;;;;;;:::i;:::-;;;;;;;;;12166:10;12138:7;:39::i;:::-;12134:180;;;12197:5;;12134:180;12232:18;12227:1;:23;12223:91;;;12270:29;;-1:-1:-1;;;12270:29:1;;16025:2:33;12270:29:1;;;16007:21:33;16064:2;16044:18;;;16037:30;-1:-1:-1;;;16083:18:33;;;16076:49;16142:18;;12270:29:1;15823:343:33;12223:91:1;12115:3;;;;:::i;:::-;;;;12070:254;;;;11699:631;;11649:681;:::o;5787:820:0:-;5869:4;;:29;;-1:-1:-1;;;5869:29:0;;5892:4;5869:29;;;674:51:33;5851:15:0;;-1:-1:-1;;;;;5869:4:0;;:14;;647:18:33;;5869:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5851:47;;5923:7;5912;:18;5908:102;;5964:5;;5946:4;;:33;;-1:-1:-1;;;;;5946:4:0;;;;5964:5;5971:7;5946:17;:33::i;5908:102::-;6020:17;6040;6050:7;6040;:17;:::i;:::-;6020:37;;6068:14;6084;6102:20;:18;:20::i;:::-;6067:55;;-1:-1:-1;6067:55:0;-1:-1:-1;6132:19:0;6142:9;6067:55;6132:19;:::i;:::-;;-1:-1:-1;6161:23:0;6187:11;:53;;6239:1;6187:53;;;6230:6;6202:24;390:6:1;6202::0;:24;:::i;:::-;6201:35;;;;:::i;:::-;6161:79;;6273:6;;6255:15;:24;6251:350;;;6295:30;6315:9;6295:19;:30::i;:::-;6339:43;6363:9;6374:7;6339:23;:43::i;:::-;6251:350;;;6421:9;;6403:15;:27;6399:202;;;6446:43;6470:9;6481:7;6446:23;:43::i;:::-;6503:13;:11;:13::i;6399:202::-;6547:43;6571:9;6582:7;6547:23;:43::i;:::-;5841:766;;;;;5787:820;:::o;3312:484:19:-;3392:22;3400:4;3406:7;3392;:22::i;:::-;3387:403;;3575:41;3603:7;-1:-1:-1;;;;;3575:41:19;3613:2;3575:19;:41::i;:::-;3687:38;3715:4;3722:2;3687:19;:38::i;:::-;3482:265;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;3482:265:19;;;;;;;;;;-1:-1:-1;;;3430:349:19;;;;;;;:::i;1947:166:20:-;2034:31;2051:4;2057:7;2034:16;:31::i;:::-;2075:18;;;;:12;:18;;;;;:31;;2098:7;2075:22;:31::i;2202:171::-;2290:32;2308:4;2314:7;2290:17;:32::i;:::-;2332:18;;;;:12;:18;;;;;:34;;2358:7;2332:25;:34::i;2110:117:23:-;1168:7;;;;1669:41;;;;-1:-1:-1;;;1669:41:23;;17955:2:33;1669:41:23;;;17937:21:33;17994:2;17974:18;;;17967:30;-1:-1:-1;;;18013:18:33;;;18006:50;18073:18;;1669:41:23;17753:344:33;1669:41:23;2168:7:::1;:15:::0;;-1:-1:-1;;2168:15:23::1;::::0;;2198:22:::1;719:10:27::0;2207:12:23::1;2198:22;::::0;-1:-1:-1;;;;;692:32:33;;;674:51;;662:2;647:18;2198:22:23::1;;;;;;;2110:117::o:0;9583:267:0:-;9663:87;;-1:-1:-1;;;9663:87:0;;9634:17;;1413:42;;9663:65;;:87;;9729:20;;9663:87;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9663:87:0;;;;;;;;;;;;:::i;:::-;;;9772:24;:22;:24::i;:::-;9760:36;;9806:18;:16;:18::i;:::-;9834:9;:7;:9::i;:::-;9583:267;:::o;14921:242::-;14974:14;14990;15008:20;:18;:20::i;:::-;14973:55;;-1:-1:-1;14973:55:0;-1:-1:-1;15038:18:0;15059:15;14973:55;;15059:15;:::i;:::-;15038:36;;15084:31;15104:10;15084:19;:31::i;:::-;15125;15145:10;15125:19;:31::i;701:205:25:-;840:58;;-1:-1:-1;;;;;20858:32:33;;840:58:25;;;20840:51:33;20907:18;;;20900:34;;;813:86:25;;833:5;;-1:-1:-1;;;863:23:25;20813:18:33;;840:58:25;;;;-1:-1:-1;;840:58:25;;;;;;;;;;;;;;-1:-1:-1;;;;;840:58:25;-1:-1:-1;;;;;;840:58:25;;;;;;;;;;813:19;:86::i;15987:743:0:-;16079:13;16095:6;:4;:6::i;:::-;:34;;-1:-1:-1;;;16095:34:0;;16123:4;16095:34;;;674:51:33;-1:-1:-1;;;;;16095:19:0;;;;;;;647:18:33;;16095:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16079:50;-1:-1:-1;16139:11:0;16164:10;;16160:333;;16190:40;16233:6;:4;:6::i;:::-;:41;;-1:-1:-1;;;16233:41:0;;21117:4:33;21105:17;;16233:41:0;;;21087:36:33;-1:-1:-1;;;;;16233:27:0;;;;;;;21060:18:33;;16233:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;16233:41:0;;;;;;;;;;;;:::i;:::-;16294:13;16288:19;;;-1:-1:-1;16160:333:0;;-1:-1:-1;16160:333:0;;16463:4;;16364:118;;-1:-1:-1;;;16364:118:0;;-1:-1:-1;;;;;16463:4:0;;;16364:118;;;674:51:33;1315:42:0;;16364:73;;647:18:33;;16364:118:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;16338:144:0;;-1:-1:-1;;;;;;;;;16160:333:0;390:6:1;16525:21:0;2253:4;16525:3;:21;:::i;:::-;16524:41;;;;:::i;:::-;16510:10;:55;;16502:83;;;;-1:-1:-1;;;16502:83:0;;23684:2:33;16502:83:0;;;23666:21:33;23723:2;23703:18;;;23696:30;-1:-1:-1;;;23742:18:33;;;23735:45;23797:18;;16502:83:0;23482:339:33;16502:83:0;16620:10;16603:13;:27;;16595:64;;;;-1:-1:-1;;;16595:64:0;;24028:2:33;16595:64:0;;;24010:21:33;24067:2;24047:18;;;24040:30;24106:26;24086:18;;;24079:54;24150:18;;16595:64:0;23826:348:33;16595:64:0;-1:-1:-1;;16669:6:0;:19;16698:9;:25;15987:743::o;1863:115:23:-;1168:7;;;;1411:9;1403:38;;;;-1:-1:-1;;;1403:38:23;;;;;;;:::i;:::-;1922:7:::1;:14:::0;;-1:-1:-1;;1922:14:23::1;1932:4;1922:14;::::0;;1951:20:::1;1958:12;719:10:27::0;;640:96;8870:156:32;8944:7;8994:22;8998:3;9010:5;8994:3;:22::i;9182:289:0:-;9238:4;;:29;;-1:-1:-1;;;9238:29:0;;9261:4;9238:29;;;674:51:33;9220:15:0;;-1:-1:-1;;;;;9238:4:0;;:14;;647:18:33;;9238:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9220:47;-1:-1:-1;9281:12:0;;9277:188;;9309:52;9344:6;:4;:6::i;:::-;9309:4;;-1:-1:-1;;;;;9309:4:0;;9353:7;9309:26;:52::i;:::-;9375:6;:4;:6::i;:::-;9397:4;;9375:79;;-1:-1:-1;;;9375:79:0;;-1:-1:-1;;;;;9397:4:0;;;9375:79;;;24541:34:33;24591:18;;;24584:34;;;9421:4:0;24634:18:33;;;24627:43;9397:4:0;24686:18:33;;;24679:47;9375:13:0;;;;;24475:19:33;;9375:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9210:261;9182:289::o;8539:532::-;8613:14;8629;8647:20;:18;:20::i;:::-;8612:55;;;;8677:23;8703:6;;8713:1;8703:11;;:53;;8755:1;8703:53;;;8746:6;;8718:24;390:6:1;8718::0;:24;:::i;:::-;8717:35;;;;:::i;:::-;8677:79;;8823:15;8814:6;:24;8806:61;;;;-1:-1:-1;;;8806:61:0;;24939:2:33;8806:61:0;;;24921:21:33;24978:2;24958:18;;;24951:30;25017:26;24997:18;;;24990:54;25061:18;;8806:61:0;24737:348:33;8806:61:0;8878:20;8901:24;8910:15;8901:6;:24;:::i;:::-;8878:47;;8953:39;8962:15;8979:12;8953:8;:39::i;:::-;8935:57;;9002:6;:4;:6::i;:::-;9026:4;;9002:62;;-1:-1:-1;;;9002:62:0;;-1:-1:-1;;;;;9026:4:0;;;9002:62;;;25330:34:33;25380:18;;;25373:34;;;9058:4:0;25423:18:33;;;25416:43;9002:15:0;;;;;25265:18:33;;9002:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;8413:115:32:-;8476:7;8502:19;8510:3;4028:18;;3946:107;5335:368:0;5383:9;:7;:9::i;:::-;5404:14;5420;5438:20;:18;:20::i;:::-;5403:55;;;;5468:18;5489:6;5499:1;5489:11;;:53;;5541:1;5489:53;;;5532:6;5504:24;390:6:1;5504::0;:24;:::i;:::-;5503:35;;;;:::i;:::-;5468:74;;5570:6;;5557:10;:19;5553:144;;;5592:22;5612:1;5592:19;:22::i;5553:144::-;5648:9;;5635:10;:22;5631:66;;;5673:13;:11;:13::i;6613:631::-;6679:14;6695;6713:20;:18;:20::i;:::-;6678:55;;-1:-1:-1;6678:55:0;-1:-1:-1;6743:18:0;6764:15;6678:55;;6764:15;:::i;:::-;6743:36;;6808:10;6797:7;:21;;6789:48;;;;-1:-1:-1;;;6789:48:0;;25672:2:33;6789:48:0;;;25654:21:33;25711:2;25691:18;;;25684:30;-1:-1:-1;;;25730:18:33;;;25723:44;25784:18;;6789:48:0;25470:338:33;6789:48:0;6896:21;6920:20;6933:7;6920:10;:20;:::i;:::-;6896:44;;6950:17;7019:9;;390:6:1;7001:27:0;;;;:::i;:::-;6987:9;;6971:25;;:13;:25;:::i;:::-;6970:59;;;;:::i;:::-;6950:79;-1:-1:-1;7039:23:0;7065:18;6950:79;7065:6;:18;:::i;:::-;7039:44;;7153:6;:4;:6::i;:::-;7185:4;;7153:84;;-1:-1:-1;;;7153:84:0;;-1:-1:-1;;;;;7185:4:0;;;7153:84;;;26015:51:33;26082:18;;;26075:34;;;2203:1:0;26125:18:33;;;26118:34;7153:23:0;;;;;25988:18:33;;7153:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6668:576;;;;;;6613:631;:::o;1697:404:32:-;1760:4;3834:19;;;:12;;;:19;;;;;;1776:319;;-1:-1:-1;1818:23:32;;;;;;;;:11;:23;;;;;;;;;;;;;1998:18;;1976:19;;;:12;;;:19;;;;;;:40;;;;2030:11;;1776:319;-1:-1:-1;2079:5:32;2072:12;;7830:529:0;7932:36;7952:15;7932:19;:36::i;:::-;7997:4;;:29;;-1:-1:-1;;;7997:29:0;;8020:4;7997:29;;;674:51:33;7979:15:0;;-1:-1:-1;;;;;7997:4:0;;:14;;647:18:33;;7997:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7979:47;;8050:15;8040:7;:25;8036:246;;;390:6:1;8155:25:0;;390:6:1;8137:43:0;;;;:::i;:::-;8118:63;;:15;:63;:::i;:::-;8117:83;;;;:::i;:::-;8106:7;:94;;8081:190;;;;-1:-1:-1;;;8081:190:0;;26365:2:33;8081:190:0;;;26347:21:33;26404:2;26384:18;;;26377:30;26443:34;26423:18;;;26416:62;-1:-1:-1;;;26494:18:33;;;26487:35;26539:19;;8081:190:0;26163:401:33;8081:190:0;8310:5;;8292:60;;-1:-1:-1;;;;;8310:5:0;8317:34;8326:7;8335:15;8317:8;:34::i;:::-;8292:4;;-1:-1:-1;;;;;8292:4:0;;:60;:17;:60::i;7348:361::-;7391:14;7407;7425:20;:18;:20::i;:::-;7390:55;;-1:-1:-1;7390:55:0;-1:-1:-1;7455:18:0;7476:15;7390:55;;7476:15;:::i;:::-;7455:36;;7501:21;7571:9;;390:6:1;7553:27:0;;;;:::i;:::-;7539:9;;7526:22;;:10;:22;:::i;:::-;7525:56;;;;:::i;:::-;7501:80;;7621:17;;7612:6;:26;;;;:::i;:::-;7596:13;:42;7592:111;;;7654:38;7669:22;7685:6;7669:13;:22;:::i;:::-;7654:14;:38::i;1588:441:28:-;1663:13;1688:19;1720:10;1724:6;1720:1;:10;:::i;:::-;:14;;1733:1;1720:14;:::i;:::-;1710:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1710:25:28;;1688:47;;-1:-1:-1;;;1745:6:28;1752:1;1745:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1745:15:28;;;;;;;;;-1:-1:-1;;;1770:6:28;1777:1;1770:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1770:15:28;;;;;;;;-1:-1:-1;1800:9:28;1812:10;1816:6;1812:1;:10;:::i;:::-;:14;;1825:1;1812:14;:::i;:::-;1800:26;;1795:132;1832:1;1828;:5;1795:132;;;-1:-1:-1;;;1879:5:28;1887:3;1879:11;1866:25;;;;;;;:::i;:::-;;;;1854:6;1861:1;1854:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;1854:37:28;;;;;;;;-1:-1:-1;1915:1:28;1905:11;;;;;1835:3;;;:::i;:::-;;;1795:132;;;-1:-1:-1;1944:10:28;;1936:55;;;;-1:-1:-1;;;1936:55:28;;26771:2:33;1936:55:28;;;26753:21:33;;;26790:18;;;26783:30;26849:34;26829:18;;;26822:62;26901:18;;1936:55:28;26569:356:33;7180:234:19;7263:22;7271:4;7277:7;7263;:22::i;:::-;7259:149;;;7333:5;7301:12;;;;;;;;;;;-1:-1:-1;;;;;7301:29:19;;;;;;;;;;:37;;-1:-1:-1;;7301:37:19;;;7357:40;719:10:27;;7301:12:19;;7357:40;;7333:5;7357:40;7180:234;;:::o;7930:156:32:-;8003:4;8026:53;8034:3;-1:-1:-1;;;;;8054:23:32;;8026:7;:53::i;9973:952:0:-;10109:8;;10071:35;;-1:-1:-1;;;10071:35:0;;10100:4;10071:35;;;674:51:33;10025:17:0;;;;390:6:1;;10109:8:0;-1:-1:-1;;;;;2687:42:0;10071:20;;647:18:33;;10071:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;;;:::i;:::-;10070:66;;;;:::i;:::-;10054:82;-1:-1:-1;10150:10:0;10146:49;;10183:1;10176:8;;;9973:952;:::o;10146:49::-;10265:29;;-1:-1:-1;;;10265:29:0;;10288:4;10265:29;;;674:51:33;2766:42:0;;10205:11;;2766:42;;10265:14;;647:18:33;;10265:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10241:53;;10304:26;10310:12;10304:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10304:26:0;;;;;;;;;;;;;;;;;;;;;10324:5;10304;:26::i;:::-;10358:29;;-1:-1:-1;;;10358:29:0;;10381:4;10358:29;;;674:51:33;10340:15:0;;10390:13;;-1:-1:-1;;;;;10358:14:0;;;;;647:18:33;;10358:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:45;;;;:::i;:::-;10340:63;-1:-1:-1;10418:12:0;;10414:505;;390:6:1;10469:7:0;;10459;:17;;;;:::i;:::-;10458:37;;;;:::i;:::-;10446:49;;10509:26;390:6:1;10549:11:0;;10539:7;:21;;;;:::i;:::-;10538:41;;;;:::i;:::-;10509:70;;10593:23;390:6:1;10641:13:0;;10620:18;:34;;;;:::i;:::-;10619:54;;;;:::i;:::-;10593:80;-1:-1:-1;10687:37:0;10593:80;10687:37;;:::i;:::-;;-1:-1:-1;10739:40:0;-1:-1:-1;;;;;10739:17:0;;10757:10;10769:9;10739:17;:40::i;:::-;10811:8;;10793:47;;-1:-1:-1;;;;;10793:17:0;;;;10811:8;10821:18;10793:17;:47::i;:::-;10872:18;;10854:54;;-1:-1:-1;;;;;10854:17:0;;;;10872:18;10892:15;10854:17;:54::i;:::-;10432:487;;10414:505;10044:881;;;;9973:952;:::o;11132:181::-;11195:35;;-1:-1:-1;;;11195:35:0;;11224:4;11195:35;;;674:51:33;11179:13:0;;-1:-1:-1;;;;;2687:42:0;11195:20;;647:18:33;;11195:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11179:51;-1:-1:-1;11244:10:0;;11240:67;;11270:26;11276:12;11270:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11270:26:0;;;;;;;;;;;;;;;;;;;;;11290:5;11270;:26::i;3207:706:25:-;3626:23;3652:69;3680:4;3652:69;;;;;;;;;;;;;;;;;3660:5;-1:-1:-1;;;;;3652:27:25;;;:69;;;;;:::i;:::-;3735:17;;3626:95;;-1:-1:-1;3735:21:25;3731:176;;3830:10;3819:30;;;;;;;;;;;;:::i;:::-;3811:85;;;;-1:-1:-1;;;3811:85:25;;27339:2:33;3811:85:25;;;27321:21:33;27378:2;27358:18;;;27351:30;27417:34;27397:18;;;27390:62;-1:-1:-1;;;27468:18:33;;;27461:40;27518:19;;3811:85:25;27137:406:33;4395:118:32;4462:7;4488:3;:11;;4500:5;4488:18;;;;;;;;:::i;:::-;;;;;;;;;4481:25;;4395:118;;;;:::o;2022:310:25:-;2171:39;;-1:-1:-1;;;2171:39:25;;2195:4;2171:39;;;11430:34:33;-1:-1:-1;;;;;11500:15:33;;;11480:18;;;11473:43;2148:20:25;;2213:5;;2171:15;;;;;11365:18:33;;2171:39:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;;;:::i;:::-;2255:69;;-1:-1:-1;;;;;20858:32:33;;2255:69:25;;;20840:51:33;20907:18;;;20900:34;;;2148:70:25;;-1:-1:-1;2228:97:25;;2248:5;;-1:-1:-1;;;2278:22:25;20813:18:33;;2255:69:25;20666:274:33;446:104:31;504:7;534:1;530;:5;:13;;542:1;530:13;;;-1:-1:-1;538:1:31;;446:104;-1:-1:-1;446:104:31:o;12161:657:0:-;12229:12;12221:44;;;;-1:-1:-1;;;12221:44:0;;27750:2:33;12221:44:0;;;27732:21:33;27789:2;27769:18;;;27762:30;-1:-1:-1;;;27808:18:33;;;27801:49;27867:18;;12221:44:0;27548:343:33;12221:44:0;12333:16;;;12347:1;12333:16;;;;;;;;;12307:23;;12333:16;;;;;;;;;-1:-1:-1;;12379:4:0;;12359:9;;;;-1:-1:-1;;;;;;12379:4:0;;12359:9;;-1:-1:-1;12379:4:0;;12359:9;;;;:::i;:::-;-1:-1:-1;;;;;12359:25:0;;;;:9;;;;;;;;;;;:25;12454:16;;;12468:1;12454:16;;;;;;;;;12427:24;;12454:16;;;;;;;;;;;;-1:-1:-1;12454:16:0;12427:43;;12493:7;12480;12488:1;12480:10;;;;;;;;:::i;:::-;;;;;;;;;;:20;12585:16;;;12599:1;12585:16;;;;;;;;;12560:22;;12585:16;;;;;;;;;;;;-1:-1:-1;12585:16:0;12560:41;;2203:1;12611:5;12617:1;12611:8;;;;;;;;:::i;:::-;;;;;;;;;;:38;2059:1;12660:15;:40;12710:6;:4;:6::i;:::-;-1:-1:-1;;;;;12710:16:0;;12735:4;12742:6;12750:7;12759:5;12774:4;2141:1;12710:101;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2269:1388:32;2335:4;2472:19;;;:12;;;:19;;;;;;2506:15;;2502:1149;;2875:21;2899:14;2912:1;2899:10;:14;:::i;:::-;2947:18;;2875:38;;-1:-1:-1;2927:17:32;;2947:22;;2968:1;;2947:22;:::i;:::-;2927:42;;3001:13;2988:9;:26;2984:398;;3034:17;3054:3;:11;;3066:9;3054:22;;;;;;;;:::i;:::-;;;;;;;;;3034:42;;3205:9;3176:3;:11;;3188:13;3176:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3288:23;;;:12;;;:23;;;;;:36;;;2984:398;3460:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3552:3;:12;;:19;3565:5;3552:19;;;;;;;;;;;3545:26;;;3593:4;3586:11;;;;;;;2502:1149;3635:5;3628:12;;;;;11390:765:0;11580:12;;1124:42;;11465:18;;11580:16;;11595:1;;11580:16;:::i;:::-;11556:41;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;11556:41:0;;-1:-1:-1;;11556:41:0;;;;;;;;;;;-1:-1:-1;11520:77:0;-1:-1:-1;11634:7:0;11608:23;;;11699:287;11723:6;:13;11719:1;:17;11699:287;;;11779:6;-1:-1:-1;;;;;11779:19:0;;11799:15;11816:5;11822:1;11816:8;;;;;;;;:::i;:::-;;;;;;;11826:5;11832:1;11836;11832:5;;;;:::i;:::-;11826:12;;;;;;;;:::i;:::-;;;;;;;11779:60;;;;;;;;;;;;;;;;30204:25:33;;;-1:-1:-1;;;;;30303:15:33;;;30298:2;30283:18;;30276:43;30355:15;30350:2;30335:18;;30328:43;30192:2;30177:18;;30002:375;11779:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11757:82;;;;;;;;11865:72;;;;;;;;11890:5;11896:1;11890:8;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;11865:72:0;;;;;11904:5;11910:1;11914;11910:5;;;;:::i;:::-;11904:12;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;11865:72:0;;;;;11926:9;11865:72;;;;;11853:6;11860:1;11853:9;;;;;;;;:::i;:::-;;;;;;:84;;;;11969:6;11951:24;;11738:3;;;;;:::i;:::-;;;;11699:287;;;;11995:60;1124:42;12047:7;12002:5;12008:1;12002:8;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;11995:38:0;;;:60;;;;;:::i;:::-;12065:83;;-1:-1:-1;;;12065:83:0;;-1:-1:-1;;;;;12065:31:0;;;;;:83;;12097:7;;12106:1;;12109:6;;12125:4;;12132:15;;12065:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12065:83:0;;;;;;;;;;;;:::i;3514:223:26:-;3647:12;3678:52;3700:6;3708:4;3714:1;3717:12;3647;1087:20;;4881:60;;;;-1:-1:-1;;;4881:60:26;;32857:2:33;4881:60:26;;;32839:21:33;32896:2;32876:18;;;32869:30;32935:31;32915:18;;;32908:59;32984:18;;4881:60:26;32655:353:33;4881:60:26;4953:12;4967:23;4994:6;-1:-1:-1;;;;;4994:11:26;5013:5;5020:4;4994:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4952:73;;;;5042:51;5059:7;5068:10;5080:12;5042:16;:51::i;:::-;5035:58;4601:499;-1:-1:-1;;;;;;;4601:499:26:o;7214:692::-;7360:12;7388:7;7384:516;;;-1:-1:-1;7418:10:26;7411:17;;7384:516;7529:17;;:21;7525:365;;7723:10;7717:17;7783:15;7770:10;7766:2;7762:19;7755:44;7525:365;7862:12;7855:20;;-1:-1:-1;;;7855:20:26;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:286:33;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:33;;209:43;;199:71;;266:1;263;256:12;736:180;795:6;848:2;836:9;827:7;823:23;819:32;816:52;;;864:1;861;854:12;816:52;-1:-1:-1;887:23:33;;736:180;-1:-1:-1;736:180:33:o;1643:316::-;1720:6;1728;1736;1789:2;1777:9;1768:7;1764:23;1760:32;1757:52;;;1805:1;1802;1795:12;1757:52;-1:-1:-1;;1828:23:33;;;1898:2;1883:18;;1870:32;;-1:-1:-1;1949:2:33;1934:18;;;1921:32;;1643:316;-1:-1:-1;1643:316:33:o;2555:131::-;-1:-1:-1;;;;;2630:31:33;;2620:42;;2610:70;;2676:1;2673;2666:12;2691:315;2759:6;2767;2820:2;2808:9;2799:7;2795:23;2791:32;2788:52;;;2836:1;2833;2826:12;2788:52;2872:9;2859:23;2849:33;;2932:2;2921:9;2917:18;2904:32;2945:31;2970:5;2945:31;:::i;:::-;2995:5;2985:15;;;2691:315;;;;;:::o;3011:248::-;3079:6;3087;3140:2;3128:9;3119:7;3115:23;3111:32;3108:52;;;3156:1;3153;3146:12;3108:52;-1:-1:-1;;3179:23:33;;;3249:2;3234:18;;;3221:32;;-1:-1:-1;3011:248:33:o;3739:247::-;3798:6;3851:2;3839:9;3830:7;3826:23;3822:32;3819:52;;;3867:1;3864;3857:12;3819:52;3906:9;3893:23;3925:31;3950:5;3925:31;:::i;4424:367::-;4487:8;4497:6;4551:3;4544:4;4536:6;4532:17;4528:27;4518:55;;4569:1;4566;4559:12;4518:55;-1:-1:-1;4592:20:33;;4635:18;4624:30;;4621:50;;;4667:1;4664;4657:12;4621:50;4704:4;4696:6;4692:17;4680:29;;4764:3;4757:4;4747:6;4744:1;4740:14;4732:6;4728:27;4724:38;4721:47;4718:67;;;4781:1;4778;4771:12;4718:67;4424:367;;;;;:::o;4796:1673::-;4983:6;4991;4999;5007;5015;5023;5031;5039;5047;5100:3;5088:9;5079:7;5075:23;5071:33;5068:53;;;5117:1;5114;5107:12;5068:53;5157:9;5144:23;5186:18;5227:2;5219:6;5216:14;5213:34;;;5243:1;5240;5233:12;5213:34;5282:70;5344:7;5335:6;5324:9;5320:22;5282:70;:::i;:::-;5371:8;;-1:-1:-1;5256:96:33;-1:-1:-1;5459:2:33;5444:18;;5431:32;;-1:-1:-1;5475:16:33;;;5472:36;;;5504:1;5501;5494:12;5472:36;5543:72;5607:7;5596:8;5585:9;5581:24;5543:72;:::i;:::-;5634:8;;-1:-1:-1;5517:98:33;-1:-1:-1;5722:2:33;5707:18;;5694:32;;-1:-1:-1;5738:16:33;;;5735:36;;;5767:1;5764;5757:12;5735:36;5806:72;5870:7;5859:8;5848:9;5844:24;5806:72;:::i;:::-;5897:8;;-1:-1:-1;5780:98:33;-1:-1:-1;5982:2:33;5967:18;;5954:32;;-1:-1:-1;5995:31:33;5954:32;5995:31;:::i;:::-;6045:5;;-1:-1:-1;6103:3:33;6088:19;;6075:33;;6120:16;;;6117:36;;;6149:1;6146;6139:12;6117:36;6187:8;6176:9;6172:24;6162:34;;6234:7;6227:4;6223:2;6219:13;6215:27;6205:55;;6256:1;6253;6246:12;6205:55;6296:2;6283:16;6322:2;6314:6;6311:14;6308:34;;;6338:1;6335;6328:12;6308:34;6383:7;6378:2;6369:6;6365:2;6361:15;6357:24;6354:37;6351:57;;;6404:1;6401;6394:12;6351:57;6435:2;6431;6427:11;6417:21;;6457:6;6447:16;;;;;4796:1673;;;;;;;;;;;:::o;6474:127::-;6535:10;6530:3;6526:20;6523:1;6516:31;6566:4;6563:1;6556:15;6590:4;6587:1;6580:15;6606:253;6678:2;6672:9;6720:4;6708:17;;6755:18;6740:34;;6776:22;;;6737:62;6734:88;;;6802:18;;:::i;:::-;6838:2;6831:22;6606:253;:::o;6864:275::-;6935:2;6929:9;7000:2;6981:13;;-1:-1:-1;;6977:27:33;6965:40;;7035:18;7020:34;;7056:22;;;7017:62;7014:88;;;7082:18;;:::i;:::-;7118:2;7111:22;6864:275;;-1:-1:-1;6864:275:33:o;7144:183::-;7204:4;7237:18;7229:6;7226:30;7223:56;;;7259:18;;:::i;:::-;-1:-1:-1;7304:1:33;7300:14;7316:4;7296:25;;7144:183::o;7332:966::-;7416:6;7447:2;7490;7478:9;7469:7;7465:23;7461:32;7458:52;;;7506:1;7503;7496:12;7458:52;7546:9;7533:23;7579:18;7571:6;7568:30;7565:50;;;7611:1;7608;7601:12;7565:50;7634:22;;7687:4;7679:13;;7675:27;-1:-1:-1;7665:55:33;;7716:1;7713;7706:12;7665:55;7752:2;7739:16;7775:60;7791:43;7831:2;7791:43;:::i;:::-;7775:60;:::i;:::-;7869:15;;;7951:1;7947:10;;;;7939:19;;7935:28;;;7900:12;;;;7975:19;;;7972:39;;;8007:1;8004;7997:12;7972:39;8031:11;;;;8051:217;8067:6;8062:3;8059:15;8051:217;;;8147:3;8134:17;8164:31;8189:5;8164:31;:::i;:::-;8208:18;;8084:12;;;;8246;;;;8051:217;;8303:437;8389:6;8397;8450:2;8438:9;8429:7;8425:23;8421:32;8418:52;;;8466:1;8463;8456:12;8418:52;8506:9;8493:23;8539:18;8531:6;8528:30;8525:50;;;8571:1;8568;8561:12;8525:50;8610:70;8672:7;8663:6;8652:9;8648:22;8610:70;:::i;:::-;8699:8;;8584:96;;-1:-1:-1;8303:437:33;-1:-1:-1;;;;8303:437:33:o;8929:127::-;8990:10;8985:3;8981:20;8978:1;8971:31;9021:4;9018:1;9011:15;9045:4;9042:1;9035:15;9061:128;9101:3;9132:1;9128:6;9125:1;9122:13;9119:39;;;9138:18;;:::i;:::-;-1:-1:-1;9174:9:33;;9061:128::o;10422:340::-;10624:2;10606:21;;;10663:2;10643:18;;;10636:30;-1:-1:-1;;;10697:2:33;10682:18;;10675:46;10753:2;10738:18;;10422:340::o;10767:125::-;10807:4;10835:1;10832;10829:8;10826:34;;;10840:18;;:::i;:::-;-1:-1:-1;10877:9:33;;10767:125::o;10897:127::-;10958:10;10953:3;10949:20;10946:1;10939:31;10989:4;10986:1;10979:15;11013:4;11010:1;11003:15;11029:184;11099:6;11152:2;11140:9;11131:7;11127:23;11123:32;11120:52;;;11168:1;11165;11158:12;11120:52;-1:-1:-1;11191:16:33;;11029:184;-1:-1:-1;11029:184:33:o;11527:164::-;11603:13;;11652;;11645:21;11635:32;;11625:60;;11681:1;11678;11671:12;11625:60;11527:164;;;:::o;11696:794::-;11834:6;11842;11850;11858;11866;11874;11882;11890;11898;11951:3;11939:9;11930:7;11926:23;11922:33;11919:53;;;11968:1;11965;11958:12;11919:53;11997:9;11991:16;11981:26;;12047:2;12036:9;12032:18;12026:25;12016:35;;12091:2;12080:9;12076:18;12070:25;12060:35;;12135:2;12124:9;12120:18;12114:25;12104:35;;12179:3;12168:9;12164:19;12158:26;12148:36;;12224:3;12213:9;12209:19;12203:26;12193:36;;12269:3;12258:9;12254:19;12248:26;12238:36;;12317:3;12306:9;12302:19;12296:26;12362:12;12355:5;12351:24;12344:5;12341:35;12331:63;;12390:1;12387;12380:12;12331:63;12413:5;-1:-1:-1;12437:47:33;12479:3;12464:19;;12437:47;:::i;:::-;12427:57;;11696:794;;;;;;;;;;;:::o;12495:251::-;12565:6;12618:2;12606:9;12597:7;12593:23;12589:32;12586:52;;;12634:1;12631;12624:12;12586:52;12666:9;12660:16;12685:31;12710:5;12685:31;:::i;12751:168::-;12791:7;12857:1;12853;12849:6;12845:14;12842:1;12839:21;12834:1;12827:9;12820:17;12816:45;12813:71;;;12864:18;;:::i;:::-;-1:-1:-1;12904:9:33;;12751:168::o;12924:127::-;12985:10;12980:3;12976:20;12973:1;12966:31;13016:4;13013:1;13006:15;13040:4;13037:1;13030:15;13056:120;13096:1;13122;13112:35;;13127:18;;:::i;:::-;-1:-1:-1;13161:9:33;;13056:120::o;13181:136::-;13216:3;-1:-1:-1;;;13237:22:33;;13234:48;;;13262:18;;:::i;:::-;-1:-1:-1;13302:1:33;13298:13;;13181:136::o;15062:265::-;15101:3;15129:9;;;15154:10;;-1:-1:-1;;;;;15173:27:33;;;15166:35;;15150:52;15147:78;;;15205:18;;:::i;:::-;-1:-1:-1;;;15252:19:33;;;15245:27;;15237:36;;15234:62;;;15276:18;;:::i;:::-;-1:-1:-1;;15312:9:33;;15062:265::o;15332:147::-;15370:3;-1:-1:-1;;;;;15391:30:33;;15388:56;;;15424:18;;:::i;:::-;-1:-1:-1;15471:1:33;15460:13;;15332:147::o;15484:136::-;15523:3;15551:5;15541:39;;15560:18;;:::i;:::-;-1:-1:-1;;;15596:18:33;;15484:136::o;15625:193::-;15664:1;15690;15680:35;;15695:18;;:::i;:::-;-1:-1:-1;;;15731:18:33;;-1:-1:-1;;15751:13:33;;15727:38;15724:64;;;15768:18;;:::i;:::-;-1:-1:-1;15802:10:33;;15625:193::o;16171:135::-;16210:3;-1:-1:-1;;16231:17:33;;16228:43;;;16251:18;;:::i;16311:258::-;16383:1;16393:113;16407:6;16404:1;16401:13;16393:113;;;16483:11;;;16477:18;16464:11;;;16457:39;16429:2;16422:10;16393:113;;;16524:6;16521:1;16518:13;16515:48;;;-1:-1:-1;;16559:1:33;16541:16;;16534:27;16311:258::o;16574:786::-;16985:25;16980:3;16973:38;16955:3;17040:6;17034:13;17056:62;17111:6;17106:2;17101:3;17097:12;17090:4;17082:6;17078:17;17056:62;:::i;:::-;-1:-1:-1;;;17177:2:33;17137:16;;;17169:11;;;17162:40;17227:13;;17249:63;17227:13;17298:2;17290:11;;17283:4;17271:17;;17249:63;:::i;:::-;17332:17;17351:2;17328:26;;16574:786;-1:-1:-1;;;;16574:786:33:o;17365:383::-;17514:2;17503:9;17496:21;17477:4;17546:6;17540:13;17589:6;17584:2;17573:9;17569:18;17562:34;17605:66;17664:6;17659:2;17648:9;17644:18;17639:2;17631:6;17627:15;17605:66;:::i;:::-;17732:2;17711:15;-1:-1:-1;;17707:29:33;17692:45;;;;17739:2;17688:54;;17365:383;-1:-1:-1;;17365:383:33:o;18102:681::-;18270:2;18322:21;;;18392:13;;18295:18;;;18414:22;;;18241:4;18479:17;;;18519:16;;;18241:4;;18270:2;18467;18452:18;;;18241:4;18563:194;18577:6;18574:1;18571:13;18563:194;;;18642:13;;-1:-1:-1;;;;;18638:39:33;18626:52;;18674:1;18733:14;;;;18698:12;;;;18592:9;18563:194;;;-1:-1:-1;18774:3:33;;18102:681;-1:-1:-1;;;;;;18102:681:33:o;18788:659::-;18853:5;18906:3;18899:4;18891:6;18887:17;18883:27;18873:55;;18924:1;18921;18914:12;18873:55;18953:6;18947:13;18979:4;19003:60;19019:43;19059:2;19019:43;:::i;19003:60::-;19097:15;;;19183:1;19179:10;;;;19167:23;;19163:32;;;19128:12;;;;19207:15;;;19204:35;;;19235:1;19232;19225:12;19204:35;19271:2;19263:6;19259:15;19283:135;19299:6;19294:3;19291:15;19283:135;;;19365:10;;19353:23;;19396:12;;;;19316;;19283:135;;;-1:-1:-1;19436:5:33;18788:659;-1:-1:-1;;;;;;18788:659:33:o;19452:1209::-;19581:6;19589;19642:2;19630:9;19621:7;19617:23;19613:32;19610:52;;;19658:1;19655;19648:12;19610:52;19691:9;19685:16;19720:18;19761:2;19753:6;19750:14;19747:34;;;19777:1;19774;19767:12;19747:34;19815:6;19804:9;19800:22;19790:32;;19860:7;19853:4;19849:2;19845:13;19841:27;19831:55;;19882:1;19879;19872:12;19831:55;19911:2;19905:9;19933:4;19957:60;19973:43;20013:2;19973:43;:::i;19957:60::-;20051:15;;;20133:1;20129:10;;;;20121:19;;20117:28;;;20082:12;;;;20157:19;;;20154:39;;;20189:1;20186;20179:12;20154:39;20213:11;;;;20233:210;20249:6;20244:3;20241:15;20233:210;;;20322:3;20316:10;20339:31;20364:5;20339:31;:::i;:::-;20383:18;;20266:12;;;;20421;;;;20233:210;;;20498:18;;;20492:25;20462:5;;-1:-1:-1;20492:25:33;;-1:-1:-1;;;20529:16:33;;;20526:36;;;20558:1;20555;20548:12;20526:36;;20581:74;20647:7;20636:8;20625:9;20621:24;20581:74;:::i;:::-;20571:84;;;19452:1209;;;;;:::o;21134:163::-;21212:13;;21265:6;21254:18;;21244:29;;21234:57;;21287:1;21284;21277:12;21302:1340;21403:6;21434:2;21477;21465:9;21456:7;21452:23;21448:32;21445:52;;;21493:1;21490;21483:12;21445:52;21526:9;21520:16;21555:18;21596:2;21588:6;21585:14;21582:34;;;21612:1;21609;21602:12;21582:34;21635:22;;;;21691:4;21673:16;;;21669:27;21666:47;;;21709:1;21706;21699:12;21666:47;21735:22;;:::i;:::-;21780:32;21809:2;21780:32;:::i;:::-;21773:5;21766:47;21845:41;21882:2;21878;21874:11;21845:41;:::i;:::-;21840:2;21833:5;21829:14;21822:65;21919:41;21956:2;21952;21948:11;21919:41;:::i;:::-;21914:2;21907:5;21903:14;21896:65;21999:2;21995;21991:11;21985:18;22012:33;22037:7;22012:33;:::i;:::-;22072:2;22061:14;;22054:31;22124:3;22116:12;;22110:19;22141:16;;;22138:36;;;22170:1;22167;22160:12;22138:36;22201:8;22197:2;22193:17;22183:27;;;22248:7;22241:4;22237:2;22233:13;22229:27;22219:55;;22270:1;22267;22260:12;22219:55;22299:2;22293:9;22321:2;22317;22314:10;22311:36;;;22327:18;;:::i;:::-;22369:53;22412:2;22393:13;;-1:-1:-1;;22389:27:33;22385:36;;22369:53;:::i;:::-;22356:66;;22445:2;22438:5;22431:17;22485:7;22480:2;22475;22471;22467:11;22463:20;22460:33;22457:53;;;22506:1;22503;22496:12;22457:53;22519:54;22570:2;22565;22558:5;22554:14;22549:2;22545;22541:11;22519:54;:::i;:::-;-1:-1:-1;22600:3:33;22589:15;;22582:30;;;;22593:5;21302:1340;-1:-1:-1;;;;;21302:1340:33:o;22647:830::-;22783:6;22791;22799;22807;22815;22823;22831;22839;22847;22855;22908:3;22896:9;22887:7;22883:23;22879:33;22876:53;;;22925:1;22922;22915:12;22876:53;22954:9;22948:16;22938:26;;23004:2;22993:9;22989:18;22983:25;22973:35;;23048:2;23037:9;23033:18;23027:25;23017:35;;23092:2;23081:9;23077:18;23071:25;23061:35;;23136:3;23125:9;23121:19;23115:26;23105:36;;23160:47;23202:3;23191:9;23187:19;23160:47;:::i;:::-;23150:57;;23226:47;23268:3;23257:9;23253:19;23226:47;:::i;:::-;23216:57;;23292:47;23334:3;23323:9;23319:19;23292:47;:::i;:::-;23282:57;;23358:47;23400:3;23389:9;23385:19;23358:47;:::i;:::-;23348:57;;23424:47;23466:3;23455:9;23451:19;23424:47;:::i;:::-;23414:57;;22647:830;;;;;;;;;;;;;:::o;26930:202::-;26997:6;27050:2;27038:9;27029:7;27025:23;27021:32;27018:52;;;27066:1;27063;27056:12;27018:52;27089:37;27116:9;27089:37;:::i;27896:435::-;27949:3;27987:5;27981:12;28014:6;28009:3;28002:19;28040:4;28069:2;28064:3;28060:12;28053:19;;28106:2;28099:5;28095:14;28127:1;28137:169;28151:6;28148:1;28145:13;28137:169;;;28212:13;;28200:26;;28246:12;;;;28281:15;;;;28173:1;28166:9;28137:169;;;-1:-1:-1;28322:3:33;;27896:435;-1:-1:-1;;;;;27896:435:33:o;28336:1529::-;-1:-1:-1;;;;;28933:15:33;;;28915:34;;28864:3;28968:2;28986:18;;;28979:31;;;29059:13;;28849:19;;;29081:22;;;28816:4;;29161:15;;;;28887:19;;28968:2;29134:3;29119:19;;;28816:4;29204:178;29218:6;29215:1;29212:13;29204:178;;;29283:13;;29279:22;;29267:35;;29357:15;;;;29322:12;;;;29240:1;29233:9;29204:178;;;29208:3;;29427:9;29422:3;29418:19;29413:2;29402:9;29398:18;29391:47;29461:41;29498:3;29490:6;29461:41;:::i;:::-;29447:55;;;;;29550:9;29542:6;29538:22;29533:2;29522:9;29518:18;29511:50;29584:44;29621:6;29613;29584:44;:::i;:::-;-1:-1:-1;;;;;987:31:33;;29679:3;29664:19;;975:44;29721:22;;;29715:3;29700:19;;29693:51;-1:-1:-1;9597:14:33;;24255:6;24244:18;;29854:3;29839:19;;24232:31;9644:4;9635:14;;-1:-1:-1;29813:46:33;;-1:-1:-1;24179:90:33;29870:127;29931:10;29926:3;29922:20;29919:1;29912:31;29962:4;29959:1;29952:15;29986:4;29983:1;29976:15;30382:263;30458:6;30466;30519:2;30507:9;30498:7;30494:23;30490:32;30487:52;;;30535:1;30532;30525:12;30487:52;30564:9;30558:16;30548:26;;30593:46;30635:2;30624:9;30620:18;30593:46;:::i;:::-;30583:56;;30382:263;;;;;:::o;30650:1225::-;30958:4;31006:3;30995:9;30991:19;31037:6;31026:9;31019:25;31063:2;31101:6;31096:2;31085:9;31081:18;31074:34;31127:2;31165:3;31160:2;31149:9;31145:18;31138:31;31189:6;31224;31218:13;31255:6;31247;31240:22;31293:3;31282:9;31278:19;31271:26;;31332:2;31324:6;31320:15;31306:29;;31353:1;31363:385;31377:6;31374:1;31371:13;31363:385;;;31436:13;;31520:9;;-1:-1:-1;;;;;31516:18:33;;;31504:31;;31579:11;;;31573:18;31569:27;31555:12;;;31548:49;31651:11;;31645:18;31638:26;31631:34;31617:12;;;31610:56;31723:15;;;;31695:4;31686:14;;;;31489:1;31392:9;31363:385;;;-1:-1:-1;;;;;;;987:31:33;;31819:4;31804:20;;975:44;31765:3;-1:-1:-1;31777:48:33;;-1:-1:-1;;;921:104:33;31777:48;31862:6;31856:3;31845:9;31841:19;31834:35;30650:1225;;;;;;;;:::o;31880:363::-;31975:6;32028:2;32016:9;32007:7;32003:23;31999:32;31996:52;;;32044:1;32041;32034:12;31996:52;32077:9;32071:16;32110:18;32102:6;32099:30;32096:50;;;32142:1;32139;32132:12;32096:50;32165:72;32229:7;32220:6;32209:9;32205:22;32165:72;:::i;33013:274::-;33142:3;33180:6;33174:13;33196:53;33242:6;33237:3;33230:4;33222:6;33218:17;33196:53;:::i;:::-;33265:16;;;;;33013:274;-1:-1:-1;;33013:274:33:o
Swarm Source
ipfs://981d059dfaa6c075b82a22a796b5a234884ad2a520dc2a196ffd10dfeecf69cb
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.31
Net Worth in ETH
0.000102
Token Allocations
AOPTWETH
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| OP | 100.00% | $2,991.36 | 0.00010231 | $0.306 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.