Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
AuraViewHelpersLite
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity)
/** *Submitted for verification at zkevm.polygonscan.com on 2023-11-23 */ // Sources flattened with hardhat v2.14.0 https://hardhat.org // File @openzeppelin/contracts-0.8/utils/[email protected] // 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; } } // File @openzeppelin/contracts-0.8/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts-0.8/token/ERC20/[email protected] // 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); } // File @openzeppelin/contracts-0.8/utils/[email protected] // 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); } } } } // File @openzeppelin/contracts-0.8/token/ERC20/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @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"); } } } // File @openzeppelin/contracts-0.8/security/[email protected] // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File contracts/interfaces/IAuraLocker.sol pragma solidity 0.8.11; interface IAuraLocker { function isShutdown() external view returns (bool); function lock(address _account, uint256 _amount) external; function checkpointEpoch() external; function epochCount() external view returns (uint256); function balanceAtEpochOf(uint256 _epoch, address _user) external view returns (uint256 amount); function totalSupplyAtEpoch(uint256 _epoch) external view returns (uint256 supply); function queueNewRewards(address _rewardsToken, uint256 reward) external; function getReward(address _account, bool _stake) external; function getReward(address _account) external; } // File contracts/interfaces/IRewardStaking.sol pragma solidity 0.8.11; interface IRewardStaking { function getReward(address _account, bool _claimExtras) external; function getReward(address _account) external; function getReward(address _account, address _token) external; function stakeFor(address, uint256) external; function processIdleRewards() external; } // File contracts/utils/AuraMath.sol pragma solidity 0.8.11; /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). library AuraMath { /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a - b; } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a * b; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return 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, so we distribute. return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2); } function to224(uint256 a) internal pure returns (uint224 c) { require(a <= type(uint224).max, "AuraMath: uint224 Overflow"); c = uint224(a); } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= type(uint128).max, "AuraMath: uint128 Overflow"); c = uint128(a); } function to112(uint256 a) internal pure returns (uint112 c) { require(a <= type(uint112).max, "AuraMath: uint112 Overflow"); c = uint112(a); } function to96(uint256 a) internal pure returns (uint96 c) { require(a <= type(uint96).max, "AuraMath: uint96 Overflow"); c = uint96(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= type(uint32).max, "AuraMath: uint32 Overflow"); c = uint32(a); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. library AuraMath32 { function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { c = a - b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint112. library AuraMath112 { function add(uint112 a, uint112 b) internal pure returns (uint112 c) { c = a + b; } function sub(uint112 a, uint112 b) internal pure returns (uint112 c) { c = a - b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint224. library AuraMath224 { function add(uint224 a, uint224 b) internal pure returns (uint224 c) { c = a + b; } } // File contracts/core/AuraLocker.sol pragma solidity 0.8.11; /** * @title AuraLocker * @author ConvexFinance * @notice Effectively allows for rolling 16 week lockups of CVX, and provides balances available * at each epoch (1 week). Also receives cvxCrv from `CvxStakingProxy` and redistributes * to depositors. * @dev Individual and delegatee vote power lookups both use independent accounting mechanisms. */ contract AuraLocker is ReentrancyGuard, Ownable, IAuraLocker { using AuraMath for uint256; using AuraMath224 for uint224; using AuraMath112 for uint112; using AuraMath32 for uint32; using SafeERC20 for IERC20; /* ========== STRUCTS ========== */ struct RewardData { /// Timestamp for current period finish uint32 periodFinish; /// Last time any user took action uint32 lastUpdateTime; /// RewardRate for the rest of the period uint96 rewardRate; /// Ever increasing rewardPerToken rate, based on % of total supply uint96 rewardPerTokenStored; } struct UserData { uint128 rewardPerTokenPaid; uint128 rewards; } struct EarnedData { address token; uint256 amount; } struct Balances { uint112 locked; uint32 nextUnlockIndex; } struct LockedBalance { uint112 amount; uint32 unlockTime; } struct Epoch { uint224 supply; uint32 date; //epoch start date } struct DelegateeCheckpoint { uint224 votes; uint32 epochStart; } /* ========== STATE VARIABLES ========== */ // Rewards address[] public rewardTokens; mapping(address => uint256) public queuedRewards; uint256 public constant newRewardRatio = 830; // Core reward data mapping(address => RewardData) public rewardData; // Reward token -> distributor -> is approved to add rewards mapping(address => mapping(address => bool)) public rewardDistributors; // User -> reward token -> amount mapping(address => mapping(address => UserData)) public userData; // Duration that rewards are streamed over uint256 public constant rewardsDuration = 86400 * 7; // Duration of lock/earned penalty period uint256 public constant lockDuration = rewardsDuration * 17; // Balances // Supplies and historic supply uint256 public lockedSupply; // Epochs contains only the tokens that were locked at that epoch, not a cumulative supply Epoch[] public epochs; // Mappings for balance data mapping(address => Balances) public balances; mapping(address => LockedBalance[]) public userLocks; // Voting // Stored delegations mapping(address => address) private _delegates; // Checkpointed votes mapping(address => DelegateeCheckpoint[]) private _checkpointedVotes; // Delegatee balances (user -> unlock timestamp -> amount) mapping(address => mapping(uint256 => uint256)) public delegateeUnlocks; // Config // Blacklisted smart contract interactions mapping(address => bool) public blacklist; // Tokens IERC20 public immutable stakingToken; address public immutable cvxCrv; // Denom for calcs uint256 public constant denominator = 10000; // Staking cvxCrv address public immutable cvxcrvStaking; // Incentives uint256 public kickRewardPerEpoch = 100; uint256 public kickRewardEpochDelay = 3; // Shutdown bool public isShutdown = false; // Basic token data string private _name; string private _symbol; uint8 private immutable _decimals; /* ========== EVENTS ========== */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); event DelegateCheckpointed(address indexed delegate); event Recovered(address _token, uint256 _amount); event RewardPaid(address indexed _user, address indexed _rewardsToken, uint256 _reward); event Staked(address indexed _user, uint256 _paidAmount, uint256 _lockedAmount); event Withdrawn(address indexed _user, uint256 _amount, bool _relocked); event KickReward(address indexed _user, address indexed _kicked, uint256 _reward); event RewardAdded(address indexed _token, uint256 _reward); event BlacklistModified(address account, bool blacklisted); event KickIncentiveSet(uint256 rate, uint256 delay); event Shutdown(); /*************************************** CONSTRUCTOR ****************************************/ /** * @param _nameArg Token name, simples * @param _symbolArg Token symbol * @param _stakingToken CVX (0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B) * @param _cvxCrv cvxCRV (0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7) * @param _cvxCrvStaking cvxCRV rewards (0x3Fe65692bfCD0e6CF84cB1E7d24108E434A7587e) */ constructor( string memory _nameArg, string memory _symbolArg, address _stakingToken, address _cvxCrv, address _cvxCrvStaking ) Ownable() { _name = _nameArg; _symbol = _symbolArg; _decimals = 18; stakingToken = IERC20(_stakingToken); cvxCrv = _cvxCrv; cvxcrvStaking = _cvxCrvStaking; uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); epochs.push(Epoch({ supply: 0, date: uint32(currentEpoch) })); } /*************************************** MODIFIER ****************************************/ modifier updateReward(address _account) { { Balances storage userBalance = balances[_account]; uint256 rewardTokensLength = rewardTokens.length; for (uint256 i = 0; i < rewardTokensLength; i++) { address token = rewardTokens[i]; uint256 newRewardPerToken = _rewardPerToken(token); rewardData[token].rewardPerTokenStored = newRewardPerToken.to96(); rewardData[token].lastUpdateTime = _lastTimeRewardApplicable(rewardData[token].periodFinish).to32(); if (_account != address(0)) { userData[_account][token] = UserData({ rewardPerTokenPaid: newRewardPerToken.to128(), rewards: _earned(_account, token, userBalance.locked).to128() }); } } } _; } modifier notBlacklisted(address _sender, address _receiver) { require(!blacklist[_sender], "blacklisted"); if (_sender != _receiver) { require(!blacklist[_receiver], "blacklisted"); } _; } /*************************************** ADMIN ****************************************/ function modifyBlacklist(address _account, bool _blacklisted) external onlyOwner { uint256 cs; // solhint-disable-next-line no-inline-assembly assembly { cs := extcodesize(_account) } require(cs != 0, "Must be contract"); blacklist[_account] = _blacklisted; emit BlacklistModified(_account, _blacklisted); } // Add a new reward token to be distributed to stakers function addReward(address _rewardsToken, address _distributor) external onlyOwner { require(rewardData[_rewardsToken].lastUpdateTime == 0, "Reward already exists"); require(_rewardsToken != address(stakingToken), "Cannot add StakingToken as reward"); require(rewardTokens.length < 5, "Max rewards length"); rewardTokens.push(_rewardsToken); rewardData[_rewardsToken].lastUpdateTime = uint32(block.timestamp); rewardData[_rewardsToken].periodFinish = uint32(block.timestamp); rewardDistributors[_rewardsToken][_distributor] = true; } // Modify approval for an address to call notifyRewardAmount function approveRewardDistributor( address _rewardsToken, address _distributor, bool _approved ) external onlyOwner { require(rewardData[_rewardsToken].lastUpdateTime > 0, "Reward does not exist"); rewardDistributors[_rewardsToken][_distributor] = _approved; } //set kick incentive function setKickIncentive(uint256 _rate, uint256 _delay) external onlyOwner { require(_rate <= 500, "over max rate"); //max 5% per epoch require(_delay >= 2, "min delay"); //minimum 2 epochs of grace kickRewardPerEpoch = _rate; kickRewardEpochDelay = _delay; emit KickIncentiveSet(_rate, _delay); } //shutdown the contract. unstake all tokens. release all locks function shutdown() external onlyOwner { isShutdown = true; emit Shutdown(); } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { require(_tokenAddress != address(stakingToken), "Cannot withdraw staking token"); require(rewardData[_tokenAddress].lastUpdateTime == 0, "Cannot withdraw reward token"); IERC20(_tokenAddress).safeTransfer(owner(), _tokenAmount); emit Recovered(_tokenAddress, _tokenAmount); } // Set approvals for staking cvx and cvxcrv function setApprovals() external { IERC20(cvxCrv).safeApprove(cvxcrvStaking, 0); IERC20(cvxCrv).safeApprove(cvxcrvStaking, type(uint256).max); } /*************************************** ACTIONS ****************************************/ // Locked tokens cannot be withdrawn for lockDuration and are eligible to receive stakingReward rewards function lock(address _account, uint256 _amount) external nonReentrant updateReward(_account) { //pull tokens stakingToken.safeTransferFrom(msg.sender, address(this), _amount); //lock _lock(_account, _amount); } //lock tokens function _lock(address _account, uint256 _amount) internal notBlacklisted(msg.sender, _account) { require(_amount > 0, "Cannot stake 0"); require(!isShutdown, "shutdown"); Balances storage bal = balances[_account]; //must try check pointing epoch first _checkpointEpoch(); //add user balances uint112 lockAmount = _amount.to112(); bal.locked = bal.locked.add(lockAmount); //add to total supplies lockedSupply = lockedSupply.add(_amount); //add user lock records or add to current uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); uint256 unlockTime = currentEpoch.add(lockDuration); uint256 idx = userLocks[_account].length; if (idx == 0 || userLocks[_account][idx - 1].unlockTime < unlockTime) { userLocks[_account].push(LockedBalance({ amount: lockAmount, unlockTime: uint32(unlockTime) })); } else { LockedBalance storage userL = userLocks[_account][idx - 1]; userL.amount = userL.amount.add(lockAmount); } address delegatee = delegates(_account); if (delegatee != address(0)) { delegateeUnlocks[delegatee][unlockTime] += lockAmount; _checkpointDelegate(delegatee, lockAmount, 0); } //update epoch supply, epoch checkpointed above so safe to add to latest Epoch storage e = epochs[epochs.length - 1]; e.supply = e.supply.add(lockAmount); emit Staked(_account, lockAmount, lockAmount); } // claim all pending rewards function getReward(address _account) external { getReward(_account, false); } // Claim all pending rewards function getReward(address _account, bool _stake) public nonReentrant updateReward(_account) { uint256 rewardTokensLength = rewardTokens.length; for (uint256 i; i < rewardTokensLength; i++) { address _rewardsToken = rewardTokens[i]; uint256 reward = userData[_account][_rewardsToken].rewards; if (reward > 0) { userData[_account][_rewardsToken].rewards = 0; if (_rewardsToken == cvxCrv && _stake && _account == msg.sender) { IRewardStaking(cvxcrvStaking).stakeFor(_account, reward); } else { IERC20(_rewardsToken).safeTransfer(_account, reward); } emit RewardPaid(_account, _rewardsToken, reward); } } } function getReward(address _account, bool[] calldata _skipIdx) external nonReentrant updateReward(_account) { uint256 rewardTokensLength = rewardTokens.length; require(_skipIdx.length == rewardTokensLength, "!arr"); for (uint256 i; i < rewardTokensLength; i++) { if (_skipIdx[i]) continue; address _rewardsToken = rewardTokens[i]; uint256 reward = userData[_account][_rewardsToken].rewards; if (reward > 0) { userData[_account][_rewardsToken].rewards = 0; IERC20(_rewardsToken).safeTransfer(_account, reward); emit RewardPaid(_account, _rewardsToken, reward); } } } function checkpointEpoch() external { _checkpointEpoch(); } //insert a new epoch if needed. fill in any gaps function _checkpointEpoch() internal { uint256 currentEpoch = block.timestamp.div(rewardsDuration).mul(rewardsDuration); //first epoch add in constructor, no need to check 0 length //check to add uint256 nextEpochDate = uint256(epochs[epochs.length - 1].date); if (nextEpochDate < currentEpoch) { while (nextEpochDate != currentEpoch) { nextEpochDate = nextEpochDate.add(rewardsDuration); epochs.push(Epoch({ supply: 0, date: uint32(nextEpochDate) })); } } } // Withdraw/relock all currently locked tokens where the unlock time has passed function processExpiredLocks(bool _relock) external nonReentrant { _processExpiredLocks(msg.sender, _relock, msg.sender, 0); } function kickExpiredLocks(address _account) external nonReentrant { //allow kick after grace period of 'kickRewardEpochDelay' _processExpiredLocks(_account, false, msg.sender, rewardsDuration.mul(kickRewardEpochDelay)); } // Withdraw without checkpointing or accruing any rewards, providing system is shutdown function emergencyWithdraw() external nonReentrant { require(isShutdown, "Must be shutdown"); LockedBalance[] memory locks = userLocks[msg.sender]; Balances storage userBalance = balances[msg.sender]; uint256 amt = userBalance.locked; require(amt > 0, "Nothing locked"); userBalance.locked = 0; userBalance.nextUnlockIndex = locks.length.to32(); lockedSupply -= amt; emit Withdrawn(msg.sender, amt, false); stakingToken.safeTransfer(msg.sender, amt); } // Withdraw all currently locked tokens where the unlock time has passed function _processExpiredLocks( address _account, bool _relock, address _rewardAddress, uint256 _checkDelay ) internal updateReward(_account) { LockedBalance[] storage locks = userLocks[_account]; Balances storage userBalance = balances[_account]; uint112 locked; uint256 length = locks.length; uint256 reward = 0; uint256 expiryTime = _checkDelay == 0 && _relock ? block.timestamp.add(rewardsDuration) : block.timestamp.sub(_checkDelay); require(length > 0, "no locks"); // e.g. now = 16 // if contract is shutdown OR latest lock unlock time (e.g. 17) <= now - (1) // e.g. 17 <= (16 + 1) if (isShutdown || locks[length - 1].unlockTime <= expiryTime) { //if time is beyond last lock, can just bundle everything together locked = userBalance.locked; //dont delete, just set next index userBalance.nextUnlockIndex = length.to32(); //check for kick reward //this wont have the exact reward rate that you would get if looped through //but this section is supposed to be for quick and easy low gas processing of all locks //we'll assume that if the reward was good enough someone would have processed at an earlier epoch if (_checkDelay > 0) { uint256 currentEpoch = block.timestamp.sub(_checkDelay).div(rewardsDuration).mul(rewardsDuration); uint256 epochsover = currentEpoch.sub(uint256(locks[length - 1].unlockTime)).div(rewardsDuration); uint256 rRate = AuraMath.min(kickRewardPerEpoch.mul(epochsover + 1), denominator); reward = uint256(locked).mul(rRate).div(denominator); } } else { //use a processed index(nextUnlockIndex) to not loop as much //deleting does not change array length uint32 nextUnlockIndex = userBalance.nextUnlockIndex; for (uint256 i = nextUnlockIndex; i < length; i++) { //unlock time must be less or equal to time if (locks[i].unlockTime > expiryTime) break; //add to cumulative amounts locked = locked.add(locks[i].amount); //check for kick reward //each epoch over due increases reward if (_checkDelay > 0) { uint256 currentEpoch = block.timestamp.sub(_checkDelay).div(rewardsDuration).mul(rewardsDuration); uint256 epochsover = currentEpoch.sub(uint256(locks[i].unlockTime)).div(rewardsDuration); uint256 rRate = AuraMath.min(kickRewardPerEpoch.mul(epochsover + 1), denominator); reward = reward.add(uint256(locks[i].amount).mul(rRate).div(denominator)); } //set next unlock index nextUnlockIndex++; } //update next unlock index userBalance.nextUnlockIndex = nextUnlockIndex; } require(locked > 0, "no exp locks"); //update user balances and total supplies userBalance.locked = userBalance.locked.sub(locked); lockedSupply = lockedSupply.sub(locked); //checkpoint the delegatee _checkpointDelegate(delegates(_account), 0, 0); emit Withdrawn(_account, locked, _relock); //send process incentive if (reward > 0) { //reduce return amount by the kick reward locked = locked.sub(reward.to112()); //transfer reward stakingToken.safeTransfer(_rewardAddress, reward); emit KickReward(_rewardAddress, _account, reward); } //relock or return to user if (_relock) { _lock(_account, locked); } else { stakingToken.safeTransfer(_account, locked); } } /*************************************** DELEGATION & VOTE BALANCE ****************************************/ /** * @dev Delegate votes from the sender to `newDelegatee`. */ function delegate(address newDelegatee) external virtual nonReentrant { // Step 1: Get lock data LockedBalance[] storage locks = userLocks[msg.sender]; uint256 len = locks.length; require(len > 0, "Nothing to delegate"); require(newDelegatee != address(0), "Must delegate to someone"); // Step 2: Update delegatee storage address oldDelegatee = delegates(msg.sender); require(newDelegatee != oldDelegatee, "Must choose new delegatee"); _delegates[msg.sender] = newDelegatee; emit DelegateChanged(msg.sender, oldDelegatee, newDelegatee); // Step 3: Move balances around // Delegate for the upcoming epoch uint256 upcomingEpoch = block.timestamp.add(rewardsDuration).div(rewardsDuration).mul(rewardsDuration); uint256 i = len - 1; uint256 futureUnlocksSum = 0; LockedBalance memory currentLock = locks[i]; // Step 3.1: Add future unlocks and sum balances while (currentLock.unlockTime > upcomingEpoch) { futureUnlocksSum += currentLock.amount; if (oldDelegatee != address(0)) { delegateeUnlocks[oldDelegatee][currentLock.unlockTime] -= currentLock.amount; } delegateeUnlocks[newDelegatee][currentLock.unlockTime] += currentLock.amount; if (i > 0) { i--; currentLock = locks[i]; } else { break; } } // Step 3.2: Checkpoint old delegatee _checkpointDelegate(oldDelegatee, 0, futureUnlocksSum); // Step 3.3: Checkpoint new delegatee _checkpointDelegate(newDelegatee, futureUnlocksSum, 0); } function _checkpointDelegate( address _account, uint256 _upcomingAddition, uint256 _upcomingDeduction ) internal { // This would only skip on first checkpointing if (_account != address(0)) { uint256 upcomingEpoch = block.timestamp.add(rewardsDuration).div(rewardsDuration).mul(rewardsDuration); DelegateeCheckpoint[] storage ckpts = _checkpointedVotes[_account]; if (ckpts.length > 0) { DelegateeCheckpoint memory prevCkpt = ckpts[ckpts.length - 1]; // If there has already been a record for the upcoming epoch, no need to deduct the unlocks if (prevCkpt.epochStart == upcomingEpoch) { ckpts[ckpts.length - 1] = DelegateeCheckpoint({ votes: (prevCkpt.votes + _upcomingAddition - _upcomingDeduction).to224(), epochStart: upcomingEpoch.to32() }); } // else if it has been over 16 weeks since the previous checkpoint, all locks have since expired // e.g. week 1 + 17 <= 18 else if (prevCkpt.epochStart + lockDuration <= upcomingEpoch) { ckpts.push( DelegateeCheckpoint({ votes: (_upcomingAddition - _upcomingDeduction).to224(), epochStart: upcomingEpoch.to32() }) ); } else { uint256 nextEpoch = upcomingEpoch; uint256 unlocksSinceLatestCkpt = 0; // Should be maximum 18 iterations while (nextEpoch > prevCkpt.epochStart) { unlocksSinceLatestCkpt += delegateeUnlocks[_account][nextEpoch]; nextEpoch -= rewardsDuration; } ckpts.push( DelegateeCheckpoint({ votes: (prevCkpt.votes - unlocksSinceLatestCkpt + _upcomingAddition - _upcomingDeduction) .to224(), epochStart: upcomingEpoch.to32() }) ); } } else { ckpts.push( DelegateeCheckpoint({ votes: (_upcomingAddition - _upcomingDeduction).to224(), epochStart: upcomingEpoch.to32() }) ); } emit DelegateCheckpointed(_account); } } /** * @dev Get the address `account` is currently delegating to. */ function delegates(address account) public view virtual returns (address) { return _delegates[account]; } /** * @dev Gets the current votes balance for `account` */ function getVotes(address account) external view returns (uint256) { return getPastVotes(account, block.timestamp); } /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) external view virtual returns (DelegateeCheckpoint memory) { return _checkpointedVotes[account][pos]; } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) external view virtual returns (uint32) { return _checkpointedVotes[account].length.to32(); } /** * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. */ function getPastVotes(address account, uint256 timestamp) public view returns (uint256 votes) { require(timestamp <= block.timestamp, "ERC20Votes: block not yet mined"); uint256 epoch = timestamp.div(rewardsDuration).mul(rewardsDuration); DelegateeCheckpoint memory ckpt = _checkpointsLookup(_checkpointedVotes[account], epoch); votes = ckpt.votes; if (votes == 0 || ckpt.epochStart + lockDuration <= epoch) { return 0; } while (epoch > ckpt.epochStart) { votes -= delegateeUnlocks[account][epoch]; epoch -= rewardsDuration; } } /** * @dev Retrieve the `totalSupply` at the end of `timestamp`. Note, this value is the sum of all balances. * It is but NOT the sum of all the delegated votes! */ function getPastTotalSupply(uint256 timestamp) external view returns (uint256) { require(timestamp < block.timestamp, "ERC20Votes: block not yet mined"); return totalSupplyAtEpoch(findEpochId(timestamp)); } /** * @dev Lookup a value in a list of (sorted) checkpoints. * Copied from oz/ERC20Votes.sol */ function _checkpointsLookup(DelegateeCheckpoint[] storage ckpts, uint256 epochStart) private view returns (DelegateeCheckpoint memory) { uint256 high = ckpts.length; uint256 low = 0; while (low < high) { uint256 mid = AuraMath.average(low, high); if (ckpts[mid].epochStart > epochStart) { high = mid; } else { low = mid + 1; } } return high == 0 ? DelegateeCheckpoint(0, 0) : ckpts[high - 1]; } /*************************************** VIEWS - BALANCES ****************************************/ // Balance of an account which only includes properly locked tokens as of the most recent eligible epoch function balanceOf(address _user) external view returns (uint256 amount) { return balanceAtEpochOf(findEpochId(block.timestamp), _user); } // Balance of an account which only includes properly locked tokens at the given epoch function balanceAtEpochOf(uint256 _epoch, address _user) public view returns (uint256 amount) { uint256 epochStart = uint256(epochs[0].date).add(uint256(_epoch).mul(rewardsDuration)); require(epochStart < block.timestamp, "Epoch is in the future"); uint256 cutoffEpoch = epochStart.sub(lockDuration); LockedBalance[] storage locks = userLocks[_user]; //need to add up since the range could be in the middle somewhere //traverse inversely to make more current queries more gas efficient uint256 locksLength = locks.length; for (uint256 i = locksLength; i > 0; i--) { uint256 lockEpoch = uint256(locks[i - 1].unlockTime).sub(lockDuration); //lock epoch must be less or equal to the epoch we're basing from. //also not include the current epoch if (lockEpoch < epochStart) { if (lockEpoch > cutoffEpoch) { amount = amount.add(locks[i - 1].amount); } else { //stop now as no futher checks matter break; } } } return amount; } // Information on a user's locked balances function lockedBalances(address _user) external view returns ( uint256 total, uint256 unlockable, uint256 locked, LockedBalance[] memory lockData ) { LockedBalance[] storage locks = userLocks[_user]; Balances storage userBalance = balances[_user]; uint256 nextUnlockIndex = userBalance.nextUnlockIndex; uint256 idx; for (uint256 i = nextUnlockIndex; i < locks.length; i++) { if (locks[i].unlockTime > block.timestamp) { if (idx == 0) { lockData = new LockedBalance[](locks.length - i); } lockData[idx] = locks[i]; idx++; locked = locked.add(locks[i].amount); } else { unlockable = unlockable.add(locks[i].amount); } } return (userBalance.locked, unlockable, locked, lockData); } // Supply of all properly locked balances at most recent eligible epoch function totalSupply() external view returns (uint256 supply) { return totalSupplyAtEpoch(findEpochId(block.timestamp)); } // Supply of all properly locked balances at the given epoch function totalSupplyAtEpoch(uint256 _epoch) public view returns (uint256 supply) { uint256 epochStart = uint256(epochs[0].date).add(uint256(_epoch).mul(rewardsDuration)); require(epochStart < block.timestamp, "Epoch is in the future"); uint256 cutoffEpoch = epochStart.sub(lockDuration); uint256 lastIndex = epochs.length - 1; uint256 epochIndex = _epoch > lastIndex ? lastIndex : _epoch; for (uint256 i = epochIndex + 1; i > 0; i--) { Epoch memory e = epochs[i - 1]; if (e.date == epochStart) { continue; } else if (e.date <= cutoffEpoch) { break; } else { supply += e.supply; } } } // Get an epoch index based on timestamp function findEpochId(uint256 _time) public view returns (uint256 epoch) { return _time.sub(epochs[0].date).div(rewardsDuration); } /*************************************** VIEWS - GENERAL ****************************************/ // Number of epochs function epochCount() external view returns (uint256) { return epochs.length; } function decimals() external view returns (uint8) { return _decimals; } function name() external view returns (string memory) { return _name; } function symbol() external view returns (string memory) { return _symbol; } /*************************************** VIEWS - REWARDS ****************************************/ // Address and claimable amount of all reward tokens for the given account function claimableRewards(address _account) external view returns (EarnedData[] memory userRewards) { userRewards = new EarnedData[](rewardTokens.length); Balances storage userBalance = balances[_account]; uint256 userRewardsLength = userRewards.length; for (uint256 i = 0; i < userRewardsLength; i++) { address token = rewardTokens[i]; userRewards[i].token = token; userRewards[i].amount = _earned(_account, token, userBalance.locked); } return userRewards; } function lastTimeRewardApplicable(address _rewardsToken) external view returns (uint256) { return _lastTimeRewardApplicable(rewardData[_rewardsToken].periodFinish); } function rewardPerToken(address _rewardsToken) external view returns (uint256) { return _rewardPerToken(_rewardsToken); } function _earned( address _user, address _rewardsToken, uint256 _balance ) internal view returns (uint256) { UserData memory data = userData[_user][_rewardsToken]; return _balance.mul(_rewardPerToken(_rewardsToken).sub(data.rewardPerTokenPaid)).div(1e18).add(data.rewards); } function _lastTimeRewardApplicable(uint256 _finishTime) internal view returns (uint256) { return AuraMath.min(block.timestamp, _finishTime); } function _rewardPerToken(address _rewardsToken) internal view returns (uint256) { if (lockedSupply == 0) { return rewardData[_rewardsToken].rewardPerTokenStored; } return uint256(rewardData[_rewardsToken].rewardPerTokenStored).add( _lastTimeRewardApplicable(rewardData[_rewardsToken].periodFinish) .sub(rewardData[_rewardsToken].lastUpdateTime) .mul(rewardData[_rewardsToken].rewardRate) .mul(1e18) .div(lockedSupply) ); } /*************************************** REWARD FUNDING ****************************************/ function queueNewRewards(address _rewardsToken, uint256 _rewards) external nonReentrant { require(rewardDistributors[_rewardsToken][msg.sender], "!authorized"); require(_rewards > 0, "No reward"); RewardData storage rdata = rewardData[_rewardsToken]; IERC20(_rewardsToken).safeTransferFrom(msg.sender, address(this), _rewards); _rewards = _rewards.add(queuedRewards[_rewardsToken]); require(_rewards < 1e25, "!rewards"); if (block.timestamp >= rdata.periodFinish) { _notifyReward(_rewardsToken, _rewards); queuedRewards[_rewardsToken] = 0; return; } //et = now - (finish-duration) uint256 elapsedTime = block.timestamp.sub(rdata.periodFinish.sub(rewardsDuration.to32())); //current at now: rewardRate * elapsedTime uint256 currentAtNow = rdata.rewardRate * elapsedTime; uint256 queuedRatio = currentAtNow.mul(1000).div(_rewards); if (queuedRatio < newRewardRatio) { _notifyReward(_rewardsToken, _rewards); queuedRewards[_rewardsToken] = 0; } else { queuedRewards[_rewardsToken] = _rewards; } } function _notifyReward(address _rewardsToken, uint256 _reward) internal updateReward(address(0)) { RewardData storage rdata = rewardData[_rewardsToken]; if (block.timestamp >= rdata.periodFinish) { rdata.rewardRate = _reward.div(rewardsDuration).to96(); } else { uint256 remaining = uint256(rdata.periodFinish).sub(block.timestamp); uint256 leftover = remaining.mul(rdata.rewardRate); rdata.rewardRate = _reward.add(leftover).div(rewardsDuration).to96(); } // Equivalent to 10 million tokens over a weeks duration require(rdata.rewardRate < 1e20, "!rewardRate"); require(lockedSupply >= 1e20, "!balance"); rdata.lastUpdateTime = block.timestamp.to32(); rdata.periodFinish = block.timestamp.add(rewardsDuration).to32(); emit RewardAdded(_rewardsToken, _reward); } } // File contracts/interfaces/balancer/IBalancerCore.sol pragma solidity 0.8.11; interface IPriceOracle { struct OracleAverageQuery { Variable variable; uint256 secs; uint256 ago; } enum Variable { PAIR_PRICE, BPT_PRICE, INVARIANT } function getTimeWeightedAverage(OracleAverageQuery[] memory queries) external view returns (uint256[] memory results); } interface IBalancerVault { enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN } enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT } enum SwapKind { GIVEN_IN, GIVEN_OUT } struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } function batchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds, int256[] memory limits, uint256 deadline ) external payable returns (int256[] memory); struct SingleSwap { bytes32 poolId; SwapKind kind; IAsset assetIn; IAsset assetOut; uint256 amount; bytes userData; } struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } struct JoinPoolRequest { IAsset[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } function getPool(bytes32 poolId) external view returns (address, PoolSpecialization); function getPoolTokens(bytes32 poolId) external view returns ( address[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock ); function joinPool( bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request ) external payable; function swap( SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline ) external returns (uint256 amountCalculated); function exitPool( bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request ) external; function getInternalBalance(address user, address[] memory tokens) external view returns (uint256[] memory); function queryBatchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds ) external returns (int256[] memory assetDeltas); struct ExitPoolRequest { IAsset[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } enum ExitKind { EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, EXACT_BPT_IN_FOR_TOKENS_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT, MANAGEMENT_FEE_TOKENS_OUT // for ManagedPool } } interface IAsset { // solhint-disable-previous-line no-empty-blocks } interface IBalancerPool { function getPoolId() external view returns (bytes32); function getNormalizedWeights() external view returns (uint256[] memory); function getSwapEnabled() external view returns (bool); function getOwner() external view returns (address); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); } interface ILBPFactory { function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256[] memory weights, uint256 swapFeePercentage, address owner, bool swapEnabledOnStart ) external returns (address); } interface ILBP { function setSwapEnabled(bool swapEnabled) external; function updateWeightsGradually( uint256 startTime, uint256 endTime, uint256[] memory endWeights ) external; function getGradualWeightUpdateParams() external view returns ( uint256 startTime, uint256 endTime, uint256[] memory endWeights ); } interface IStablePoolFactory { function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256 amplificationParameter, uint256 swapFeePercentage, address owner ) external returns (address); } interface IWeightedPool2TokensFactory { function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256[] memory weights, uint256 swapFeePercentage, bool oracleEnabled, address owner ) external returns (address); } interface IRateProvider { function getRate() external view returns (uint256); } interface IWeightedPoolFactory { /** * @dev Deploys a new `WeightedPool`. */ function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256[] memory normalizedWeights, IRateProvider[] memory rateProviders, uint256 swapFeePercentage, address owner ) external returns (address); } interface IWeightedPoolFactoryV2 { /** * @dev Deploys a new `WeightedPool`. */ function create( string memory name, string memory symbol, IERC20[] memory tokens, uint256[] memory normalizedWeights, uint256 swapFeePercentage, address owner ) external returns (address); } // File contracts/interfaces/IAuraBalVault.sol pragma solidity 0.8.11; interface IAuraBalVault { function underlying() external view returns (address); function withdrawalPenalty() external view returns (uint256); function extraRewards(uint256 index) external view returns (address); function extraRewardsLength() external view returns (uint256); function totalUnderlying() external view returns (uint256); function balanceOf(address user) external view returns (uint256); function balanceOfUnderlying(address user) external view returns (uint256); function totalSupply() external view returns (uint256); } // File contracts/interfaces/IBoosterLite.sol pragma solidity 0.8.11; interface IBoosterLite { struct PoolInfo { address lptoken; address token; address gauge; address crvRewards; address stash; bool shutdown; } function earmarkRewards(uint256 _pid, address _zroPaymentAddress) external payable returns (bool); function poolLength() external view returns (uint256); function poolInfo(uint256 _pid) external view returns (PoolInfo memory poolInfo); function lockIncentive() external view returns (uint256); function stakerIncentive() external view returns (uint256); function earmarkIncentive() external view returns (uint256); function platformFee() external view returns (uint256); function FEE_DENOMINATOR() external view returns (uint256); } // File contracts/peripheral/AuraViewHelpersLite.sol pragma solidity 0.8.11; /** * @title AuraViewHelpersLite * @author AuraFinance * @notice View-only contract to combine calls for sidechain deployments * @dev IMPORTANT: These functions are extremely gas-intensive and should not be called from within a transaction. */ contract AuraViewHelpersLite { IBalancerVault public immutable balancerVault = IBalancerVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8); struct Token { address addr; uint8 decimals; string symbol; string name; } struct Pool { uint256 pid; address lptoken; address token; address gauge; address crvRewards; address stash; bool shutdown; address rewardToken; bytes32 poolId; uint256[] normalizedWeights; address[] poolTokens; uint256[] underlying; uint256 totalSupply; uint256 bptTotalSupply; RewardsData rewardsData; ExtraRewards[] extraRewards; } struct Vault { address addr; address underlying; uint256 totalUnderlying; uint256 totalSupply; uint256 withdrawalPenalty; ExtraRewards[] extraRewards; } struct VaultAccount { address addr; uint256 balance; uint256 balanceOfUnderlying; uint256[] extraRewardsEarned; } struct RewardsData { uint256 periodFinish; uint256 lastUpdateTime; uint256 rewardRate; uint256 rewardPerTokenStored; uint256 queuedRewards; } struct ExtraRewards { address addr; address rewardsToken; RewardsData rewardsData; } struct PoolBalances { uint256 pid; uint256 earned; uint256[] extraRewardsEarned; uint256 staked; } function getVault(address _vault) external view returns (Vault memory vault) { IAuraBalVault auraBalVault = IAuraBalVault(_vault); address underlying = auraBalVault.underlying(); uint256 totalUnderlying = auraBalVault.totalUnderlying(); uint256 totalSupply = auraBalVault.totalSupply(); uint256 withdrawPenalty = auraBalVault.withdrawalPenalty(); ExtraRewards[] memory extraRewards = getExtraRewards(_vault); vault = Vault({ addr: _vault, underlying: underlying, totalUnderlying: totalUnderlying, totalSupply: totalSupply, withdrawalPenalty: withdrawPenalty, extraRewards: extraRewards }); } function getVaultAccount(address _vault, address _account) external view returns (VaultAccount memory vaultAccount) { IAuraBalVault auraBalVault = IAuraBalVault(_vault); uint256 balance = auraBalVault.balanceOf(_account); uint256 balanceOfUnderlying = auraBalVault.balanceOfUnderlying(_account); uint256 extraRewardsLength = auraBalVault.extraRewardsLength(); uint256[] memory extraRewardsEarned = new uint256[](extraRewardsLength); for (uint256 i = 0; i < extraRewardsLength; i++) { IBaseRewardPool extraRewardsPool = IBaseRewardPool(auraBalVault.extraRewards(i)); extraRewardsEarned[i] = extraRewardsPool.earned(_account); } vaultAccount = VaultAccount({ addr: _account, balance: balance, balanceOfUnderlying: balanceOfUnderlying, extraRewardsEarned: extraRewardsEarned }); } function getPools(address _booster) external view returns (Pool[] memory) { IBoosterLite booster = IBoosterLite(_booster); uint256 poolLength = booster.poolLength(); Pool[] memory pools = new Pool[](poolLength); for (uint256 i = 0; i < poolLength; i++) { IBoosterLite.PoolInfo memory poolInfo = booster.poolInfo(i); pools[i] = getPool(poolInfo, i); } return pools; } function getCvxCrvRewards(address _cvxCrvRewards) public view returns (Pool memory) { IBaseRewardPool pool = IBaseRewardPool(_cvxCrvRewards); address cvxCrv = pool.stakingToken(); uint256[] memory normalizedWeights = new uint256[](1); normalizedWeights[0] = 1; address[] memory poolTokens = new address[](1); poolTokens[0] = cvxCrv; uint256[] memory underlying = new uint256[](1); underlying[0] = IERC20Detailed(cvxCrv).balanceOf(_cvxCrvRewards); RewardsData memory rewardsData = RewardsData({ rewardRate: pool.rewardRate(), periodFinish: pool.periodFinish(), lastUpdateTime: pool.lastUpdateTime(), rewardPerTokenStored: pool.rewardPerTokenStored(), queuedRewards: pool.queuedRewards() }); ExtraRewards[] memory extraRewards = getExtraRewards(_cvxCrvRewards); return Pool({ pid: uint256(0), lptoken: cvxCrv, token: cvxCrv, gauge: address(0), crvRewards: _cvxCrvRewards, stash: address(0), shutdown: false, rewardToken: pool.rewardToken(), poolId: bytes32(0), normalizedWeights: normalizedWeights, poolTokens: poolTokens, underlying: underlying, rewardsData: rewardsData, extraRewards: extraRewards, totalSupply: pool.totalSupply(), bptTotalSupply: 0 }); } function getExtraRewards(address _baseRewardPool) internal view returns (ExtraRewards[] memory) { IBaseRewardPool baseRewardPool = IBaseRewardPool(_baseRewardPool); uint256 extraRewardsLength = baseRewardPool.extraRewardsLength(); ExtraRewards[] memory extraRewards = new ExtraRewards[](extraRewardsLength); for (uint256 i = 0; i < extraRewardsLength; i++) { address addr = baseRewardPool.extraRewards(i); IBaseRewardPool extraRewardsPool = IBaseRewardPool(addr); RewardsData memory data = RewardsData({ rewardRate: extraRewardsPool.rewardRate(), periodFinish: extraRewardsPool.periodFinish(), lastUpdateTime: extraRewardsPool.lastUpdateTime(), rewardPerTokenStored: extraRewardsPool.rewardPerTokenStored(), queuedRewards: extraRewardsPool.queuedRewards() }); extraRewards[i] = ExtraRewards({ addr: addr, rewardsData: data, rewardsToken: extraRewardsPool.rewardToken() }); } return extraRewards; } function getPool(IBoosterLite.PoolInfo memory poolInfo, uint256 _pid) public view returns (Pool memory) { IBaseRewardPool rewardPool = IBaseRewardPool(poolInfo.crvRewards); IBalancerPool balancerPool = IBalancerPool(poolInfo.lptoken); // Some pools were added to the Booster without valid LP tokens; // we need to try/catch all of these calls as a result. bytes32 poolId; uint256[] memory normalizedWeights; address[] memory poolTokens; uint256[] memory underlying; try balancerPool.getPoolId() returns (bytes32 fetchedPoolId) { poolId = fetchedPoolId; (poolTokens, underlying, ) = balancerVault.getPoolTokens(poolId); try balancerPool.getNormalizedWeights() returns (uint256[] memory weights) { normalizedWeights = weights; } catch { normalizedWeights = new uint256[](0); } } catch { poolId = bytes32(0); poolTokens = new address[](0); underlying = new uint256[](0); normalizedWeights = new uint256[](0); } ExtraRewards[] memory extraRewards = getExtraRewards(poolInfo.crvRewards); RewardsData memory rewardsData = RewardsData({ rewardRate: rewardPool.rewardRate(), periodFinish: rewardPool.periodFinish(), lastUpdateTime: rewardPool.lastUpdateTime(), rewardPerTokenStored: rewardPool.rewardPerTokenStored(), queuedRewards: rewardPool.queuedRewards() }); return Pool({ pid: _pid, lptoken: poolInfo.lptoken, token: poolInfo.token, gauge: poolInfo.gauge, crvRewards: poolInfo.crvRewards, stash: poolInfo.stash, shutdown: poolInfo.shutdown, rewardToken: rewardPool.rewardToken(), poolId: poolId, normalizedWeights: normalizedWeights, poolTokens: poolTokens, underlying: underlying, rewardsData: rewardsData, extraRewards: extraRewards, totalSupply: rewardPool.totalSupply(), bptTotalSupply: balancerPool.totalSupply() }); } function getPoolsBalances(address _booster, address _account) external view returns (PoolBalances[] memory) { uint256 poolLength = IBoosterLite(_booster).poolLength(); PoolBalances[] memory balances = new PoolBalances[](poolLength); for (uint256 i = 0; i < poolLength; i++) { IBoosterLite.PoolInfo memory poolInfo = IBoosterLite(_booster).poolInfo(i); balances[i] = getPoolBalances(poolInfo.crvRewards, i, _account); } return balances; } function getPoolBalances( address _rewardPool, uint256 _pid, address _account ) public view returns (PoolBalances memory) { IBaseRewardPool pool = IBaseRewardPool(_rewardPool); uint256 staked = pool.balanceOf(_account); uint256 earned = pool.earned(_account); uint256 extraRewardsLength = pool.extraRewardsLength(); uint256[] memory extraRewardsEarned = new uint256[](extraRewardsLength); for (uint256 i = 0; i < extraRewardsLength; i++) { IBaseRewardPool extraRewardsPool = IBaseRewardPool(pool.extraRewards(i)); extraRewardsEarned[i] = extraRewardsPool.earned(_account); } return PoolBalances({ pid: _pid, staked: staked, earned: earned, extraRewardsEarned: extraRewardsEarned }); } function getTokens(address[] memory _addresses) public view returns (Token[] memory) { uint256 length = _addresses.length; Token[] memory tokens = new Token[](length); for (uint256 i = 0; i < length; i++) { address addr = _addresses[i]; IERC20Detailed token = IERC20Detailed(addr); uint8 decimals; try token.decimals() { decimals = token.decimals(); } catch { decimals = 0; } tokens[i] = Token({ addr: addr, decimals: decimals, symbol: token.symbol(), name: token.name() }); } return tokens; } function getEarmarkingReward( uint256 pool, address booster, address token ) public returns (uint256 pending) { uint256 start = IERC20Detailed(token).balanceOf(address(this)); IBoosterLite(booster).earmarkRewards(pool, address(0)); pending = IERC20Detailed(token).balanceOf(address(this)) - start; } function getMultipleEarmarkingRewards( uint256[] memory pools, address booster, address token ) external returns (uint256[] memory pendings) { pendings = new uint256[](pools.length); for (uint256 i = 0; i < pools.length; i++) { pendings[i] = getEarmarkingReward(pools[i], booster, token); } } } interface IBaseRewardPool { function extraRewards(uint256 index) external view returns (address rewards); function extraRewardsLength() external view returns (uint256); function lastUpdateTime() external view returns (uint256); function periodFinish() external view returns (uint256); function pid() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function earned(address owner) external view returns (uint256); function queuedRewards() external view returns (uint256); function rewardPerTokenStored() external view returns (uint256); function rewardRate() external view returns (uint256); function totalSupply() external view returns (uint256); function rewardToken() external view returns (address); function stakingToken() external view returns (address); } interface IERC20Detailed { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"balancerVault","outputs":[{"internalType":"contract IBalancerVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_cvxCrvRewards","type":"address"}],"name":"getCvxCrvRewards","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256[]","name":"normalizedWeights","type":"uint256[]"},{"internalType":"address[]","name":"poolTokens","type":"address[]"},{"internalType":"uint256[]","name":"underlying","type":"uint256[]"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"bptTotalSupply","type":"uint256"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.RewardsData","name":"rewardsData","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct AuraViewHelpersLite.ExtraRewards[]","name":"extraRewards","type":"tuple[]"}],"internalType":"struct AuraViewHelpersLite.Pool","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pool","type":"uint256"},{"internalType":"address","name":"booster","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getEarmarkingReward","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pools","type":"uint256[]"},{"internalType":"address","name":"booster","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getMultipleEarmarkingRewards","outputs":[{"internalType":"uint256[]","name":"pendings","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"}],"internalType":"struct IBoosterLite.PoolInfo","name":"poolInfo","type":"tuple"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getPool","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256[]","name":"normalizedWeights","type":"uint256[]"},{"internalType":"address[]","name":"poolTokens","type":"address[]"},{"internalType":"uint256[]","name":"underlying","type":"uint256[]"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"bptTotalSupply","type":"uint256"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.RewardsData","name":"rewardsData","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct AuraViewHelpersLite.ExtraRewards[]","name":"extraRewards","type":"tuple[]"}],"internalType":"struct AuraViewHelpersLite.Pool","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardPool","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_account","type":"address"}],"name":"getPoolBalances","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"earned","type":"uint256"},{"internalType":"uint256[]","name":"extraRewardsEarned","type":"uint256[]"},{"internalType":"uint256","name":"staked","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.PoolBalances","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_booster","type":"address"}],"name":"getPools","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"lptoken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"crvRewards","type":"address"},{"internalType":"address","name":"stash","type":"address"},{"internalType":"bool","name":"shutdown","type":"bool"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"bytes32","name":"poolId","type":"bytes32"},{"internalType":"uint256[]","name":"normalizedWeights","type":"uint256[]"},{"internalType":"address[]","name":"poolTokens","type":"address[]"},{"internalType":"uint256[]","name":"underlying","type":"uint256[]"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"bptTotalSupply","type":"uint256"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.RewardsData","name":"rewardsData","type":"tuple"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct AuraViewHelpersLite.ExtraRewards[]","name":"extraRewards","type":"tuple[]"}],"internalType":"struct AuraViewHelpersLite.Pool[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_booster","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"getPoolsBalances","outputs":[{"components":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"earned","type":"uint256"},{"internalType":"uint256[]","name":"extraRewardsEarned","type":"uint256[]"},{"internalType":"uint256","name":"staked","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.PoolBalances[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"getTokens","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct AuraViewHelpersLite.Token[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"getVault","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"totalUnderlying","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"withdrawalPenalty","type":"uint256"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"components":[{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"uint256","name":"queuedRewards","type":"uint256"}],"internalType":"struct AuraViewHelpersLite.RewardsData","name":"rewardsData","type":"tuple"}],"internalType":"struct AuraViewHelpersLite.ExtraRewards[]","name":"extraRewards","type":"tuple[]"}],"internalType":"struct AuraViewHelpersLite.Vault","name":"vault","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"getVaultAccount","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"balanceOfUnderlying","type":"uint256"},{"internalType":"uint256[]","name":"extraRewardsEarned","type":"uint256[]"}],"internalType":"struct AuraViewHelpersLite.VaultAccount","name":"vaultAccount","type":"tuple"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a060405273ba12222222228d8ba445958a75a0704d566bf2c860805234801561002857600080fd5b50608051612f3061004a6000396000818160dc0152610e4d0152612f306000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80634cf4c36a116100715780634cf4c36a146101775780635c39f467146101975780637f5f53d1146101b75780639b9e0955146101d7578063c025d1a5146101f7578063eda242901461021757600080fd5b80630eb9af38146100ae578063158274a5146100d75780631fbf73ac14610116578063273a94aa146101375780633e3dcce814610157575b600080fd5b6100c16100bc3660046122c3565b61022a565b6040516100ce919061237b565b60405180910390f35b6100fe7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100ce565b6101296101243660046123dc565b610461565b6040519081526020016100ce565b61014a6101453660046124af565b6105c1565b6040516100ce91906125a9565b61016a610165366004612653565b610865565b6040516100ce91906126f7565b61018a61018536600461270a565b610b5a565b6040516100ce91906127bc565b6101aa6101a53660046122c3565b610c00565b6040516100ce9190612994565b6101ca6101c5366004612a04565b610d80565b6040516100ce9190612aa9565b6101ea6101e5366004612abc565b611351565b6040516100ce9190612af5565b61020a610205366004612abc565b6114eb565b6040516100ce9190612b4a565b6101ca6102253660046122c3565b6117f4565b6102756040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001606081525090565b60008290506000816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102de9190612b8b565b90506000826001600160a01b031663c70920bc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610320573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103449190612ba8565b90506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa9190612ba8565b90506000846001600160a01b031663a2468c196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104109190612ba8565b9050600061041d88611d3f565b6040805160c0810182526001600160a01b039a8b16815296909916602087015297850193909352606084019190915260808301525060a08101939093525090919050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038416906370a0823190602401602060405180830381865afa1580156104aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ce9190612ba8565b604051637979426b60e01b815260048101879052600060248201529091506001600160a01b03851690637979426b906044016020604051808303816000875af115801561051f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105439190612bc1565b506040516370a0823160e01b815230600482015281906001600160a01b038516906370a0823190602401602060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ae9190612ba8565b6105b89190612bf4565b95945050505050565b80516060906000816001600160401b038111156105e0576105e061241e565b60405190808252806020026020018201604052801561063457816020015b60408051608081018252600080825260208201526060918101829052818101919091528152602001906001900390816105fe5790505b50905060005b8281101561085d57600085828151811061065657610656612c0b565b6020026020010151905060008190506000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106c1575060408051601f3d908101601f191682019092526106be91810190612c21565b60015b6106cd57506000610733565b50816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561070c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107309190612c21565b90505b6040518060800160405280846001600160a01b031681526020018260ff168152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610794573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107bc9190810190612c44565b8152602001836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108279190810190612c44565b81525085858151811061083c5761083c612c0b565b6020026020010181905250505050808061085590612cce565b91505061063a565b509392505050565b6108906040518060800160405280600081526020016000815260200160608152602001600081525090565b6040516370a0823160e01b81526001600160a01b03838116600483015285916000918316906370a0823190602401602060405180830381865afa1580156108db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ff9190612ba8565b6040516246613160e11b81526001600160a01b038681166004830152919250600091841690628cc26290602401602060405180830381865afa158015610949573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096d9190612ba8565b90506000836001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d39190612ba8565b90506000816001600160401b038111156109ef576109ef61241e565b604051908082528060200260200182016040528015610a18578160200160208202803683370190505b50905060005b82811015610b2e57604051632061aa2360e11b8152600481018290526000906001600160a01b038816906340c3544690602401602060405180830381865afa158015610a6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a929190612b8b565b6040516246613160e11b81526001600160a01b038b8116600483015291925090821690628cc26290602401602060405180830381865afa158015610ada573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afe9190612ba8565b838381518110610b1057610b10612c0b565b60209081029190910101525080610b2681612cce565b915050610a1e565b506040805160808101825289815260208101949094528301525060608101919091529150509392505050565b606083516001600160401b03811115610b7557610b7561241e565b604051908082528060200260200182016040528015610b9e578160200160208202803683370190505b50905060005b845181101561085d57610bd1858281518110610bc257610bc2612c0b565b60200260200101518585610461565b828281518110610be357610be3612c0b565b602090810291909101015280610bf881612cce565b915050610ba4565b606060008290506000816001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6b9190612ba8565b90506000816001600160401b03811115610c8757610c8761241e565b604051908082528060200260200182016040528015610cc057816020015b610cad612151565b815260200190600190039081610ca55790505b50905060005b82811015610d7757604051631526fe2760e01b8152600481018290526000906001600160a01b03861690631526fe279060240160c060405180830381865afa158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a9190612ce9565b9050610d468183610d80565b838381518110610d5857610d58612c0b565b6020026020010181905250508080610d6f90612cce565b915050610cc6565b50949350505050565b610d88612151565b60008360600151905060008460000151905060006060806060846001600160a01b03166338fff2d06040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610dfb575060408051601f3d908101601f19168201909252610df891810190612ba8565b60015b610e2a575050604080516000808252602082018181528284018281526060840190945290945091925090610f43565b604051631f29a8cd60e31b81526004810182905290945084906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f94d466890602401600060405180830381865afa158015610e94573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ebc9190810190612df9565b508093508194505050856001600160a01b031663f89f27ed6040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015610f2457506040513d6000823e601f3d908101601f19168201604052610f219190810190612ec6565b60015b610f3e576040805160008152602081019091529350610f41565b93505b505b6000610f528a60600151611d3f565b905060006040518060a00160405280896001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc39190612ba8565b8152602001896001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611006573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102a9190612ba8565b8152602001896001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612ba8565b8152602001896001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f89190612ba8565b8152602001896001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561113b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115f9190612ba8565b81525090506040518061020001604052808b81526020018c600001516001600160a01b031681526020018c602001516001600160a01b031681526020018c604001516001600160a01b031681526020018c606001516001600160a01b031681526020018c608001516001600160a01b031681526020018c60a0015115158152602001896001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa15801561121f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112439190612b8b565b6001600160a01b03168152602001878152602001868152602001858152602001848152602001896001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb9190612ba8565b8152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113329190612ba8565b8152602001828152602001838152509850505050505050505092915050565b60606000836001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611393573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b79190612ba8565b90506000816001600160401b038111156113d3576113d361241e565b60405190808252806020026020018201604052801561142f57816020015b61141c6040518060800160405280600081526020016000815260200160608152602001600081525090565b8152602001906001900390816113f15790505b50905060005b82811015610d7757604051631526fe2760e01b8152600481018290526000906001600160a01b03881690631526fe279060240160c060405180830381865afa158015611485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a99190612ce9565b90506114ba81606001518388610865565b8383815181106114cc576114cc612c0b565b60200260200101819052505080806114e390612cce565b915050611435565b61151f604051806080016040528060006001600160a01b031681526020016000815260200160008152602001606081525090565b6040516370a0823160e01b81526001600160a01b03838116600483015284916000918316906370a0823190602401602060405180830381865afa15801561156a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158e9190612ba8565b604051633af9e66960e01b81526001600160a01b038681166004830152919250600091841690633af9e66990602401602060405180830381865afa1580156115da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fe9190612ba8565b90506000836001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611640573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116649190612ba8565b90506000816001600160401b038111156116805761168061241e565b6040519080825280602002602001820160405280156116a9578160200160208202803683370190505b50905060005b828110156117bf57604051632061aa2360e11b8152600481018290526000906001600160a01b038816906340c3544690602401602060405180830381865afa1580156116ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117239190612b8b565b6040516246613160e11b81526001600160a01b038b8116600483015291925090821690628cc26290602401602060405180830381865afa15801561176b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178f9190612ba8565b8383815181106117a1576117a1612c0b565b602090810291909101015250806117b781612cce565b9150506116af565b50604080516080810182526001600160a01b039098168852602088019490945292860191909152506060840152509092915050565b6117fc612151565b60008290506000816001600160a01b03166372f702f36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118659190612b8b565b60408051600180825281830190925291925060009190602080830190803683370190505090506001816000815181106118a0576118a0612c0b565b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905082816000815181106118e3576118e3612c0b565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050506040516370a0823160e01b81526001600160a01b038981166004830152919250908516906370a0823190602401602060405180830381865afa158015611968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198c9190612ba8565b8160008151811061199f5761199f612c0b565b60200260200101818152505060006040518060a00160405280876001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1a9190612ba8565b8152602001876001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a819190612ba8565b8152602001876001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ac4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae89190612ba8565b8152602001876001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4f9190612ba8565b8152602001876001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb69190612ba8565b905290506000611bc589611d3f565b905060405180610200016040528060008152602001876001600160a01b03168152602001876001600160a01b0316815260200160006001600160a01b031681526020018a6001600160a01b0316815260200160006001600160a01b03168152602001600015158152602001886001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c929190612b8b565b6001600160a01b031681526020016000801b8152602001868152602001858152602001848152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1d9190612ba8565b8152600060208201526040810193909352606090920152979650505050505050565b606060008290506000816001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611daa9190612ba8565b90506000816001600160401b03811115611dc657611dc661241e565b604051908082528060200260200182016040528015611dff57816020015b611dec612239565b815260200190600190039081611de45790505b50905060005b82811015610d7757604051632061aa2360e11b8152600481018290526000906001600160a01b038616906340c3544690602401602060405180830381865afa158015611e55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e799190612b8b565b9050600081905060006040518060a00160405280836001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eef9190612ba8565b8152602001836001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f569190612ba8565b8152602001836001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fbd9190612ba8565b8152602001836001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612000573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120249190612ba8565b8152602001836001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208b9190612ba8565b81525090506040518060600160405280846001600160a01b03168152602001836001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210c9190612b8b565b6001600160a01b031681526020018281525085858151811061213057612130612c0b565b6020026020010181905250505050808061214990612cce565b915050611e05565b6040518061020001604052806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160001515815260200160006001600160a01b0316815260200160008019168152602001606081526020016060815260200160608152602001600081526020016000815260200161222c6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001606081525090565b604051806060016040528060006001600160a01b0316815260200160006001600160a01b031681526020016122966040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b905290565b6001600160a01b03811681146122b057600080fd5b50565b80356122be8161229b565b919050565b6000602082840312156122d557600080fd5b81356122e08161229b565b9392505050565b600081518084526020808501945080840160005b8381101561237057815180516001600160a01b0390811689528482015116848901526040908101519061235b818a018380518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b505060e09690960195908201906001016122fb565b509495945050505050565b60208152600060018060a01b03808451166020840152806020850151166040840152506040830151606083015260608301516080830152608083015160a083015260a083015160c0808401526123d460e08401826122e7565b949350505050565b6000806000606084860312156123f157600080fd5b8335925060208401356124038161229b565b915060408401356124138161229b565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156124565761245661241e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156124845761248461241e565b604052919050565b60006001600160401b038211156124a5576124a561241e565b5060051b60200190565b600060208083850312156124c257600080fd5b82356001600160401b038111156124d857600080fd5b8301601f810185136124e957600080fd5b80356124fc6124f78261248c565b61245c565b81815260059190911b8201830190838101908783111561251b57600080fd5b928401925b828410156125425783356125338161229b565b82529284019290840190612520565b979650505050505050565b60005b83811015612568578181015183820152602001612550565b83811115612577576000848401525b50505050565b6000815180845261259581602086016020860161254d565b601f01601f19169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561264557888303603f19018552815180516001600160a01b031684528781015160ff1688850152868101516080888601819052906126148287018261257d565b91505060608083015192508582038187015250612631818361257d565b9689019694505050908601906001016125d0565b509098975050505050505050565b60008060006060848603121561266857600080fd5b83356126738161229b565b92506020840135915060408401356124138161229b565b600081518084526020808501945080840160005b838110156123705781518752958201959082019060010161269e565b805182526020810151602083015260006040820151608060408501526126e3608085018261268a565b606093840151949093019390935250919050565b6020815260006122e060208301846126ba565b60008060006060848603121561271f57600080fd5b83356001600160401b0381111561273557600080fd5b8401601f8101861361274657600080fd5b803560206127566124f78361248c565b82815260059290921b8301810191818101908984111561277557600080fd5b938201935b838510156127935784358252938201939082019061277a565b96506127a290508782016122b3565b94505050506127b3604085016122b3565b90509250925092565b6020815260006122e0602083018461268a565b600081518084526020808501945080840160005b838110156123705781516001600160a01b0316875295820195908201906001016127e3565b600061028082518452602083015161282b60208601826001600160a01b03169052565b50604083015161284660408601826001600160a01b03169052565b50606083015161286160608601826001600160a01b03169052565b50608083015161287c60808601826001600160a01b03169052565b5060a083015161289760a08601826001600160a01b03169052565b5060c08301516128ab60c086018215159052565b5060e08301516128c660e08601826001600160a01b03169052565b506101008084015181860152506101208084015182828701526128eb8387018261268a565b92505050610140808401518583038287015261290783826127cf565b925050506101608084015185830382870152612923838261268a565b61018086810151908801526101a080870151908801526101c0808701518051828a015260208101516101e08a015260408101516102008a015260608101516102208a015260808101516102408a01529194509250905050506101e08301518482036102608601526105b882826122e7565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156129e957603f198886030184526129d7858351612808565b945092850192908501906001016129bb565b5092979650505050505050565b80151581146122b057600080fd5b60008082840360e0811215612a1857600080fd5b60c0811215612a2657600080fd5b50612a2f612434565b8335612a3a8161229b565b81526020840135612a4a8161229b565b60208201526040840135612a5d8161229b565b60408201526060840135612a708161229b565b60608201526080840135612a838161229b565b608082015260a0840135612a96816129f6565b60a08201529460c0939093013593505050565b6020815260006122e06020830184612808565b60008060408385031215612acf57600080fd5b8235612ada8161229b565b91506020830135612aea8161229b565b809150509250929050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156129e957603f19888603018452612b388583516126ba565b94509285019290850190600101612b1c565b6020815260018060a01b0382511660208201526020820151604082015260408201516060820152600060608301516080808401526123d460a084018261268a565b600060208284031215612b9d57600080fd5b81516122e08161229b565b600060208284031215612bba57600080fd5b5051919050565b600060208284031215612bd357600080fd5b81516122e0816129f6565b634e487b7160e01b600052601160045260246000fd5b600082821015612c0657612c06612bde565b500390565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612c3357600080fd5b815160ff811681146122e057600080fd5b600060208284031215612c5657600080fd5b81516001600160401b0380821115612c6d57600080fd5b818401915084601f830112612c8157600080fd5b815181811115612c9357612c9361241e565b612ca6601f8201601f191660200161245c565b9150808252856020828501011115612cbd57600080fd5b610d7781602084016020860161254d565b6000600019821415612ce257612ce2612bde565b5060010190565b600060c08284031215612cfb57600080fd5b60405160c081018181106001600160401b0382111715612d1d57612d1d61241e565b6040528251612d2b8161229b565b81526020830151612d3b8161229b565b60208201526040830151612d4e8161229b565b60408201526060830151612d618161229b565b60608201526080830151612d748161229b565b608082015260a0830151612d87816129f6565b60a08201529392505050565b600082601f830112612da457600080fd5b81516020612db46124f78361248c565b82815260059290921b84018101918181019086841115612dd357600080fd5b8286015b84811015612dee5780518352918301918301612dd7565b509695505050505050565b600080600060608486031215612e0e57600080fd5b83516001600160401b0380821115612e2557600080fd5b818601915086601f830112612e3957600080fd5b81516020612e496124f78361248c565b82815260059290921b8401810191818101908a841115612e6857600080fd5b948201945b83861015612e8f578551612e808161229b565b82529482019490820190612e6d565b91890151919750909350505080821115612ea857600080fd5b50612eb586828701612d93565b925050604084015190509250925092565b600060208284031215612ed857600080fd5b81516001600160401b03811115612eee57600080fd5b6123d484828501612d9356fea26469706673582212207cd163f6f7b9f3828ecdd70456149d48d52ddfd35ef8e0837b37ecf9f2a3632464736f6c634300080b0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80634cf4c36a116100715780634cf4c36a146101775780635c39f467146101975780637f5f53d1146101b75780639b9e0955146101d7578063c025d1a5146101f7578063eda242901461021757600080fd5b80630eb9af38146100ae578063158274a5146100d75780631fbf73ac14610116578063273a94aa146101375780633e3dcce814610157575b600080fd5b6100c16100bc3660046122c3565b61022a565b6040516100ce919061237b565b60405180910390f35b6100fe7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c881565b6040516001600160a01b0390911681526020016100ce565b6101296101243660046123dc565b610461565b6040519081526020016100ce565b61014a6101453660046124af565b6105c1565b6040516100ce91906125a9565b61016a610165366004612653565b610865565b6040516100ce91906126f7565b61018a61018536600461270a565b610b5a565b6040516100ce91906127bc565b6101aa6101a53660046122c3565b610c00565b6040516100ce9190612994565b6101ca6101c5366004612a04565b610d80565b6040516100ce9190612aa9565b6101ea6101e5366004612abc565b611351565b6040516100ce9190612af5565b61020a610205366004612abc565b6114eb565b6040516100ce9190612b4a565b6101ca6102253660046122c3565b6117f4565b6102756040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001606081525090565b60008290506000816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102de9190612b8b565b90506000826001600160a01b031663c70920bc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610320573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103449190612ba8565b90506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa9190612ba8565b90506000846001600160a01b031663a2468c196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104109190612ba8565b9050600061041d88611d3f565b6040805160c0810182526001600160a01b039a8b16815296909916602087015297850193909352606084019190915260808301525060a08101939093525090919050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038416906370a0823190602401602060405180830381865afa1580156104aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ce9190612ba8565b604051637979426b60e01b815260048101879052600060248201529091506001600160a01b03851690637979426b906044016020604051808303816000875af115801561051f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105439190612bc1565b506040516370a0823160e01b815230600482015281906001600160a01b038516906370a0823190602401602060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ae9190612ba8565b6105b89190612bf4565b95945050505050565b80516060906000816001600160401b038111156105e0576105e061241e565b60405190808252806020026020018201604052801561063457816020015b60408051608081018252600080825260208201526060918101829052818101919091528152602001906001900390816105fe5790505b50905060005b8281101561085d57600085828151811061065657610656612c0b565b6020026020010151905060008190506000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106c1575060408051601f3d908101601f191682019092526106be91810190612c21565b60015b6106cd57506000610733565b50816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561070c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107309190612c21565b90505b6040518060800160405280846001600160a01b031681526020018260ff168152602001836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610794573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107bc9190810190612c44565b8152602001836001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108279190810190612c44565b81525085858151811061083c5761083c612c0b565b6020026020010181905250505050808061085590612cce565b91505061063a565b509392505050565b6108906040518060800160405280600081526020016000815260200160608152602001600081525090565b6040516370a0823160e01b81526001600160a01b03838116600483015285916000918316906370a0823190602401602060405180830381865afa1580156108db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ff9190612ba8565b6040516246613160e11b81526001600160a01b038681166004830152919250600091841690628cc26290602401602060405180830381865afa158015610949573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096d9190612ba8565b90506000836001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d39190612ba8565b90506000816001600160401b038111156109ef576109ef61241e565b604051908082528060200260200182016040528015610a18578160200160208202803683370190505b50905060005b82811015610b2e57604051632061aa2360e11b8152600481018290526000906001600160a01b038816906340c3544690602401602060405180830381865afa158015610a6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a929190612b8b565b6040516246613160e11b81526001600160a01b038b8116600483015291925090821690628cc26290602401602060405180830381865afa158015610ada573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afe9190612ba8565b838381518110610b1057610b10612c0b565b60209081029190910101525080610b2681612cce565b915050610a1e565b506040805160808101825289815260208101949094528301525060608101919091529150509392505050565b606083516001600160401b03811115610b7557610b7561241e565b604051908082528060200260200182016040528015610b9e578160200160208202803683370190505b50905060005b845181101561085d57610bd1858281518110610bc257610bc2612c0b565b60200260200101518585610461565b828281518110610be357610be3612c0b565b602090810291909101015280610bf881612cce565b915050610ba4565b606060008290506000816001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6b9190612ba8565b90506000816001600160401b03811115610c8757610c8761241e565b604051908082528060200260200182016040528015610cc057816020015b610cad612151565b815260200190600190039081610ca55790505b50905060005b82811015610d7757604051631526fe2760e01b8152600481018290526000906001600160a01b03861690631526fe279060240160c060405180830381865afa158015610d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3a9190612ce9565b9050610d468183610d80565b838381518110610d5857610d58612c0b565b6020026020010181905250508080610d6f90612cce565b915050610cc6565b50949350505050565b610d88612151565b60008360600151905060008460000151905060006060806060846001600160a01b03166338fff2d06040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610dfb575060408051601f3d908101601f19168201909252610df891810190612ba8565b60015b610e2a575050604080516000808252602082018181528284018281526060840190945290945091925090610f43565b604051631f29a8cd60e31b81526004810182905290945084906001600160a01b037f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8169063f94d466890602401600060405180830381865afa158015610e94573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ebc9190810190612df9565b508093508194505050856001600160a01b031663f89f27ed6040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015610f2457506040513d6000823e601f3d908101601f19168201604052610f219190810190612ec6565b60015b610f3e576040805160008152602081019091529350610f41565b93505b505b6000610f528a60600151611d3f565b905060006040518060a00160405280896001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc39190612ba8565b8152602001896001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611006573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102a9190612ba8565b8152602001896001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561106d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110919190612ba8565b8152602001896001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f89190612ba8565b8152602001896001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561113b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115f9190612ba8565b81525090506040518061020001604052808b81526020018c600001516001600160a01b031681526020018c602001516001600160a01b031681526020018c604001516001600160a01b031681526020018c606001516001600160a01b031681526020018c608001516001600160a01b031681526020018c60a0015115158152602001896001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa15801561121f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112439190612b8b565b6001600160a01b03168152602001878152602001868152602001858152602001848152602001896001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb9190612ba8565b8152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561130e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113329190612ba8565b8152602001828152602001838152509850505050505050505092915050565b60606000836001600160a01b031663081e3eda6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611393573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b79190612ba8565b90506000816001600160401b038111156113d3576113d361241e565b60405190808252806020026020018201604052801561142f57816020015b61141c6040518060800160405280600081526020016000815260200160608152602001600081525090565b8152602001906001900390816113f15790505b50905060005b82811015610d7757604051631526fe2760e01b8152600481018290526000906001600160a01b03881690631526fe279060240160c060405180830381865afa158015611485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a99190612ce9565b90506114ba81606001518388610865565b8383815181106114cc576114cc612c0b565b60200260200101819052505080806114e390612cce565b915050611435565b61151f604051806080016040528060006001600160a01b031681526020016000815260200160008152602001606081525090565b6040516370a0823160e01b81526001600160a01b03838116600483015284916000918316906370a0823190602401602060405180830381865afa15801561156a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158e9190612ba8565b604051633af9e66960e01b81526001600160a01b038681166004830152919250600091841690633af9e66990602401602060405180830381865afa1580156115da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fe9190612ba8565b90506000836001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611640573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116649190612ba8565b90506000816001600160401b038111156116805761168061241e565b6040519080825280602002602001820160405280156116a9578160200160208202803683370190505b50905060005b828110156117bf57604051632061aa2360e11b8152600481018290526000906001600160a01b038816906340c3544690602401602060405180830381865afa1580156116ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117239190612b8b565b6040516246613160e11b81526001600160a01b038b8116600483015291925090821690628cc26290602401602060405180830381865afa15801561176b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178f9190612ba8565b8383815181106117a1576117a1612c0b565b602090810291909101015250806117b781612cce565b9150506116af565b50604080516080810182526001600160a01b039098168852602088019490945292860191909152506060840152509092915050565b6117fc612151565b60008290506000816001600160a01b03166372f702f36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118659190612b8b565b60408051600180825281830190925291925060009190602080830190803683370190505090506001816000815181106118a0576118a0612c0b565b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905082816000815181106118e3576118e3612c0b565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050506040516370a0823160e01b81526001600160a01b038981166004830152919250908516906370a0823190602401602060405180830381865afa158015611968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198c9190612ba8565b8160008151811061199f5761199f612c0b565b60200260200101818152505060006040518060a00160405280876001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1a9190612ba8565b8152602001876001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a819190612ba8565b8152602001876001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ac4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae89190612ba8565b8152602001876001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4f9190612ba8565b8152602001876001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bb69190612ba8565b905290506000611bc589611d3f565b905060405180610200016040528060008152602001876001600160a01b03168152602001876001600160a01b0316815260200160006001600160a01b031681526020018a6001600160a01b0316815260200160006001600160a01b03168152602001600015158152602001886001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c929190612b8b565b6001600160a01b031681526020016000801b8152602001868152602001858152602001848152602001886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1d9190612ba8565b8152600060208201526040810193909352606090920152979650505050505050565b606060008290506000816001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611daa9190612ba8565b90506000816001600160401b03811115611dc657611dc661241e565b604051908082528060200260200182016040528015611dff57816020015b611dec612239565b815260200190600190039081611de45790505b50905060005b82811015610d7757604051632061aa2360e11b8152600481018290526000906001600160a01b038616906340c3544690602401602060405180830381865afa158015611e55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e799190612b8b565b9050600081905060006040518060a00160405280836001600160a01b031663ebe2b12b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eef9190612ba8565b8152602001836001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f569190612ba8565b8152602001836001600160a01b0316637b0a47ee6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fbd9190612ba8565b8152602001836001600160a01b031663df136d656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612000573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120249190612ba8565b8152602001836001600160a01b03166363d38c3b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208b9190612ba8565b81525090506040518060600160405280846001600160a01b03168152602001836001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210c9190612b8b565b6001600160a01b031681526020018281525085858151811061213057612130612c0b565b6020026020010181905250505050808061214990612cce565b915050611e05565b6040518061020001604052806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160001515815260200160006001600160a01b0316815260200160008019168152602001606081526020016060815260200160608152602001600081526020016000815260200161222c6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8152602001606081525090565b604051806060016040528060006001600160a01b0316815260200160006001600160a01b031681526020016122966040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b905290565b6001600160a01b03811681146122b057600080fd5b50565b80356122be8161229b565b919050565b6000602082840312156122d557600080fd5b81356122e08161229b565b9392505050565b600081518084526020808501945080840160005b8381101561237057815180516001600160a01b0390811689528482015116848901526040908101519061235b818a018380518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b505060e09690960195908201906001016122fb565b509495945050505050565b60208152600060018060a01b03808451166020840152806020850151166040840152506040830151606083015260608301516080830152608083015160a083015260a083015160c0808401526123d460e08401826122e7565b949350505050565b6000806000606084860312156123f157600080fd5b8335925060208401356124038161229b565b915060408401356124138161229b565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156124565761245661241e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156124845761248461241e565b604052919050565b60006001600160401b038211156124a5576124a561241e565b5060051b60200190565b600060208083850312156124c257600080fd5b82356001600160401b038111156124d857600080fd5b8301601f810185136124e957600080fd5b80356124fc6124f78261248c565b61245c565b81815260059190911b8201830190838101908783111561251b57600080fd5b928401925b828410156125425783356125338161229b565b82529284019290840190612520565b979650505050505050565b60005b83811015612568578181015183820152602001612550565b83811115612577576000848401525b50505050565b6000815180845261259581602086016020860161254d565b601f01601f19169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561264557888303603f19018552815180516001600160a01b031684528781015160ff1688850152868101516080888601819052906126148287018261257d565b91505060608083015192508582038187015250612631818361257d565b9689019694505050908601906001016125d0565b509098975050505050505050565b60008060006060848603121561266857600080fd5b83356126738161229b565b92506020840135915060408401356124138161229b565b600081518084526020808501945080840160005b838110156123705781518752958201959082019060010161269e565b805182526020810151602083015260006040820151608060408501526126e3608085018261268a565b606093840151949093019390935250919050565b6020815260006122e060208301846126ba565b60008060006060848603121561271f57600080fd5b83356001600160401b0381111561273557600080fd5b8401601f8101861361274657600080fd5b803560206127566124f78361248c565b82815260059290921b8301810191818101908984111561277557600080fd5b938201935b838510156127935784358252938201939082019061277a565b96506127a290508782016122b3565b94505050506127b3604085016122b3565b90509250925092565b6020815260006122e0602083018461268a565b600081518084526020808501945080840160005b838110156123705781516001600160a01b0316875295820195908201906001016127e3565b600061028082518452602083015161282b60208601826001600160a01b03169052565b50604083015161284660408601826001600160a01b03169052565b50606083015161286160608601826001600160a01b03169052565b50608083015161287c60808601826001600160a01b03169052565b5060a083015161289760a08601826001600160a01b03169052565b5060c08301516128ab60c086018215159052565b5060e08301516128c660e08601826001600160a01b03169052565b506101008084015181860152506101208084015182828701526128eb8387018261268a565b92505050610140808401518583038287015261290783826127cf565b925050506101608084015185830382870152612923838261268a565b61018086810151908801526101a080870151908801526101c0808701518051828a015260208101516101e08a015260408101516102008a015260608101516102208a015260808101516102408a01529194509250905050506101e08301518482036102608601526105b882826122e7565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156129e957603f198886030184526129d7858351612808565b945092850192908501906001016129bb565b5092979650505050505050565b80151581146122b057600080fd5b60008082840360e0811215612a1857600080fd5b60c0811215612a2657600080fd5b50612a2f612434565b8335612a3a8161229b565b81526020840135612a4a8161229b565b60208201526040840135612a5d8161229b565b60408201526060840135612a708161229b565b60608201526080840135612a838161229b565b608082015260a0840135612a96816129f6565b60a08201529460c0939093013593505050565b6020815260006122e06020830184612808565b60008060408385031215612acf57600080fd5b8235612ada8161229b565b91506020830135612aea8161229b565b809150509250929050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156129e957603f19888603018452612b388583516126ba565b94509285019290850190600101612b1c565b6020815260018060a01b0382511660208201526020820151604082015260408201516060820152600060608301516080808401526123d460a084018261268a565b600060208284031215612b9d57600080fd5b81516122e08161229b565b600060208284031215612bba57600080fd5b5051919050565b600060208284031215612bd357600080fd5b81516122e0816129f6565b634e487b7160e01b600052601160045260246000fd5b600082821015612c0657612c06612bde565b500390565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612c3357600080fd5b815160ff811681146122e057600080fd5b600060208284031215612c5657600080fd5b81516001600160401b0380821115612c6d57600080fd5b818401915084601f830112612c8157600080fd5b815181811115612c9357612c9361241e565b612ca6601f8201601f191660200161245c565b9150808252856020828501011115612cbd57600080fd5b610d7781602084016020860161254d565b6000600019821415612ce257612ce2612bde565b5060010190565b600060c08284031215612cfb57600080fd5b60405160c081018181106001600160401b0382111715612d1d57612d1d61241e565b6040528251612d2b8161229b565b81526020830151612d3b8161229b565b60208201526040830151612d4e8161229b565b60408201526060830151612d618161229b565b60608201526080830151612d748161229b565b608082015260a0830151612d87816129f6565b60a08201529392505050565b600082601f830112612da457600080fd5b81516020612db46124f78361248c565b82815260059290921b84018101918181019086841115612dd357600080fd5b8286015b84811015612dee5780518352918301918301612dd7565b509695505050505050565b600080600060608486031215612e0e57600080fd5b83516001600160401b0380821115612e2557600080fd5b818601915086601f830112612e3957600080fd5b81516020612e496124f78361248c565b82815260059290921b8401810191818101908a841115612e6857600080fd5b948201945b83861015612e8f578551612e808161229b565b82529482019490820190612e6d565b91890151919750909350505080821115612ea857600080fd5b50612eb586828701612d93565b925050604084015190509250925092565b600060208284031215612ed857600080fd5b81516001600160401b03811115612eee57600080fd5b6123d484828501612d9356fea26469706673582212207cd163f6f7b9f3828ecdd70456149d48d52ddfd35ef8e0837b37ecf9f2a3632464736f6c634300080b0033
Deployed Bytecode Sourcemap
69642:11833:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71258:752;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69678:106;;;;;;;;-1:-1:-1;;;;;2630:32:1;;;2612:51;;2600:2;2585:18;69678:106:0;2443:226:1;80732:363:0;;;;;;:::i;:::-;;:::i;:::-;;;3281:25:1;;;3269:2;3254:18;80732:363:0;3135:177:1;80048:676:0;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;79217:823::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;81103:369::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;73005:457::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;76301:2387::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;78696:513::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;72018:979::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;73470:1639::-;;;;;;:::i;:::-;;:::i;71258:752::-;71315:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71315:18:0;71346:26;71389:6;71346:50;;71409:18;71430:12;-1:-1:-1;;;;;71430:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71409:46;;71466:23;71492:12;-1:-1:-1;;;;;71492:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71466:56;;71533:19;71555:12;-1:-1:-1;;;;;71555:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71533:48;;71592:23;71618:12;-1:-1:-1;;;;;71618:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71592:58;;71663:34;71700:23;71716:6;71700:15;:23::i;:::-;71744:258;;;;;;;;-1:-1:-1;;;;;71744:258:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71744:258:0;;;;;;;-1:-1:-1;71744:258:0;;71258:752;-1:-1:-1;71258:752:0:o;80732:363::-;80901:46;;-1:-1:-1;;;80901:46:0;;80941:4;80901:46;;;2612:51:1;80857:15:0;;;;-1:-1:-1;;;;;80901:31:0;;;;;2585:18:1;;80901:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80958:54;;-1:-1:-1;;;80958:54:0;;;;;17595:25:1;;;81009:1:0;17636:18:1;;;17629:60;80885:62:0;;-1:-1:-1;;;;;;80958:36:0;;;;;17568:18:1;;80958:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;81033:46:0;;-1:-1:-1;;;81033:46:0;;81073:4;81033:46;;;2612:51:1;81082:5:0;;-1:-1:-1;;;;;81033:31:0;;;;;2585:18:1;;81033:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;;;:::i;:::-;81023:64;80732:363;-1:-1:-1;;;;;80732:363:0:o;80048:676::-;80161:17;;80117:14;;80144;80161:17;-1:-1:-1;;;;;80213:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80213:19:0;;;;;;;;;;;;;;;;80189:43;;80250:9;80245:446;80269:6;80265:1;:10;80245:446;;;80297:12;80312:10;80323:1;80312:13;;;;;;;;:::i;:::-;;;;;;;80297:28;;80340:20;80378:4;80340:43;;80400:14;80433:5;-1:-1:-1;;;;;80433:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80433:16:0;;;;;;;;-1:-1:-1;;80433:16:0;;;;;;;;;;;;:::i;:::-;;;80429:137;;-1:-1:-1;80549:1:0;80429:137;;;;80480:5;-1:-1:-1;;;;;80480:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80469:27;;80429:137;80594:85;;;;;;;;80608:4;-1:-1:-1;;;;;80594:85:0;;;;;80624:8;80594:85;;;;;;80642:5;-1:-1:-1;;;;;80642:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;80642:14:0;;;;;;;;;;;;:::i;:::-;80594:85;;;;80664:5;-1:-1:-1;;;;;80664:10:0;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;80664:12:0;;;;;;;;;;;;:::i;:::-;80594:85;;;80582:6;80589:1;80582:9;;;;;;;;:::i;:::-;;;;;;:97;;;;80282:409;;;80277:3;;;;;:::i;:::-;;;;80245:446;;;-1:-1:-1;80710:6:0;80048:676;-1:-1:-1;;;80048:676:0:o;79217:823::-;79350:19;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79350:19:0;79461:24;;-1:-1:-1;;;79461:24:0;;-1:-1:-1;;;;;2630:32:1;;;79461:24:0;;;2612:51:1;79421:11:0;;79382:20;;79461:14;;;;;2585:18:1;;79461:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79513:21;;-1:-1:-1;;;79513:21:0;;-1:-1:-1;;;;;2630:32:1;;;79513:21:0;;;2612:51:1;79444:41:0;;-1:-1:-1;79496:14:0;;79513:11;;;;;2585:18:1;;79513:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79496:38;;79547:26;79576:4;-1:-1:-1;;;;;79576:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79547:54;;79612:35;79664:18;-1:-1:-1;;;;;79650:33:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79650:33:0;;79612:71;;79699:9;79694:220;79718:18;79714:1;:22;79694:220;;;79809:20;;-1:-1:-1;;;79809:20:0;;;;;3281:25:1;;;79758:32:0;;-1:-1:-1;;;;;79809:17:0;;;;;3254:18:1;;79809:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79869:33;;-1:-1:-1;;;79869:33:0;;-1:-1:-1;;;;;2630:32:1;;;79869:33:0;;;2612:51:1;79758:72:0;;-1:-1:-1;79869:23:0;;;;;;2585:18:1;;79869:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79845:18;79864:1;79845:21;;;;;;;;:::i;:::-;;;;;;;;;;:57;-1:-1:-1;79738:3:0;;;;:::i;:::-;;;;79694:220;;;-1:-1:-1;79933:99:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79933:99:0;;;;;;;;-1:-1:-1;;79217:823:0;;;;;:::o;81103:369::-;81249:25;81312:5;:12;-1:-1:-1;;;;;81298:27:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81298:27:0;;81287:38;;81341:9;81336:129;81360:5;:12;81356:1;:16;81336:129;;;81408:45;81428:5;81434:1;81428:8;;;;;;;;:::i;:::-;;;;;;;81438:7;81447:5;81408:19;:45::i;:::-;81394:8;81403:1;81394:11;;;;;;;;:::i;:::-;;;;;;;;;;:59;81374:3;;;;:::i;:::-;;;;81336:129;;73005:457;73064:13;73090:20;73126:8;73090:45;;73148:18;73169:7;-1:-1:-1;;;;;73169:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73148:41;;73200:19;73233:10;-1:-1:-1;;;;;73222:22:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;73200:44;;73262:9;73257:173;73281:10;73277:1;:14;73257:173;;;73353:19;;-1:-1:-1;;;73353:19:0;;;;;3281:25:1;;;73313:37:0;;-1:-1:-1;;;;;73353:16:0;;;;;3254:18:1;;73353:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73313:59;;73398:20;73406:8;73416:1;73398:7;:20::i;:::-;73387:5;73393:1;73387:8;;;;;;;;:::i;:::-;;;;;;:31;;;;73298:132;73293:3;;;;;:::i;:::-;;;;73257:173;;;-1:-1:-1;73449:5:0;73005:457;-1:-1:-1;;;;73005:457:0:o;76301:2387::-;76392:11;;:::i;:::-;76416:26;76461:8;:19;;;76416:65;;76492:26;76535:8;:16;;;76492:60;;76704:14;76729:34;76774:27;76812;76856:12;-1:-1:-1;;;;;76856:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76856:24:0;;;;;;;;-1:-1:-1;;76856:24:0;;;;;;;;;;;;:::i;:::-;;;76852:612;;-1:-1:-1;;77341:16:0;;;77311:1;77341:16;;;;;;77385;;;;;;77436;;;;;;;;;77311:1;;-1:-1:-1;77385:16:0;;-1:-1:-1;77341:16:0;76852:612;;;76994:35;;-1:-1:-1;;;76994:35:0;;;;;3281:25:1;;;76937:13:0;;-1:-1:-1;76937:13:0;;-1:-1:-1;;;;;76994:13:0;:27;;;;3254:18:1;;76994:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;76994:35:0;;;;;;;;;;;;:::i;:::-;76965:64;;;;;;;;;77050:12;-1:-1:-1;;;;;77050:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;77050:35:0;;;;;;;;;;;;:::i;:::-;;;77046:215;;77229:16;;;77243:1;77229:16;;;;;;;;;-1:-1:-1;77046:215:0;;;77160:7;-1:-1:-1;77046:215:0;76881:391;76852:612;77476:34;77513:36;77529:8;:19;;;77513:15;:36::i;:::-;77476:73;;77562:30;77595:312;;;;;;;;77686:10;-1:-1:-1;;;;;77686:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77595:312;;;;77742:10;-1:-1:-1;;;;;77742:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77595:312;;;;77634:10;-1:-1:-1;;;;;77634:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77595:312;;;;77806:10;-1:-1:-1;;;;;77806:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77595:312;;;;77869:10;-1:-1:-1;;;;;77869:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77595:312;;;77562:345;;77940:740;;;;;;;;77969:4;77940:740;;;;78001:8;:16;;;-1:-1:-1;;;;;77940:740:0;;;;;78043:8;:14;;;-1:-1:-1;;;;;77940:740:0;;;;;78083:8;:14;;;-1:-1:-1;;;;;77940:740:0;;;;;78128:8;:19;;;-1:-1:-1;;;;;77940:740:0;;;;;78173:8;:14;;;-1:-1:-1;;;;;77940:740:0;;;;;78216:8;:17;;;77940:740;;;;;;78265:10;-1:-1:-1;;;;;78265:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;77940:740:0;;;;;78316:6;77940:740;;;;78360:17;77940:740;;;;78408:10;77940:740;;;;78449:10;77940:740;;;;78579:10;-1:-1:-1;;;;;78579:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77940:740;;;;78638:12;-1:-1:-1;;;;;78638:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77940:740;;;;78491:11;77940:740;;;;78535:12;77940:740;;;77920:760;;;;;;;;;;76301:2387;;;;:::o;78696:513::-;78781:21;78815:18;78849:8;-1:-1:-1;;;;;78836:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78815:56;;78882:30;78934:10;-1:-1:-1;;;;;78915:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78915:30:0;;;;;;;;;;;;;;;;;78882:63;;78961:9;78956:220;78980:10;78976:1;:14;78956:220;;;79052:34;;-1:-1:-1;;;79052:34:0;;;;;3281:25:1;;;79012:37:0;;-1:-1:-1;;;;;79052:31:0;;;;;3254:18:1;;79052:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79012:74;;79115:49;79131:8;:19;;;79152:1;79155:8;79115:15;:49::i;:::-;79101:8;79110:1;79101:11;;;;;;;;:::i;:::-;;;;;;:63;;;;78997:179;78992:3;;;;;:::i;:::-;;;;78956:220;;72018:979;72127:32;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72127:32:0;72258;;-1:-1:-1;;;72258:32:0;;-1:-1:-1;;;;;2630:32:1;;;72258::0;;;2612:51:1;72220:6:0;;72177:26;;72258:22;;;;;2585:18:1;;72258:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72331:42;;-1:-1:-1;;;72331:42:0;;-1:-1:-1;;;;;2630:32:1;;;72331:42:0;;;2612:51:1;72240:50:0;;-1:-1:-1;72301:27:0;;72331:32;;;;;2585:18:1;;72331:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72301:72;;72386:26;72415:12;-1:-1:-1;;;;;72415:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72386:62;;72459:35;72511:18;-1:-1:-1;;;;;72497:33:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72497:33:0;;72459:71;;72546:9;72541:228;72565:18;72561:1;:22;72541:228;;;72656:28;;-1:-1:-1;;;72656:28:0;;;;;3281:25:1;;;72605:32:0;;-1:-1:-1;;;;;72656:25:0;;;;;3254:18:1;;72656:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72724:33;;-1:-1:-1;;;72724:33:0;;-1:-1:-1;;;;;2630:32:1;;;72724:33:0;;;2612:51:1;72605:80:0;;-1:-1:-1;72724:23:0;;;;;;2585:18:1;;72724:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72700:18;72719:1;72700:21;;;;;;;;:::i;:::-;;;;;;;;;;:57;-1:-1:-1;72585:3:0;;;;:::i;:::-;;;;72541:228;;;-1:-1:-1;72796:193:0;;;;;;;;-1:-1:-1;;;;;72796:193:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;72796:193:0;;;;-1:-1:-1;72796:193:0;;72018:979;-1:-1:-1;;72018:979:0:o;73470:1639::-;73541:11;;:::i;:::-;73565:20;73604:14;73565:54;;73630:14;73647:4;-1:-1:-1;;;;;73647:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73716:16;;;73730:1;73716:16;;;;;;;;;73630:36;;-1:-1:-1;73679:34:0;;73716:16;;;;;;;;;;;;-1:-1:-1;73716:16:0;73679:53;;73766:1;73743:17;73761:1;73743:20;;;;;;;;:::i;:::-;;;;;;;;;;:24;73808:16;;;73822:1;73808:16;;;;;;;;;73778:27;;73808:16;;;;;;;;;;;;-1:-1:-1;73808:16:0;73778:46;;73851:6;73835:10;73846:1;73835:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;73835:22:0;;;;:13;;;;;;;;;;;:22;73898:16;;;73912:1;73898:16;;;;;;;;;73868:27;;73898:16;;;;;;;;;;;;-1:-1:-1;;73941:48:0;;-1:-1:-1;;;73941:48:0;;-1:-1:-1;;;;;2630:32:1;;;73941:48:0;;;2612:51:1;73868:46:0;;-1:-1:-1;73941:32:0;;;;;;2585:18:1;;73941:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73925:10;73936:1;73925:13;;;;;;;;:::i;:::-;;;;;;:64;;;;;74002:30;74035:282;;;;;;;;74120:4;-1:-1:-1;;;;;74120:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74035:282;;;;74170:4;-1:-1:-1;;;;;74170:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74035:282;;;;74074:4;-1:-1:-1;;;;;74074:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74035:282;;;;74228:4;-1:-1:-1;;;;;74228:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74035:282;;;;74285:4;-1:-1:-1;;;;;74285:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74035:282;;74002:315;-1:-1:-1;74330:34:0;74367:31;74383:14;74367:15;:31::i;:::-;74330:68;;74431:670;;;;;;;;74468:1;74431:670;;;;74498:6;-1:-1:-1;;;;;74431:670:0;;;;;74530:6;-1:-1:-1;;;;;74431:670:0;;;;;74570:1;-1:-1:-1;;;;;74431:670:0;;;;;74603:14;-1:-1:-1;;;;;74431:670:0;;;;;74651:1;-1:-1:-1;;;;;74431:670:0;;;;;74682:5;74431:670;;;;;;74719:4;-1:-1:-1;;;;;74719:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;74431:670:0;;;;;74772:1;74764:10;;74431:670;;;;74812:17;74431:670;;;;74860:10;74431:670;;;;74901:10;74431:670;;;;75031:4;-1:-1:-1;;;;;75031:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74431:670;;75084:1;74431:670;;;;;;;;;;;;;;;;74411:690;73470:1639;-1:-1:-1;;;;;;;73470:1639:0:o;75117:1176::-;75190:21;75224:30;75273:15;75224:65;;75302:26;75331:14;-1:-1:-1;;;;;75331:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75302:64;;75377:34;75433:18;-1:-1:-1;;;;;75414:38:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;75377:75;;75470:9;75465:789;75489:18;75485:1;:22;75465:789;;;75544:30;;-1:-1:-1;;;75544:30:0;;;;;3281:25:1;;;75529:12:0;;-1:-1:-1;;;;;75544:27:0;;;;;3254:18:1;;75544:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75529:45;;75589:32;75640:4;75589:56;;75660:23;75686:366;;;;;;;;75791:16;-1:-1:-1;;;;;75791:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75686:366;;;;75857:16;-1:-1:-1;;;;;75857:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75686:366;;;;75729:16;-1:-1:-1;;;;;75729:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75686:366;;;;75931:16;-1:-1:-1;;;;;75931:37:0;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75686:366;;;;76004:16;-1:-1:-1;;;;;76004:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75686:366;;;75660:392;;76085:157;;;;;;;;76123:4;-1:-1:-1;;;;;76085:157:0;;;;;76196:16;-1:-1:-1;;;;;76196:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;76085:157:0;;;;;76159:4;76085:157;;;76067:12;76080:1;76067:15;;;;;;;;:::i;:::-;;;;;;:175;;;;75514:740;;;75509:3;;;;;:::i;:::-;;;;75465:789;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;69:70;14:131;:::o;150:134::-;218:20;;247:31;218:20;247:31;:::i;:::-;150:134;;;:::o;289:247::-;348:6;401:2;389:9;380:7;376:23;372:32;369:52;;;417:1;414;407:12;369:52;456:9;443:23;475:31;500:5;475:31;:::i;:::-;525:5;289:247;-1:-1:-1;;;289:247:1:o;975:742::-;1040:3;1078:5;1072:12;1105:6;1100:3;1093:19;1131:4;1160:2;1155:3;1151:12;1144:19;;1197:2;1190:5;1186:14;1218:1;1228:464;1242:6;1239:1;1236:13;1228:464;;;1301:13;;1385:9;;-1:-1:-1;;;;;1381:18:1;;;1369:31;;1444:11;;;1438:18;1434:27;1420:12;;;1413:49;1485:4;1528:11;;;1522:18;;1553:57;1597:12;;;1522:18;733:5;727:12;722:3;715:25;789:4;782:5;778:16;772:23;765:4;760:3;756:14;749:47;845:4;838:5;834:16;828:23;821:4;816:3;812:14;805:47;901:4;894:5;890:16;884:23;877:4;872:3;868:14;861:47;957:4;950:5;946:16;940:23;933:4;928:3;924:14;917:47;;;650:320;1553:57;-1:-1:-1;;1639:4:1;1630:14;;;;;1667:15;;;;1264:1;1257:9;1228:464;;;-1:-1:-1;1708:3:1;;975:742;-1:-1:-1;;;;;975:742:1:o;1722:716::-;1897:2;1886:9;1879:21;1860:4;1936:1;1932;1927:3;1923:11;1919:19;1993:2;1984:6;1978:13;1974:22;1969:2;1958:9;1954:18;1947:50;2061:2;2055;2047:6;2043:15;2037:22;2033:31;2028:2;2017:9;2013:18;2006:59;;2119:2;2111:6;2107:15;2101:22;2096:2;2085:9;2081:18;2074:50;2179:2;2171:6;2167:15;2161:22;2155:3;2144:9;2140:19;2133:51;2239:3;2231:6;2227:16;2221:23;2215:3;2204:9;2200:19;2193:52;2292:3;2284:6;2280:16;2274:23;2335:4;2328;2317:9;2313:20;2306:34;2357:75;2427:3;2416:9;2412:19;2398:12;2357:75;:::i;:::-;2349:83;1722:716;-1:-1:-1;;;;1722:716:1:o;2674:456::-;2751:6;2759;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;-1:-1:-1;3052:2:1;3037:18;;3024:32;3065:33;3024:32;3065:33;:::i;:::-;3117:7;3107:17;;;2674:456;;;;;:::o;3317:127::-;3378:10;3373:3;3369:20;3366:1;3359:31;3409:4;3406:1;3399:15;3433:4;3430:1;3423:15;3449:253;3521:2;3515:9;3563:4;3551:17;;-1:-1:-1;;;;;3583:34:1;;3619:22;;;3580:62;3577:88;;;3645:18;;:::i;:::-;3681:2;3674:22;3449:253;:::o;3707:275::-;3778:2;3772:9;3843:2;3824:13;;-1:-1:-1;;3820:27:1;3808:40;;-1:-1:-1;;;;;3863:34:1;;3899:22;;;3860:62;3857:88;;;3925:18;;:::i;:::-;3961:2;3954:22;3707:275;;-1:-1:-1;3707:275:1:o;3987:183::-;4047:4;-1:-1:-1;;;;;4072:6:1;4069:30;4066:56;;;4102:18;;:::i;:::-;-1:-1:-1;4147:1:1;4143:14;4159:4;4139:25;;3987:183::o;4175:966::-;4259:6;4290:2;4333;4321:9;4312:7;4308:23;4304:32;4301:52;;;4349:1;4346;4339:12;4301:52;4389:9;4376:23;-1:-1:-1;;;;;4414:6:1;4411:30;4408:50;;;4454:1;4451;4444:12;4408:50;4477:22;;4530:4;4522:13;;4518:27;-1:-1:-1;4508:55:1;;4559:1;4556;4549:12;4508:55;4595:2;4582:16;4618:60;4634:43;4674:2;4634:43;:::i;:::-;4618:60;:::i;:::-;4712:15;;;4794:1;4790:10;;;;4782:19;;4778:28;;;4743:12;;;;4818:19;;;4815:39;;;4850:1;4847;4840:12;4815:39;4874:11;;;;4894:217;4910:6;4905:3;4902:15;4894:217;;;4990:3;4977:17;5007:31;5032:5;5007:31;:::i;:::-;5051:18;;4927:12;;;;5089;;;;4894:217;;;5130:5;4175:966;-1:-1:-1;;;;;;;4175:966:1:o;5146:258::-;5218:1;5228:113;5242:6;5239:1;5236:13;5228:113;;;5318:11;;;5312:18;5299:11;;;5292:39;5264:2;5257:10;5228:113;;;5359:6;5356:1;5353:13;5350:48;;;5394:1;5385:6;5380:3;5376:16;5369:27;5350:48;;5146:258;;;:::o;5409:::-;5451:3;5489:5;5483:12;5516:6;5511:3;5504:19;5532:63;5588:6;5581:4;5576:3;5572:14;5565:4;5558:5;5554:16;5532:63;:::i;:::-;5649:2;5628:15;-1:-1:-1;;5624:29:1;5615:39;;;;5656:4;5611:50;;5409:258;-1:-1:-1;;5409:258:1:o;5672:1348::-;5860:4;5889:2;5929;5918:9;5914:18;5959:2;5948:9;5941:21;5982:6;6017;6011:13;6048:6;6040;6033:22;6074:2;6064:12;;6107:2;6096:9;6092:18;6085:25;;6169:2;6159:6;6156:1;6152:14;6141:9;6137:30;6133:39;6207:2;6199:6;6195:15;6228:1;6238:753;6252:6;6249:1;6246:13;6238:753;;;6317:22;;;-1:-1:-1;;6313:36:1;6301:49;;6373:13;;6445:9;;-1:-1:-1;;;;;6441:35:1;6426:51;;6524:11;;;6518:18;6538:4;6514:29;6497:15;;;6490:54;6583:11;;;6577:18;6409:4;6615:15;;;6608:27;;;6409:4;6662:48;6694:15;;;6577:18;6662:48;:::i;:::-;6648:62;;;6733:4;6786:2;6782;6778:11;6772:18;6750:40;;6839:6;6831;6827:19;6822:2;6814:6;6810:15;6803:44;;6870:41;6904:6;6888:14;6870:41;:::i;:::-;6969:12;;;;6860:51;-1:-1:-1;;;6934:15:1;;;;6274:1;6267:9;6238:753;;;-1:-1:-1;7008:6:1;;5672:1348;-1:-1:-1;;;;;;;;5672:1348:1:o;7025:456::-;7102:6;7110;7118;7171:2;7159:9;7150:7;7146:23;7142:32;7139:52;;;7187:1;7184;7177:12;7139:52;7226:9;7213:23;7245:31;7270:5;7245:31;:::i;:::-;7295:5;-1:-1:-1;7347:2:1;7332:18;;7319:32;;-1:-1:-1;7403:2:1;7388:18;;7375:32;7416:33;7375:32;7416:33;:::i;7486:435::-;7539:3;7577:5;7571:12;7604:6;7599:3;7592:19;7630:4;7659:2;7654:3;7650:12;7643:19;;7696:2;7689:5;7685:14;7717:1;7727:169;7741:6;7738:1;7735:13;7727:169;;;7802:13;;7790:26;;7836:12;;;;7871:15;;;;7763:1;7756:9;7727:169;;7926:404;8017:5;8011:12;8006:3;7999:25;8073:4;8066:5;8062:16;8056:23;8049:4;8044:3;8040:14;8033:47;7981:3;8126:4;8119:5;8115:16;8109:23;8164:4;8157;8152:3;8148:14;8141:28;8190:58;8242:4;8237:3;8233:14;8219:12;8190:58;:::i;:::-;8297:4;8286:16;;;8280:23;8264:14;;;;8257:47;;;;-1:-1:-1;8178:70:1;7926:404;-1:-1:-1;7926:404:1:o;8335:273::-;8524:2;8513:9;8506:21;8487:4;8544:58;8598:2;8587:9;8583:18;8575:6;8544:58;:::i;8613:1041::-;8715:6;8723;8731;8784:2;8772:9;8763:7;8759:23;8755:32;8752:52;;;8800:1;8797;8790:12;8752:52;8840:9;8827:23;-1:-1:-1;;;;;8865:6:1;8862:30;8859:50;;;8905:1;8902;8895:12;8859:50;8928:22;;8981:4;8973:13;;8969:27;-1:-1:-1;8959:55:1;;9010:1;9007;9000:12;8959:55;9046:2;9033:16;9068:4;9092:60;9108:43;9148:2;9108:43;:::i;9092:60::-;9186:15;;;9268:1;9264:10;;;;9256:19;;9252:28;;;9217:12;;;;9292:19;;;9289:39;;;9324:1;9321;9314:12;9289:39;9348:11;;;;9368:142;9384:6;9379:3;9376:15;9368:142;;;9450:17;;9438:30;;9401:12;;;;9488;;;;9368:142;;;9529:5;-1:-1:-1;9553:38:1;;-1:-1:-1;9572:18:1;;;9553:38;:::i;:::-;9543:48;;;;;9610:38;9644:2;9633:9;9629:18;9610:38;:::i;:::-;9600:48;;8613:1041;;;;;:::o;9659:261::-;9838:2;9827:9;9820:21;9801:4;9858:56;9910:2;9899:9;9895:18;9887:6;9858:56;:::i;10021:461::-;10074:3;10112:5;10106:12;10139:6;10134:3;10127:19;10165:4;10194:2;10189:3;10185:12;10178:19;;10231:2;10224:5;10220:14;10252:1;10262:195;10276:6;10273:1;10270:13;10262:195;;;10341:13;;-1:-1:-1;;;;;10337:39:1;10325:52;;10397:12;;;;10432:15;;;;10373:1;10291:9;10262:195;;10487:2055;10534:3;10562:6;10595:5;10589:12;10584:3;10577:25;10648:4;10641:5;10637:16;10631:23;10663:48;10705:4;10700:3;10696:14;10682:12;-1:-1:-1;;;;;607:31:1;595:44;;541:104;10663:48;;10759:4;10752:5;10748:16;10742:23;10774:50;10818:4;10813:3;10809:14;10793;-1:-1:-1;;;;;607:31:1;595:44;;541:104;10774:50;;10872:4;10865:5;10861:16;10855:23;10887:50;10931:4;10926:3;10922:14;10906;-1:-1:-1;;;;;607:31:1;595:44;;541:104;10887:50;;10985:4;10978:5;10974:16;10968:23;11000:50;11044:4;11039:3;11035:14;11019;-1:-1:-1;;;;;607:31:1;595:44;;541:104;11000:50;;11098:4;11091:5;11087:16;11081:23;11113:50;11157:4;11152:3;11148:14;11132;-1:-1:-1;;;;;607:31:1;595:44;;541:104;11113:50;;11211:4;11204:5;11200:16;11194:23;11226:47;11267:4;11262:3;11258:14;11242;9995:13;9988:21;9976:34;;9925:91;11226:47;;11321:4;11314:5;11310:16;11304:23;11336:50;11380:4;11375:3;11371:14;11355;-1:-1:-1;;;;;607:31:1;595:44;;541:104;11336:50;;11405:6;11458:2;11451:5;11447:14;11441:21;11436:2;11431:3;11427:12;11420:43;;11482:6;11536:2;11529:5;11525:14;11519:21;11570:2;11565;11560:3;11556:12;11549:24;11594:58;11648:2;11643:3;11639:12;11623:14;11594:58;:::i;:::-;11582:70;;;;11671:6;11725:2;11718:5;11714:14;11708:21;11769:3;11763:4;11759:14;11754:2;11749:3;11745:12;11738:36;11797:50;11842:4;11826:14;11797:50;:::i;:::-;11783:64;;;;11866:6;11920:2;11913:5;11909:14;11903:21;11966:3;11958:6;11954:16;11949:2;11944:3;11940:12;11933:38;11994:52;12039:6;12023:14;11994:52;:::i;:::-;12065:6;12107:14;;;12101:21;12087:12;;;12080:43;12142:6;12184:14;;;12178:21;12164:12;;;12157:43;12219:6;12263:14;;;12257:21;727:12;;12334;;;715:25;789:4;778:16;;772:23;756:14;;;749:47;845:4;834:16;;828:23;812:14;;;805:47;901:4;890:16;;884:23;868:14;;;861:47;957:4;946:16;;940:23;924:14;;;917:47;11980:66;;-1:-1:-1;12219:6:1;-1:-1:-1;12257:21:1;-1:-1:-1;12287:60:1;;12396:6;12389:5;12385:18;12379:25;12450:3;12442:6;12438:16;12429:6;12424:3;12420:16;12413:42;12471:65;12529:6;12512:15;12471:65;:::i;12547:832::-;12733:4;12762:2;12802;12791:9;12787:18;12832:2;12821:9;12814:21;12855:6;12890;12884:13;12921:6;12913;12906:22;12959:2;12948:9;12944:18;12937:25;;13021:2;13011:6;13008:1;13004:14;12993:9;12989:30;12985:39;12971:53;;13059:2;13051:6;13047:15;13080:1;13090:260;13104:6;13101:1;13098:13;13090:260;;;13197:2;13193:7;13181:9;13173:6;13169:22;13165:36;13160:3;13153:49;13225:45;13263:6;13254;13248:13;13225:45;:::i;:::-;13215:55;-1:-1:-1;13328:12:1;;;;13293:15;;;;13126:1;13119:9;13090:260;;;-1:-1:-1;13367:6:1;;12547:832;-1:-1:-1;;;;;;;12547:832:1:o;13384:118::-;13470:5;13463:13;13456:21;13449:5;13446:32;13436:60;;13492:1;13489;13482:12;13507:1177;13601:6;13609;13653:9;13644:7;13640:23;13683:3;13679:2;13675:12;13672:32;;;13700:1;13697;13690:12;13672:32;13724:4;13720:2;13716:13;13713:33;;;13742:1;13739;13732:12;13713:33;;13768:22;;:::i;:::-;13827:9;13814:23;13846:33;13871:7;13846:33;:::i;:::-;13888:22;;13962:2;13947:18;;13934:32;13975:33;13934:32;13975:33;:::i;:::-;14035:2;14024:14;;14017:31;14100:2;14085:18;;14072:32;14113:33;14072:32;14113:33;:::i;:::-;14173:2;14162:14;;14155:31;14238:2;14223:18;;14210:32;14251:33;14210:32;14251:33;:::i;:::-;14311:2;14300:14;;14293:31;14376:3;14361:19;;14348:33;14390;14348;14390;:::i;:::-;14450:3;14439:15;;14432:32;14516:3;14501:19;;14488:33;14530:30;14488:33;14530:30;:::i;:::-;14587:3;14576:15;;14569:32;14580:5;14672:4;14657:20;;;;14644:34;;-1:-1:-1;;;13507:1177:1:o;14689:249::-;14862:2;14851:9;14844:21;14825:4;14882:50;14928:2;14917:9;14913:18;14905:6;14882:50;:::i;14943:388::-;15011:6;15019;15072:2;15060:9;15051:7;15047:23;15043:32;15040:52;;;15088:1;15085;15078:12;15040:52;15127:9;15114:23;15146:31;15171:5;15146:31;:::i;:::-;15196:5;-1:-1:-1;15253:2:1;15238:18;;15225:32;15266:33;15225:32;15266:33;:::i;:::-;15318:7;15308:17;;;14943:388;;;;;:::o;15336:856::-;15538:4;15567:2;15607;15596:9;15592:18;15637:2;15626:9;15619:21;15660:6;15695;15689:13;15726:6;15718;15711:22;15764:2;15753:9;15749:18;15742:25;;15826:2;15816:6;15813:1;15809:14;15798:9;15794:30;15790:39;15776:53;;15864:2;15856:6;15852:15;15885:1;15895:268;15909:6;15906:1;15903:13;15895:268;;;16002:2;15998:7;15986:9;15978:6;15974:22;15970:36;15965:3;15958:49;16030:53;16076:6;16067;16061:13;16030:53;:::i;:::-;16020:63;-1:-1:-1;16141:12:1;;;;16106:15;;;;15931:1;15924:9;15895:268;;16197:566;16386:2;16375:9;16368:21;16461:1;16457;16452:3;16448:11;16444:19;16435:6;16429:13;16425:39;16420:2;16409:9;16405:18;16398:67;16519:2;16511:6;16507:15;16501:22;16496:2;16485:9;16481:18;16474:50;16578:2;16570:6;16566:15;16560:22;16555:2;16544:9;16540:18;16533:50;16349:4;16630:2;16622:6;16618:15;16612:22;16672:4;16665;16654:9;16650:20;16643:34;16694:63;16752:3;16741:9;16737:19;16723:12;16694:63;:::i;16768:251::-;16838:6;16891:2;16879:9;16870:7;16866:23;16862:32;16859:52;;;16907:1;16904;16897:12;16859:52;16939:9;16933:16;16958:31;16983:5;16958:31;:::i;17024:184::-;17094:6;17147:2;17135:9;17126:7;17122:23;17118:32;17115:52;;;17163:1;17160;17153:12;17115:52;-1:-1:-1;17186:16:1;;17024:184;-1:-1:-1;17024:184:1:o;17700:245::-;17767:6;17820:2;17808:9;17799:7;17795:23;17791:32;17788:52;;;17836:1;17833;17826:12;17788:52;17868:9;17862:16;17887:28;17909:5;17887:28;:::i;17950:127::-;18011:10;18006:3;18002:20;17999:1;17992:31;18042:4;18039:1;18032:15;18066:4;18063:1;18056:15;18082:125;18122:4;18150:1;18147;18144:8;18141:34;;;18155:18;;:::i;:::-;-1:-1:-1;18192:9:1;;18082:125::o;18212:127::-;18273:10;18268:3;18264:20;18261:1;18254:31;18304:4;18301:1;18294:15;18328:4;18325:1;18318:15;18344:273;18412:6;18465:2;18453:9;18444:7;18440:23;18436:32;18433:52;;;18481:1;18478;18471:12;18433:52;18513:9;18507:16;18563:4;18556:5;18552:16;18545:5;18542:27;18532:55;;18583:1;18580;18573:12;18622:706;18702:6;18755:2;18743:9;18734:7;18730:23;18726:32;18723:52;;;18771:1;18768;18761:12;18723:52;18804:9;18798:16;-1:-1:-1;;;;;18874:2:1;18866:6;18863:14;18860:34;;;18890:1;18887;18880:12;18860:34;18928:6;18917:9;18913:22;18903:32;;18973:7;18966:4;18962:2;18958:13;18954:27;18944:55;;18995:1;18992;18985:12;18944:55;19024:2;19018:9;19046:2;19042;19039:10;19036:36;;;19052:18;;:::i;:::-;19094:53;19137:2;19118:13;;-1:-1:-1;;19114:27:1;19143:2;19110:36;19094:53;:::i;:::-;19081:66;;19170:2;19163:5;19156:17;19210:7;19205:2;19200;19196;19192:11;19188:20;19185:33;19182:53;;;19231:1;19228;19221:12;19182:53;19244:54;19295:2;19290;19283:5;19279:14;19274:2;19270;19266:11;19244:54;:::i;19333:135::-;19372:3;-1:-1:-1;;19393:17:1;;19390:43;;;19413:18;;:::i;:::-;-1:-1:-1;19460:1:1;19449:13;;19333:135::o;19473:1173::-;19569:6;19622:3;19610:9;19601:7;19597:23;19593:33;19590:53;;;19639:1;19636;19629:12;19590:53;19672:2;19666:9;19714:3;19706:6;19702:16;19784:6;19772:10;19769:22;-1:-1:-1;;;;;19736:10:1;19733:34;19730:62;19727:88;;;19795:18;;:::i;:::-;19831:2;19824:22;19868:16;;19893:31;19868:16;19893:31;:::i;:::-;19933:21;;19999:2;19984:18;;19978:25;20012:33;19978:25;20012:33;:::i;:::-;20073:2;20061:15;;20054:32;20131:2;20116:18;;20110:25;20144:33;20110:25;20144:33;:::i;:::-;20205:2;20193:15;;20186:32;20263:2;20248:18;;20242:25;20276:33;20242:25;20276:33;:::i;:::-;20337:2;20325:15;;20318:32;20395:3;20380:19;;20374:26;20409:33;20374:26;20409:33;:::i;:::-;20470:3;20458:16;;20451:33;20529:3;20514:19;;20508:26;20543:30;20508:26;20543:30;:::i;:::-;20601:3;20589:16;;20582:33;20593:6;19473:1173;-1:-1:-1;;;19473:1173:1:o;21022:659::-;21087:5;21140:3;21133:4;21125:6;21121:17;21117:27;21107:55;;21158:1;21155;21148:12;21107:55;21187:6;21181:13;21213:4;21237:60;21253:43;21293:2;21253:43;:::i;21237:60::-;21331:15;;;21417:1;21413:10;;;;21401:23;;21397:32;;;21362:12;;;;21441:15;;;21438:35;;;21469:1;21466;21459:12;21438:35;21505:2;21497:6;21493:15;21517:135;21533:6;21528:3;21525:15;21517:135;;;21599:10;;21587:23;;21630:12;;;;21550;;21517:135;;;-1:-1:-1;21670:5:1;21022:659;-1:-1:-1;;;;;;21022:659:1:o;21686:1270::-;21824:6;21832;21840;21893:2;21881:9;21872:7;21868:23;21864:32;21861:52;;;21909:1;21906;21899:12;21861:52;21942:9;21936:16;-1:-1:-1;;;;;22012:2:1;22004:6;22001:14;21998:34;;;22028:1;22025;22018:12;21998:34;22066:6;22055:9;22051:22;22041:32;;22111:7;22104:4;22100:2;22096:13;22092:27;22082:55;;22133:1;22130;22123:12;22082:55;22162:2;22156:9;22184:4;22208:60;22224:43;22264:2;22224:43;:::i;22208:60::-;22302:15;;;22384:1;22380:10;;;;22372:19;;22368:28;;;22333:12;;;;22408:19;;;22405:39;;;22440:1;22437;22430:12;22405:39;22464:11;;;;22484:210;22500:6;22495:3;22492:15;22484:210;;;22573:3;22567:10;22590:31;22615:5;22590:31;:::i;:::-;22634:18;;22517:12;;;;22672;;;;22484:210;;;22749:18;;;22743:25;22713:5;;-1:-1:-1;22743:25:1;;-1:-1:-1;;;22780:16:1;;;22777:36;;;22809:1;22806;22799:12;22777:36;;22832:74;22898:7;22887:8;22876:9;22872:24;22832:74;:::i;:::-;22822:84;;;22946:2;22935:9;22931:18;22925:25;22915:35;;21686:1270;;;;;:::o;22961:363::-;23056:6;23109:2;23097:9;23088:7;23084:23;23080:32;23077:52;;;23125:1;23122;23115:12;23077:52;23158:9;23152:16;-1:-1:-1;;;;;23183:6:1;23180:30;23177:50;;;23223:1;23220;23213:12;23177:50;23246:72;23310:7;23301:6;23290:9;23286:22;23246:72;:::i
Swarm Source
ipfs://7cd163f6f7b9f3828ecdd70456149d48d52ddfd35ef8e0837b37ecf9f2a36324
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.