Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
StakedAave
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-09-24 */ // File: contracts/interfaces/IERC20.sol // SPDX-License-Identifier: agpl-3.0 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; /** * @dev Interface of the ERC20 standard as defined in the EIP. * From https://github.com/OpenZeppelin/openzeppelin-contracts */ 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: contracts/interfaces/IStakedAave.sol pragma solidity 0.6.12; interface IStakedAave { function stake(address to, uint256 amount) external; function redeem(address to, uint256 amount) external; function cooldown() external; function claimRewards(address to, uint256 amount) external; } // File: contracts/interfaces/ITransferHook.sol pragma solidity 0.6.12; interface ITransferHook { function onTransfer(address from, address to, uint256 amount) external; } // File: contracts/lib/Context.sol pragma solidity 0.6.12; /** * @dev From https://github.com/OpenZeppelin/openzeppelin-contracts * 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 GSN 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 virtual view returns (address payable) { return msg.sender; } function _msgData() internal virtual view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: contracts/interfaces/IERC20Detailed.sol pragma solidity 0.6.12; /** * @dev Interface for ERC20 including metadata **/ interface IERC20Detailed is IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); } // File: contracts/lib/SafeMath.sol pragma solidity 0.6.12; /** * @dev From https://github.com/OpenZeppelin/openzeppelin-contracts * Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, 'SafeMath: addition overflow'); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, 'SafeMath: subtraction overflow'); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, 'SafeMath: multiplication overflow'); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, 'SafeMath: division by zero'); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, 'SafeMath: modulo by zero'); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/lib/ERC20.sol pragma solidity 0.6.12; /** * @title ERC20 * @notice Basic ERC20 implementation * @author Aave **/ contract ERC20 is Context, IERC20, IERC20Detailed { using SafeMath for uint256; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; constructor( string memory name, string memory symbol, uint8 decimals ) public { _name = name; _symbol = symbol; _decimals = decimals; } /** * @return the name of the token **/ function name() public override view returns (string memory) { return _name; } /** * @return the symbol of the token **/ function symbol() public override view returns (string memory) { return _symbol; } /** * @return the decimals of the token **/ function decimals() public override view returns (uint8) { return _decimals; } /** * @return the total supply of the token **/ function totalSupply() public override view returns (uint256) { return _totalSupply; } /** * @return the balance of the token **/ function balanceOf(address account) public override view returns (uint256) { return _balances[account]; } /** * @dev executes a transfer of tokens from msg.sender to recipient * @param recipient the recipient of the tokens * @param amount the amount of tokens being transferred * @return true if the transfer succeeds, false otherwise **/ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev returns the allowance of spender on the tokens owned by owner * @param owner the owner of the tokens * @param spender the user allowed to spend the owner's tokens * @return the amount of owner's tokens spender is allowed to spend **/ function allowance(address owner, address spender) public virtual override view returns (uint256) { return _allowances[owner][spender]; } /** * @dev allows spender to spend the tokens owned by msg.sender * @param spender the user allowed to spend msg.sender tokens * @return true **/ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev executes a transfer of token from sender to recipient, if msg.sender is allowed to do so * @param sender the owner of the tokens * @param recipient the recipient of the tokens * @param amount the amount of tokens being transferred * @return true if the transfer succeeds, false otherwise **/ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve( sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, 'ERC20: transfer amount exceeds allowance') ); return true; } /** * @dev increases the allowance of spender to spend msg.sender tokens * @param spender the user allowed to spend on behalf of msg.sender * @param addedValue the amount being added to the allowance * @return true **/ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev decreases the allowance of spender to spend msg.sender tokens * @param spender the user allowed to spend on behalf of msg.sender * @param subtractedValue the amount being subtracted to the allowance * @return true **/ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve( _msgSender(), spender, _allowances[_msgSender()][spender].sub( subtractedValue, 'ERC20: decreased allowance below zero' ) ); return true; } function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), 'ERC20: transfer from the zero address'); require(recipient != address(0), 'ERC20: transfer to the zero address'); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, 'ERC20: transfer amount exceeds balance'); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } function _mint(address account, uint256 amount) internal virtual { require(account != address(0), 'ERC20: mint to the zero address'); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } function _burn(address account, uint256 amount) internal virtual { require(account != address(0), 'ERC20: burn from the zero address'); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, 'ERC20: burn amount exceeds balance'); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), 'ERC20: approve from the zero address'); require(spender != address(0), 'ERC20: approve to the zero address'); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _setName(string memory newName) internal { _name = newName; } function _setSymbol(string memory newSymbol) internal { _symbol = newSymbol; } function _setDecimals(uint8 newDecimals) internal { _decimals = newDecimals; } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File: contracts/lib/ERC20WithSnapshot.sol pragma solidity 0.6.12; /** * @title ERC20WithSnapshot * @notice ERC20 including snapshots of balances on transfer-related actions * @author Aave **/ contract ERC20WithSnapshot is ERC20 { /// @dev snapshot of a value on a specific block, used for balances struct Snapshot { uint128 blockNumber; uint128 value; } mapping (address => mapping (uint256 => Snapshot)) public _snapshots; mapping (address => uint256) public _countsSnapshots; /// @dev reference to the Aave governance contract to call (if initialized) on _beforeTokenTransfer /// !!! IMPORTANT The Aave governance is considered a trustable contract, being its responsibility /// to control all potential reentrancies by calling back the this contract ITransferHook public _aaveGovernance; event SnapshotDone(address owner, uint128 oldValue, uint128 newValue); constructor(string memory name, string memory symbol, uint8 decimals) public ERC20(name, symbol, decimals) {} function _setAaveGovernance(ITransferHook aaveGovernance) internal virtual { _aaveGovernance = aaveGovernance; } /** * @dev Writes a snapshot for an owner of tokens * @param owner The owner of the tokens * @param oldValue The value before the operation that is gonna be executed after the snapshot * @param newValue The value after the operation */ function _writeSnapshot(address owner, uint128 oldValue, uint128 newValue) internal virtual { uint128 currentBlock = uint128(block.number); uint256 ownerCountOfSnapshots = _countsSnapshots[owner]; mapping (uint256 => Snapshot) storage snapshotsOwner = _snapshots[owner]; // Doing multiple operations in the same block if (ownerCountOfSnapshots != 0 && snapshotsOwner[ownerCountOfSnapshots.sub(1)].blockNumber == currentBlock) { snapshotsOwner[ownerCountOfSnapshots.sub(1)].value = newValue; } else { snapshotsOwner[ownerCountOfSnapshots] = Snapshot(currentBlock, newValue); _countsSnapshots[owner] = ownerCountOfSnapshots.add(1); } emit SnapshotDone(owner, oldValue, newValue); } /** * @dev Writes a snapshot before any operation involving transfer of value: _transfer, _mint and _burn * - On _transfer, it writes snapshots for both "from" and "to" * - On _mint, only for _to * - On _burn, only for _from * @param from the from address * @param to the to address * @param amount the amount to transfer */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal override { if (from == to) { return; } if (from != address(0)) { uint256 fromBalance = balanceOf(from); _writeSnapshot(from, uint128(fromBalance), uint128(fromBalance.sub(amount))); } if (to != address(0)) { uint256 toBalance = balanceOf(to); _writeSnapshot(to, uint128(toBalance), uint128(toBalance.add(amount))); } // caching the aave governance address to avoid multiple state loads ITransferHook aaveGovernance = _aaveGovernance; if (aaveGovernance != ITransferHook(0)) { aaveGovernance.onTransfer(from, to, amount); } } } // File: contracts/lib/Address.sol pragma solidity 0.6.12; /** * @dev Collection of functions related to the address type * From https://github.com/OpenZeppelin/openzeppelin-contracts */ 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) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @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'); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } } // File: contracts/lib/SafeERC20.sol pragma solidity 0.6.12; /** * @title SafeERC20 * @dev From https://github.com/OpenZeppelin/openzeppelin-contracts * 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 SafeMath for uint256; 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)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { 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 callOptionalReturn(IERC20 token, bytes memory data) private { require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: contracts/utils/VersionedInitializable.sol pragma solidity 0.6.12; /** * @title VersionedInitializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. * * @author Aave, inspired by the OpenZeppelin Initializable contract */ abstract contract VersionedInitializable { /** * @dev Indicates that the contract has been initialized. */ uint256 internal lastInitializedRevision = 0; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { uint256 revision = getRevision(); require( revision > lastInitializedRevision, 'Contract instance has already been initialized' ); lastInitializedRevision = revision; _; } /// @dev returns the revision number of the contract. /// Needs to be defined in the inherited class as a constant. function getRevision() internal virtual pure returns (uint256); // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } // File: contracts/lib/DistributionTypes.sol pragma solidity 0.6.12; library DistributionTypes { struct AssetConfigInput { uint128 emissionPerSecond; uint256 totalStaked; address underlyingAsset; } struct UserStakeInput { address underlyingAsset; uint256 stakedByUser; uint256 totalStaked; } } // File: contracts/interfaces/IAaveDistributionManager.sol pragma solidity 0.6.12; interface IAaveDistributionManager { function configureAssets(DistributionTypes.AssetConfigInput[] calldata assetsConfigInput) external; } // File: contracts/stake/AaveDistributionManager.sol pragma solidity 0.6.12; /** * @title AaveDistributionManager * @notice Accounting contract to manage multiple staking distributions * @author Aave **/ contract AaveDistributionManager is IAaveDistributionManager { using SafeMath for uint256; struct AssetData { uint128 emissionPerSecond; uint128 lastUpdateTimestamp; uint256 index; mapping(address => uint256) users; } uint256 public immutable DISTRIBUTION_END; address public immutable EMISSION_MANAGER; uint8 public constant PRECISION = 18; mapping(address => AssetData) public assets; event AssetConfigUpdated(address indexed asset, uint256 emission); event AssetIndexUpdated(address indexed asset, uint256 index); event UserIndexUpdated(address indexed user, address indexed asset, uint256 index); constructor(address emissionManager, uint256 distributionDuration) public { DISTRIBUTION_END = block.timestamp.add(distributionDuration); EMISSION_MANAGER = emissionManager; } /** * @dev Configures the distribution of rewards for a list of assets * @param assetsConfigInput The list of configurations to apply **/ function configureAssets(DistributionTypes.AssetConfigInput[] calldata assetsConfigInput) external override { require(msg.sender == EMISSION_MANAGER, 'ONLY_EMISSION_MANAGER'); for (uint256 i = 0; i < assetsConfigInput.length; i++) { AssetData storage assetConfig = assets[assetsConfigInput[i].underlyingAsset]; _updateAssetStateInternal( assetsConfigInput[i].underlyingAsset, assetConfig, assetsConfigInput[i].totalStaked ); assetConfig.emissionPerSecond = assetsConfigInput[i].emissionPerSecond; emit AssetConfigUpdated( assetsConfigInput[i].underlyingAsset, assetsConfigInput[i].emissionPerSecond ); } } /** * @dev Updates the state of one distribution, mainly rewards index and timestamp * @param underlyingAsset The address used as key in the distribution, for example sAAVE or the aTokens addresses on Aave * @param assetConfig Storage pointer to the distribution's config * @param totalStaked Current total of staked assets for this distribution * @return The new distribution index **/ function _updateAssetStateInternal( address underlyingAsset, AssetData storage assetConfig, uint256 totalStaked ) internal returns (uint256) { uint256 oldIndex = assetConfig.index; uint128 lastUpdateTimestamp = assetConfig.lastUpdateTimestamp; if (block.timestamp == lastUpdateTimestamp) { return oldIndex; } uint256 newIndex = _getAssetIndex( oldIndex, assetConfig.emissionPerSecond, lastUpdateTimestamp, totalStaked ); if (newIndex != oldIndex) { assetConfig.index = newIndex; emit AssetIndexUpdated(underlyingAsset, newIndex); } assetConfig.lastUpdateTimestamp = uint128(block.timestamp); return newIndex; } /** * @dev Updates the state of an user in a distribution * @param user The user's address * @param asset The address of the reference asset of the distribution * @param stakedByUser Amount of tokens staked by the user in the distribution at the moment * @param totalStaked Total tokens staked in the distribution * @return The accrued rewards for the user until the moment **/ function _updateUserAssetInternal( address user, address asset, uint256 stakedByUser, uint256 totalStaked ) internal returns (uint256) { AssetData storage assetData = assets[asset]; uint256 userIndex = assetData.users[user]; uint256 accruedRewards = 0; uint256 newIndex = _updateAssetStateInternal(asset, assetData, totalStaked); if (userIndex != newIndex) { if (stakedByUser != 0) { accruedRewards = _getRewards(stakedByUser, newIndex, userIndex); } assetData.users[user] = newIndex; emit UserIndexUpdated(user, asset, newIndex); } return accruedRewards; } /** * @dev Used by "frontend" stake contracts to update the data of an user when claiming rewards from there * @param user The address of the user * @param stakes List of structs of the user data related with his stake * @return The accrued rewards for the user until the moment **/ function _claimRewards(address user, DistributionTypes.UserStakeInput[] memory stakes) internal returns (uint256) { uint256 accruedRewards = 0; for (uint256 i = 0; i < stakes.length; i++) { accruedRewards = accruedRewards.add( _updateUserAssetInternal( user, stakes[i].underlyingAsset, stakes[i].stakedByUser, stakes[i].totalStaked ) ); } return accruedRewards; } /** * @dev Return the accrued rewards for an user over a list of distribution * @param user The address of the user * @param stakes List of structs of the user data related with his stake * @return The accrued rewards for the user until the moment **/ function _getUnclaimedRewards(address user, DistributionTypes.UserStakeInput[] memory stakes) internal view returns (uint256) { uint256 accruedRewards = 0; for (uint256 i = 0; i < stakes.length; i++) { AssetData storage assetConfig = assets[stakes[i].underlyingAsset]; uint256 assetIndex = _getAssetIndex( assetConfig.index, assetConfig.emissionPerSecond, assetConfig.lastUpdateTimestamp, stakes[i].totalStaked ); accruedRewards = accruedRewards.add( _getRewards(stakes[i].stakedByUser, assetIndex, assetConfig.users[user]) ); } return accruedRewards; } /** * @dev Internal function for the calculation of user's rewards on a distribution * @param principalUserBalance Amount staked by the user on a distribution * @param reserveIndex Current index of the distribution * @param userIndex Index stored for the user, representation his staking moment * @return The rewards **/ function _getRewards( uint256 principalUserBalance, uint256 reserveIndex, uint256 userIndex ) internal pure returns (uint256) { return principalUserBalance.mul(reserveIndex.sub(userIndex)).div(10**uint256(PRECISION)); } /** * @dev Calculates the next value of an specific distribution index, with validations * @param currentIndex Current index of the distribution * @param emissionPerSecond Representing the total rewards distributed per second per asset unit, on the distribution * @param lastUpdateTimestamp Last moment this distribution was updated * @param totalBalance of tokens considered for the distribution * @return The new index. **/ function _getAssetIndex( uint256 currentIndex, uint256 emissionPerSecond, uint128 lastUpdateTimestamp, uint256 totalBalance ) internal view returns (uint256) { if ( emissionPerSecond == 0 || totalBalance == 0 || lastUpdateTimestamp == block.timestamp || lastUpdateTimestamp >= DISTRIBUTION_END ) { return currentIndex; } uint256 currentTimestamp = block.timestamp > DISTRIBUTION_END ? DISTRIBUTION_END : block.timestamp; uint256 timeDelta = currentTimestamp.sub(lastUpdateTimestamp); return emissionPerSecond.mul(timeDelta).mul(10**uint256(PRECISION)).div(totalBalance).add( currentIndex ); } /** * @dev Returns the data of an user on a distribution * @param user Address of the user * @param asset The address of the reference asset of the distribution * @return The new index **/ function getUserAssetData(address user, address asset) public view returns (uint256) { return assets[asset].users[user]; } } // File: contracts/stake/StakedToken.sol pragma solidity 0.6.12; /** * @title StakedToken * @notice Contract to stake Aave token, tokenize the position and get rewards, inheriting from a distribution manager contract * @author Aave **/ contract StakedToken is IStakedAave, ERC20WithSnapshot, VersionedInitializable, AaveDistributionManager { using SafeERC20 for IERC20; uint256 public constant REVISION = 1; IERC20 public immutable STAKED_TOKEN; IERC20 public immutable REWARD_TOKEN; uint256 public immutable COOLDOWN_SECONDS; /// @notice Seconds available to redeem once the cooldown period is fullfilled uint256 public immutable UNSTAKE_WINDOW; /// @notice Address to pull from the rewards, needs to have approved this contract address public immutable REWARDS_VAULT; mapping(address => uint256) public stakerRewardsToClaim; mapping(address => uint256) public stakersCooldowns; event Staked(address indexed from, address indexed onBehalfOf, uint256 amount); event Redeem(address indexed from, address indexed to, uint256 amount); event RewardsAccrued(address user, uint256 amount); event RewardsClaimed(address indexed from, address indexed to, uint256 amount); event Cooldown(address indexed user); constructor( IERC20 stakedToken, IERC20 rewardToken, uint256 cooldownSeconds, uint256 unstakeWindow, address rewardsVault, address emissionManager, uint128 distributionDuration, string memory name, string memory symbol, uint8 decimals ) public ERC20WithSnapshot(name, symbol, decimals) AaveDistributionManager(emissionManager, distributionDuration) { STAKED_TOKEN = stakedToken; REWARD_TOKEN = rewardToken; COOLDOWN_SECONDS = cooldownSeconds; UNSTAKE_WINDOW = unstakeWindow; REWARDS_VAULT = rewardsVault; } /** * @dev Called by the proxy contract **/ function initialize(ITransferHook aaveGovernance, string calldata name, string calldata symbol, uint8 decimals) external initializer { _setName(name); _setSymbol(symbol); _setDecimals(decimals); _setAaveGovernance(aaveGovernance); } function stake(address onBehalfOf, uint256 amount) external override { require(amount != 0, 'INVALID_ZERO_AMOUNT'); uint256 balanceOfUser = balanceOf(onBehalfOf); uint256 accruedRewards = _updateUserAssetInternal( onBehalfOf, address(this), balanceOfUser, totalSupply() ); if (accruedRewards != 0) { emit RewardsAccrued(onBehalfOf, accruedRewards); stakerRewardsToClaim[onBehalfOf] = stakerRewardsToClaim[onBehalfOf].add(accruedRewards); } stakersCooldowns[onBehalfOf] = getNextCooldownTimestamp(0, amount, onBehalfOf, balanceOfUser); _mint(onBehalfOf, amount); IERC20(STAKED_TOKEN).safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, onBehalfOf, amount); } /** * @dev Redeems staked tokens, and stop earning rewards * @param to Address to redeem to * @param amount Amount to redeem **/ function redeem(address to, uint256 amount) external override { require(amount != 0, 'INVALID_ZERO_AMOUNT'); //solium-disable-next-line uint256 cooldownStartTimestamp = stakersCooldowns[msg.sender]; require( block.timestamp > cooldownStartTimestamp.add(COOLDOWN_SECONDS), 'INSUFFICIENT_COOLDOWN' ); require( block.timestamp.sub(cooldownStartTimestamp.add(COOLDOWN_SECONDS)) <= UNSTAKE_WINDOW, 'UNSTAKE_WINDOW_FINISHED' ); uint256 balanceOfMessageSender = balanceOf(msg.sender); uint256 amountToRedeem = (amount > balanceOfMessageSender) ? balanceOfMessageSender : amount; _updateCurrentUnclaimedRewards(msg.sender, balanceOfMessageSender, true); _burn(msg.sender, amountToRedeem); if (balanceOfMessageSender.sub(amountToRedeem) == 0) { stakersCooldowns[msg.sender] = 0; } IERC20(STAKED_TOKEN).safeTransfer(to, amountToRedeem); emit Redeem(msg.sender, to, amountToRedeem); } /** * @dev Activates the cooldown period to unstake * - It can't be called if the user is not staking **/ function cooldown() external override { require(balanceOf(msg.sender) != 0, "INVALID_BALANCE_ON_COOLDOWN"); //solium-disable-next-line stakersCooldowns[msg.sender] = block.timestamp; emit Cooldown(msg.sender); } /** * @dev Claims an `amount` of `REWARD_TOKEN` to the address `to` * @param to Address to stake for * @param amount Amount to stake **/ function claimRewards(address to, uint256 amount) external override { uint256 newTotalRewards = _updateCurrentUnclaimedRewards( msg.sender, balanceOf(msg.sender), false ); uint256 amountToClaim = (amount == type(uint256).max) ? newTotalRewards : amount; stakerRewardsToClaim[msg.sender] = newTotalRewards.sub(amountToClaim, "INVALID_AMOUNT"); REWARD_TOKEN.safeTransferFrom(REWARDS_VAULT, to, amountToClaim); emit RewardsClaimed(msg.sender, to, amountToClaim); } /** * @dev Internal ERC20 _transfer of the tokenized staked tokens * @param from Address to transfer from * @param to Address to transfer to * @param amount Amount to transfer **/ function _transfer( address from, address to, uint256 amount ) internal override { uint256 balanceOfFrom = balanceOf(from); // Sender _updateCurrentUnclaimedRewards(from, balanceOfFrom, true); // Recipient if (from != to) { uint256 balanceOfTo = balanceOf(to); _updateCurrentUnclaimedRewards(to, balanceOfTo, true); uint256 previousSenderCooldown = stakersCooldowns[from]; stakersCooldowns[to] = getNextCooldownTimestamp(previousSenderCooldown, amount, to, balanceOfTo); // if cooldown was set and whole balance of sender was transferred - clear cooldown if (balanceOfFrom == amount && previousSenderCooldown != 0) { stakersCooldowns[from] = 0; } } super._transfer(from, to, amount); } /** * @dev Updates the user state related with his accrued rewards * @param user Address of the user * @param userBalance The current balance of the user * @param updateStorage Boolean flag used to update or not the stakerRewardsToClaim of the user * @return The unclaimed rewards that were added to the total accrued **/ function _updateCurrentUnclaimedRewards( address user, uint256 userBalance, bool updateStorage ) internal returns (uint256) { uint256 accruedRewards = _updateUserAssetInternal( user, address(this), userBalance, totalSupply() ); uint256 unclaimedRewards = stakerRewardsToClaim[user].add(accruedRewards); if (accruedRewards != 0) { if (updateStorage) { stakerRewardsToClaim[user] = unclaimedRewards; } emit RewardsAccrued(user, accruedRewards); } return unclaimedRewards; } /** * @dev Calculates the how is gonna be a new cooldown timestamp depending on the sender/receiver situation * - If the timestamp of the sender is "better" or the timestamp of the recipient is 0, we take the one of the recipient * - Weighted average of from/to cooldown timestamps if: * # The sender doesn't have the cooldown activated (timestamp 0). * # The sender timestamp is expired * # The sender has a "worse" timestamp * - If the receiver's cooldown timestamp expired (too old), the next is 0 * @param fromCooldownTimestamp Cooldown timestamp of the sender * @param amountToReceive Amount * @param toAddress Address of the recipient * @param toBalance Current balance of the receiver * @return The new cooldown timestamp **/ function getNextCooldownTimestamp( uint256 fromCooldownTimestamp, uint256 amountToReceive, address toAddress, uint256 toBalance ) public returns (uint256) { uint256 toCooldownTimestamp = stakersCooldowns[toAddress]; if (toCooldownTimestamp == 0) { return 0; } uint256 minimalValidCooldownTimestamp = block.timestamp.sub(COOLDOWN_SECONDS).sub( UNSTAKE_WINDOW ); if (minimalValidCooldownTimestamp > toCooldownTimestamp) { toCooldownTimestamp = 0; } else { uint256 fromCooldownTimestamp = (minimalValidCooldownTimestamp > fromCooldownTimestamp) ? block.timestamp : fromCooldownTimestamp; if (fromCooldownTimestamp < toCooldownTimestamp) { return toCooldownTimestamp; } else { toCooldownTimestamp = ( amountToReceive.mul(fromCooldownTimestamp).add(toBalance.mul(toCooldownTimestamp)) ) .div(amountToReceive.add(toBalance)); } } stakersCooldowns[toAddress] = toCooldownTimestamp; return toCooldownTimestamp; } /** * @dev Return the total rewards pending to claim by an staker * @param staker The staker address * @return The rewards */ function getTotalRewardsBalance(address staker) external view returns (uint256) { DistributionTypes.UserStakeInput[] memory userStakeInputs = new DistributionTypes.UserStakeInput[](1); userStakeInputs[0] = DistributionTypes.UserStakeInput({ underlyingAsset: address(this), stakedByUser: balanceOf(staker), totalStaked: totalSupply() }); return stakerRewardsToClaim[staker].add(_getUnclaimedRewards(staker, userStakeInputs)); } /** * @dev returns the revision of the implementation contract * @return The revision */ function getRevision() internal override pure returns (uint256) { return REVISION; } } // File: contracts/stake/StakedAave.sol pragma solidity 0.6.12; /** * @title StakedAave * @notice StakedToken with AAVE token as staked token * @author Aave **/ contract StakedAave is StakedToken { string internal constant NAME = 'Staked Aave'; string internal constant SYMBOL = 'stkAAVE'; uint8 internal constant DECIMALS = 18; constructor( IERC20 stakedToken, IERC20 rewardToken, uint256 cooldownSeconds, uint256 unstakeWindow, address rewardsVault, address emissionManager, uint128 distributionDuration ) public StakedToken( stakedToken, rewardToken, cooldownSeconds, unstakeWindow, rewardsVault, emissionManager, distributionDuration, NAME, SYMBOL, DECIMALS) {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"stakedToken","type":"address"},{"internalType":"contract IERC20","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"cooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"unstakeWindow","type":"uint256"},{"internalType":"address","name":"rewardsVault","type":"address"},{"internalType":"address","name":"emissionManager","type":"address"},{"internalType":"uint128","name":"distributionDuration","type":"uint128"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"emission","type":"uint256"}],"name":"AssetConfigUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"AssetIndexUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Cooldown","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsAccrued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint128","name":"oldValue","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"newValue","type":"uint128"}],"name":"SnapshotDone","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"UserIndexUpdated","type":"event"},{"inputs":[],"name":"COOLDOWN_SECONDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISTRIBUTION_END","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EMISSION_MANAGER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARDS_VAULT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_TOKEN","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKED_TOKEN","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNSTAKE_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_aaveGovernance","outputs":[{"internalType":"contract ITransferHook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_countsSnapshots","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_snapshots","outputs":[{"internalType":"uint128","name":"blockNumber","type":"uint128"},{"internalType":"uint128","name":"value","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"assets","outputs":[{"internalType":"uint128","name":"emissionPerSecond","type":"uint128"},{"internalType":"uint128","name":"lastUpdateTimestamp","type":"uint128"},{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"emissionPerSecond","type":"uint128"},{"internalType":"uint256","name":"totalStaked","type":"uint256"},{"internalType":"address","name":"underlyingAsset","type":"address"}],"internalType":"struct DistributionTypes.AssetConfigInput[]","name":"assetsConfigInput","type":"tuple[]"}],"name":"configureAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fromCooldownTimestamp","type":"uint256"},{"internalType":"uint256","name":"amountToReceive","type":"uint256"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"toBalance","type":"uint256"}],"name":"getNextCooldownTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getTotalRewardsBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"asset","type":"address"}],"name":"getUserAssetData","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITransferHook","name":"aaveGovernance","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakerRewardsToClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakersCooldowns","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61016060405260006009553480156200001757600080fd5b5060405162002d3f38038062002d3f8339810160408190526200003a9162000228565b868686868686866040518060400160405280600b81526020016a5374616b6564204161766560a81b8152506040518060400160405280600781526020016673746b4141564560c81b815250601284846001600160801b03168484848282828260039080519060200190620000b09291906200018c565b508151620000c69060049060208501906200018c565b5080600560006101000a81548160ff021916908360ff1602179055505050505050506200010281426200015460201b620011f51790919060201c565b608052506001600160601b0319606091821b811660a0529a811b8b1660c05298891b8a1660e05250505061010094909452506101209190915290911b9091166101405250620003159650505050505050565b600082820183811015620001855760405162461bcd60e51b81526004016200017c90620002c5565b60405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620001cf57805160ff1916838001178555620001ff565b82800160010185558215620001ff579182015b82811115620001ff578251825591602001919060010190620001e2565b506200020d92915062000211565b5090565b5b808211156200020d576000815560010162000212565b600080600080600080600060e0888a03121562000243578283fd5b87516200025081620002fc565b60208901519097506200026381620002fc565b80965050604088015194506060880151935060808801516200028581620002fc565b60a08901519093506200029881620002fc565b60c08901519092506001600160801b0381168114620002b5578182fd5b8091505092959891949750929550565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6001600160a01b03811681146200031257600080fd5b50565b60805160a05160601c60c05160601c60e05160601c61010051610120516101405160601c612989620003b660003980610a2b5280610b795250806105bf5280610824528061104952508061057b52806105e752806108b1528061106e525080610ab05280610b4f52508061069352806107c75280610d6b525080610de15280610f9a525080610a075280611d285280611d645280611d9152506129896000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c80638dbefee211610125578063adc9772e116100ad578063dd62ed3e1161007c578063dd62ed3e14610410578063dde43cba14610423578063f11b81881461042b578063f1cc432a1461044d578063f6d2ee861461046057610211565b8063adc9772e146103da578063b2a5dbfa146103ed578063c3863ada14610400578063cbcbb5071461040857610211565b806399248ea7116100f457806399248ea7146103915780639a99b4f014610399578063a457c2d7146103ac578063a9059cbb146103bf578063aaf5eb68146103d257610211565b80638dbefee214610366578063919cd40f14610379578063946776cd1461038157806395d89b411461038957610211565b8063313ce567116101a857806370a082311161017757806370a082311461031d57806372b49d6314610330578063787a08a6146103385780637e90d7ef146103405780638779588c1461035357610211565b8063313ce567146102da5780633373ee4c146102ef578063359c4a9614610302578063395093511461030a57610211565b80631e9a6950116101e45780631e9a69501461027c57806323b872dd146102915780632acbf823146102a4578063312f6b83146102c557610211565b806306fdde0314610216578063091030c314610234578063095ea7b31461025457806318160ddd14610274575b600080fd5b61021e610473565b60405161022b91906123e3565b60405180910390f35b6102476102423660046120f6565b610509565b60405161022b9190612863565b61026761026236600461218a565b61051b565b60405161022b91906123d8565b610247610539565b61028f61028a36600461218a565b61053f565b005b61026761029f36600461214a565b61070c565b6102b76102b236600461218a565b610794565b60405161022b929190612825565b6102cd6107c5565b60405161022b919061235d565b6102e26107e9565b60405161022b919061286c565b6102476102fd366004612112565b6107f2565b610247610822565b61026761031836600461218a565b610846565b61024761032b3660046120f6565b610894565b6102476108af565b61028f6108d3565b61024761034e3660046120f6565b610932565b6102476103613660046120f6565b610944565b6102476103743660046120f6565b610956565b610247610a05565b6102cd610a29565b61021e610a4d565b6102cd610aae565b61028f6103a736600461218a565b610ad2565b6102676103ba36600461218a565b610bf0565b6102676103cd36600461218a565b610c58565b6102e2610c6c565b61028f6103e836600461218a565b610c71565b61028f6103fb3660046121b5565b610dd6565b6102cd610f89565b6102cd610f98565b61024761041e366004612112565b610fbc565b610247610fe7565b61043e6104393660046120f6565b610fec565b60405161022b9392919061283f565b61024761045b366004612303565b61101a565b61028f61046e366004612245565b61112c565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104ff5780601f106104d4576101008083540402835291602001916104ff565b820191906000526020600020905b8154815290600101906020018083116104e257829003601f168201915b5050505050905090565b603e6020526000908152604090205481565b600061052f61052861121a565b848461121e565b5060015b92915050565b60025490565b806105655760405162461bcd60e51b815260040161055c906124d2565b60405180910390fd5b336000908152603e602052604090205461059f817f00000000000000000000000000000000000000000000000000000000000000006111f5565b42116105bd5760405162461bcd60e51b815260040161055c90612534565b7f000000000000000000000000000000000000000000000000000000000000000061061261060b837f00000000000000000000000000000000000000000000000000000000000000006111f5565b42906112d2565b11156106305760405162461bcd60e51b815260040161055c906126a7565b600061063b33610894565b9050600081841161064c578361064e565b815b905061065c33836001611314565b5061066733826113b9565b61067182826112d2565b61068657336000908152603e60205260408120555b6106ba6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016868361149b565b846001600160a01b0316336001600160a01b03167fd12200efa34901b99367694174c3b0d32c99585fdf37c7c26892136ddd0836d9836040516106fd9190612863565b60405180910390a35050505050565b60006107198484846114f1565b6107898461072561121a565b61078485604051806060016040528060288152602001612907602891396001600160a01b038a1660009081526001602052604081209061076361121a565b6001600160a01b0316815260208101919091526040016000205491906115bd565b61121e565b5060015b9392505050565b60066020908152600092835260408084209091529082529020546001600160801b0380821691600160801b90041682565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055460ff1690565b6001600160a01b038082166000908152603c60209081526040808320938616835260029093019052205492915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061052f61085361121a565b84610784856001600061086461121a565b6001600160a01b03908116825260208083019390935260409182016000908120918c1681529252902054906111f5565b6001600160a01b031660009081526020819052604090205490565b7f000000000000000000000000000000000000000000000000000000000000000081565b6108dc33610894565b6108f85760405162461bcd60e51b815260040161055c9061276c565b336000818152603e6020526040808220429055517ff52f50426b32362d3e6bb8cb36b7074756b224622def6352a59eac7f66ebe6e89190a2565b603d6020526000908152604090205481565b60076020526000908152604090205481565b60408051600180825281830190925260009160609190816020015b610979611ff2565b8152602001906001900390816109715790505090506040518060600160405280306001600160a01b031681526020016109b185610894565b81526020016109be610539565b815250816000815181106109ce57fe5b602002602001018190525061078d6109e684836115e9565b6001600160a01b0385166000908152603d6020526040902054906111f5565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104ff5780601f106104d4576101008083540402835291602001916104ff565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610ae833610ae133610894565b6000611314565b905060006000198314610afb5782610afd565b815b9050610b3a816040518060400160405280600e81526020016d1253959053125117d05353d5539560921b815250846115bd9092919063ffffffff16565b336000908152603d6020526040902055610b9f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f000000000000000000000000000000000000000000000000000000000000000086846116da565b836001600160a01b0316336001600160a01b03167f9310ccfcb8de723f578a9e4282ea9f521f05ae40dc08f3068dfad528a65ee3c783604051610be29190612863565b60405180910390a350505050565b600061052f610bfd61121a565b846107848560405180606001604052806025815260200161292f6025913960016000610c2761121a565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906115bd565b600061052f610c6561121a565b84846114f1565b601281565b80610c8e5760405162461bcd60e51b815260040161055c906124d2565b6000610c9983610894565b90506000610cb0843084610cab610539565b6116fb565b90508015610d2e577f2468f9268c60ad90e2d49edb0032c8a001e733ae888b3ab8e982edf535be1a768482604051610ce99291906123bf565b60405180910390a16001600160a01b0384166000908152603d6020526040902054610d1490826111f5565b6001600160a01b0385166000908152603d60205260409020555b610d3b600084868561101a565b6001600160a01b0385166000908152603e6020526040902055610d5e84846117ba565b610d936001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330866116da565b836001600160a01b0316336001600160a01b03167f5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd785604051610be29190612863565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e1e5760405162461bcd60e51b815260040161055c906125f2565b60005b81811015610f84576000603c6000858585818110610e3b57fe5b9050606002016040016020810190610e5391906120f6565b6001600160a01b03166001600160a01b031681526020019081526020016000209050610eb8848484818110610e8457fe5b9050606002016040016020810190610e9c91906120f6565b82868686818110610ea957fe5b9050606002016020013561186e565b50838383818110610ec557fe5b610edb92602060609092020190810191506122dc565b81546001600160801b0319166001600160801b0391909116178155838383818110610f0257fe5b9050606002016040016020810190610f1a91906120f6565b6001600160a01b03167f87fa03892a0556cb6b8f97e6d533a150d4d55fcbf275fff5fa003fa636bcc7fa858585818110610f5057fe5b610f6692602060609092020190810191506122dc565b604051610f739190612811565b60405180910390a250600101610e21565b505050565b6008546001600160a01b031681565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600181565b603c60205260009081526040902080546001909101546001600160801b0380831692600160801b9004169083565b6001600160a01b0382166000908152603e602052604081205480611042576000915050611124565b60006110987f0000000000000000000000000000000000000000000000000000000000000000611092427f00000000000000000000000000000000000000000000000000000000000000006112d2565b906112d2565b9050818111156110ab5760009150611105565b60008782116110ba57876110bc565b425b9050828110156110d157829350505050611124565b6111016110de88876111f5565b6110fb6110eb888761192b565b6110f58b8661192b565b906111f5565b90611965565b9250505b506001600160a01b0384166000908152603e6020526040902081905590505b949350505050565b60006111366119a7565b905060095481116111595760405162461bcd60e51b815260040161055c906125a4565b6009819055604080516020601f880181900481028201810190925286815261119b9188908890819084018382808284376000920191909152506119ac92505050565b6111da84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119c392505050565b6111e3826119d6565b6111ec876119ec565b50505050505050565b60008282018381101561078d5760405162461bcd60e51b815260040161055c9061249b565b3390565b6001600160a01b0383166112445760405162461bcd60e51b815260040161055c906126de565b6001600160a01b03821661126a5760405162461bcd60e51b815260040161055c90612459565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906112c5908590612863565b60405180910390a3505050565b600061078d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506115bd565b600080611325853086610cab610539565b6001600160a01b0386166000908152603d60205260408120549192509061134c90836111f5565b905081156113b0578315611376576001600160a01b0386166000908152603d602052604090208190555b7f2468f9268c60ad90e2d49edb0032c8a001e733ae888b3ab8e982edf535be1a7686836040516113a79291906123bf565b60405180910390a15b95945050505050565b6001600160a01b0382166113df5760405162461bcd60e51b815260040161055c90612621565b6113eb82600083611a0e565b611428816040518060600160405280602281526020016128bf602291396001600160a01b03851660009081526020819052604090205491906115bd565b6001600160a01b03831660009081526020819052604090205560025461144e90826112d2565b6002556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061148f908590612863565b60405180910390a35050565b610f848363a9059cbb60e01b84846040516024016114ba9291906123bf565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611b06565b60006114fc84610894565b905061150a84826001611314565b50826001600160a01b0316846001600160a01b0316146115ac57600061152f84610894565b905061153d84826001611314565b506001600160a01b0385166000908152603e60205260409020546115638185878561101a565b6001600160a01b0386166000908152603e6020526040902055828414801561158a57508015155b156115a9576001600160a01b0386166000908152603e60205260408120555b50505b6115b7848484611beb565b50505050565b600081848411156115e15760405162461bcd60e51b815260040161055c91906123e3565b505050900390565b600080805b83518110156116d2576000603c600086848151811061160957fe5b602090810291909101810151516001600160a01b031682528101919091526040016000908120600181015481548851929450611671926001600160801b0380831692600160801b900416908a908890811061166057fe5b602002602001015160400151611d00565b90506116c66116bf87858151811061168557fe5b602002602001015160200151838560020160008c6001600160a01b03166001600160a01b0316815260200190815260200160002054611df9565b85906111f5565b935050506001016115ee565b509392505050565b6115b7846323b872dd60e01b8585856040516024016114ba93929190612371565b6001600160a01b038084166000908152603c60209081526040808320938816835260028401909152812054909190828061173688858861186e565b90508083146117ae57861561175357611750878285611df9565b91505b6001600160a01b03808a1660008181526002870160205260409081902084905551918a16917fbb123b5c06d5408bbea3c4fef481578175cfb432e3b482c6186f02ed9086585b906117a5908590612863565b60405180910390a35b50979650505050505050565b6001600160a01b0382166117e05760405162461bcd60e51b815260040161055c906127da565b6117ec60008383611a0e565b6002546117f990826111f5565b6002556001600160a01b03821660009081526020819052604090205461181f90826111f5565b6001600160a01b0383166000818152602081905260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061148f908590612863565b6001820154825460009190600160801b90046001600160801b0316428114156118995750905061078d565b84546000906118b49084906001600160801b03168488611d00565b905082811461190857808660010181905550866001600160a01b03167f5777ca300dfe5bead41006fbce4389794dbc0ed8d6cccebfaf94630aa04184bc826040516118ff9190612863565b60405180910390a25b85546001600160801b03428116600160801b029116178655925050509392505050565b60008261193a57506000610533565b8282028284828161194757fe5b041461078d5760405162461bcd60e51b815260040161055c90612563565b600061078d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e1b565b600190565b80516119bf90600390602084019061201c565b5050565b80516119bf90600490602084019061201c565b6005805460ff191660ff92909216919091179055565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b816001600160a01b0316836001600160a01b03161415611a2d57610f84565b6001600160a01b03831615611a5f576000611a4784610894565b9050611a5d8482611a5881866112d2565b611e52565b505b6001600160a01b03821615611a8c576000611a7983610894565b9050611a8a8382611a5881866111f5565b505b6008546001600160a01b031680156115b757604051634a39314960e01b81526001600160a01b03821690634a39314990611ace90879087908790600401612371565b600060405180830381600087803b158015611ae857600080fd5b505af1158015611afc573d6000803e3d6000fd5b5050505050505050565b611b18826001600160a01b0316611fb9565b611b345760405162461bcd60e51b815260040161055c906127a3565b60006060836001600160a01b031683604051611b509190612341565b6000604051808303816000865af19150503d8060008114611b8d576040519150601f19603f3d011682016040523d82523d6000602084013e611b92565b606091505b509150915081611bb45760405162461bcd60e51b815260040161055c906124ff565b8051156115b75780806020019051810190611bcf9190612225565b6115b75760405162461bcd60e51b815260040161055c90612722565b6001600160a01b038316611c115760405162461bcd60e51b815260040161055c90612662565b6001600160a01b038216611c375760405162461bcd60e51b815260040161055c90612416565b611c42838383611a0e565b611c7f816040518060600160405280602681526020016128e1602691396001600160a01b03861660009081526020819052604090205491906115bd565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611cae90826111f5565b6001600160a01b0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906112c5908590612863565b6000831580611d0d575081155b80611d20575042836001600160801b0316145b80611d5457507f0000000000000000000000000000000000000000000000000000000000000000836001600160801b031610155b15611d60575083611124565b60007f00000000000000000000000000000000000000000000000000000000000000004211611d8f5742611db1565b7f00000000000000000000000000000000000000000000000000000000000000005b90506000611dc8826001600160801b0387166112d2565b9050611dee876110f5866110fb670de0b6b3a7640000611de88c8861192b565b9061192b565b979650505050505050565b6000611124670de0b6b3a76400006110fb611e1486866112d2565b879061192b565b60008183611e3c5760405162461bcd60e51b815260040161055c91906123e3565b506000838581611e4857fe5b0495945050505050565b6001600160a01b03831660009081526007602090815260408083205460069092529091204391908115801590611eb757506001600160801b038316816000611e9b8560016112d2565b81526020810191909152604001600020546001600160801b0316145b15611efb5783816000611ecb8560016112d2565b8152602081019190915260400160002080546001600160801b03928316600160801b029216919091179055611f76565b6040805180820182526001600160801b0380861682528681166020808401918252600087815290869052939093209151825493518216600160801b029082166001600160801b03199094169390931716919091179055611f5c8260016111f5565b6001600160a01b0387166000908152600760205260409020555b7f2cd3c83ddac2953ee75f53265d9ea4463eaf05030e5459a1b7e63819b7ce88f7868686604051611fa993929190612395565b60405180910390a1505050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611124575050151592915050565b604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061205d57805160ff191683800117855561208a565b8280016001018555821561208a579182015b8281111561208a57825182559160200191906001019061206f565b5061209692915061209a565b5090565b5b80821115612096576000815560010161209b565b60008083601f8401126120c0578182fd5b50813567ffffffffffffffff8111156120d7578182fd5b6020830191508360208285010111156120ef57600080fd5b9250929050565b600060208284031215612107578081fd5b813561078d816128a6565b60008060408385031215612124578081fd5b823561212f816128a6565b9150602083013561213f816128a6565b809150509250929050565b60008060006060848603121561215e578081fd5b8335612169816128a6565b92506020840135612179816128a6565b929592945050506040919091013590565b6000806040838503121561219c578182fd5b82356121a7816128a6565b946020939093013593505050565b600080602083850312156121c7578182fd5b823567ffffffffffffffff808211156121de578384fd5b818501915085601f8301126121f1578384fd5b8135818111156121ff578485fd5b866020606083028501011115612213578485fd5b60209290920196919550909350505050565b600060208284031215612236578081fd5b8151801515811461078d578182fd5b6000806000806000806080878903121561225d578182fd5b8635612268816128a6565b9550602087013567ffffffffffffffff80821115612284578384fd5b6122908a838b016120af565b909750955060408901359150808211156122a8578384fd5b506122b589828a016120af565b909450925050606087013560ff811681146122ce578182fd5b809150509295509295509295565b6000602082840312156122ed578081fd5b81356001600160801b038116811461078d578182fd5b60008060008060808587031215612318578384fd5b84359350602085013592506040850135612331816128a6565b9396929550929360600135925050565b6000825161235381846020870161287a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039390931683526001600160801b03918216602084015216604082015260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252825180602084015261240281604085016020870161287a565b601f01601f19169190910160400192915050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601390820152721253959053125117d6915493d7d05353d55395606a1b604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526015908201527424a729aaa32324a1a4a2a72a2fa1a7a7a62227aba760591b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526015908201527427a7262cafa2a6a4a9a9a4a7a72fa6a0a720a3a2a960591b604082015260600190565b60208082526021908201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526025908201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526017908201527f554e5354414b455f57494e444f575f46494e4953484544000000000000000000604082015260600190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646040820152637265737360e01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601b908201527f494e56414c49445f42414c414e43455f4f4e5f434f4f4c444f574e0000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b6020808252601f908201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b6001600160801b0391909116815260200190565b6001600160801b0392831681529116602082015260400190565b6001600160801b039384168152919092166020820152604081019190915260600190565b90815260200190565b60ff91909116815260200190565b60005b8381101561289557818101518382015260200161287d565b838111156115b75750506000910152565b6001600160a01b03811681146128bb57600080fd5b5056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212200aaf30318f6fba50199f5b888b6a82fb87c7ae90d3ffa0e30faacf2b6ff136ce64736f6c634300060c00330000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae90000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae900000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000000002a30000000000000000000000000025f2226b597e8f9514b3f68f00f494cf4f2864910000000000000000000000008a2efd9a790199f4c94c6effe210fce0b4724f520000000000000000000000000000000000000000000000000000000000c5c100
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102115760003560e01c80638dbefee211610125578063adc9772e116100ad578063dd62ed3e1161007c578063dd62ed3e14610410578063dde43cba14610423578063f11b81881461042b578063f1cc432a1461044d578063f6d2ee861461046057610211565b8063adc9772e146103da578063b2a5dbfa146103ed578063c3863ada14610400578063cbcbb5071461040857610211565b806399248ea7116100f457806399248ea7146103915780639a99b4f014610399578063a457c2d7146103ac578063a9059cbb146103bf578063aaf5eb68146103d257610211565b80638dbefee214610366578063919cd40f14610379578063946776cd1461038157806395d89b411461038957610211565b8063313ce567116101a857806370a082311161017757806370a082311461031d57806372b49d6314610330578063787a08a6146103385780637e90d7ef146103405780638779588c1461035357610211565b8063313ce567146102da5780633373ee4c146102ef578063359c4a9614610302578063395093511461030a57610211565b80631e9a6950116101e45780631e9a69501461027c57806323b872dd146102915780632acbf823146102a4578063312f6b83146102c557610211565b806306fdde0314610216578063091030c314610234578063095ea7b31461025457806318160ddd14610274575b600080fd5b61021e610473565b60405161022b91906123e3565b60405180910390f35b6102476102423660046120f6565b610509565b60405161022b9190612863565b61026761026236600461218a565b61051b565b60405161022b91906123d8565b610247610539565b61028f61028a36600461218a565b61053f565b005b61026761029f36600461214a565b61070c565b6102b76102b236600461218a565b610794565b60405161022b929190612825565b6102cd6107c5565b60405161022b919061235d565b6102e26107e9565b60405161022b919061286c565b6102476102fd366004612112565b6107f2565b610247610822565b61026761031836600461218a565b610846565b61024761032b3660046120f6565b610894565b6102476108af565b61028f6108d3565b61024761034e3660046120f6565b610932565b6102476103613660046120f6565b610944565b6102476103743660046120f6565b610956565b610247610a05565b6102cd610a29565b61021e610a4d565b6102cd610aae565b61028f6103a736600461218a565b610ad2565b6102676103ba36600461218a565b610bf0565b6102676103cd36600461218a565b610c58565b6102e2610c6c565b61028f6103e836600461218a565b610c71565b61028f6103fb3660046121b5565b610dd6565b6102cd610f89565b6102cd610f98565b61024761041e366004612112565b610fbc565b610247610fe7565b61043e6104393660046120f6565b610fec565b60405161022b9392919061283f565b61024761045b366004612303565b61101a565b61028f61046e366004612245565b61112c565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104ff5780601f106104d4576101008083540402835291602001916104ff565b820191906000526020600020905b8154815290600101906020018083116104e257829003601f168201915b5050505050905090565b603e6020526000908152604090205481565b600061052f61052861121a565b848461121e565b5060015b92915050565b60025490565b806105655760405162461bcd60e51b815260040161055c906124d2565b60405180910390fd5b336000908152603e602052604090205461059f817f00000000000000000000000000000000000000000000000000000000000d2f006111f5565b42116105bd5760405162461bcd60e51b815260040161055c90612534565b7f000000000000000000000000000000000000000000000000000000000002a30061061261060b837f00000000000000000000000000000000000000000000000000000000000d2f006111f5565b42906112d2565b11156106305760405162461bcd60e51b815260040161055c906126a7565b600061063b33610894565b9050600081841161064c578361064e565b815b905061065c33836001611314565b5061066733826113b9565b61067182826112d2565b61068657336000908152603e60205260408120555b6106ba6001600160a01b037f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae916868361149b565b846001600160a01b0316336001600160a01b03167fd12200efa34901b99367694174c3b0d32c99585fdf37c7c26892136ddd0836d9836040516106fd9190612863565b60405180910390a35050505050565b60006107198484846114f1565b6107898461072561121a565b61078485604051806060016040528060288152602001612907602891396001600160a01b038a1660009081526001602052604081209061076361121a565b6001600160a01b0316815260208101919091526040016000205491906115bd565b61121e565b5060015b9392505050565b60066020908152600092835260408084209091529082529020546001600160801b0380821691600160801b90041682565b7f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae981565b60055460ff1690565b6001600160a01b038082166000908152603c60209081526040808320938616835260029093019052205492915050565b7f000000000000000000000000000000000000000000000000000000000002a30081565b600061052f61085361121a565b84610784856001600061086461121a565b6001600160a01b03908116825260208083019390935260409182016000908120918c1681529252902054906111f5565b6001600160a01b031660009081526020819052604090205490565b7f00000000000000000000000000000000000000000000000000000000000d2f0081565b6108dc33610894565b6108f85760405162461bcd60e51b815260040161055c9061276c565b336000818152603e6020526040808220429055517ff52f50426b32362d3e6bb8cb36b7074756b224622def6352a59eac7f66ebe6e89190a2565b603d6020526000908152604090205481565b60076020526000908152604090205481565b60408051600180825281830190925260009160609190816020015b610979611ff2565b8152602001906001900390816109715790505090506040518060600160405280306001600160a01b031681526020016109b185610894565b81526020016109be610539565b815250816000815181106109ce57fe5b602002602001018190525061078d6109e684836115e9565b6001600160a01b0385166000908152603d6020526040902054906111f5565b7f000000000000000000000000000000000000000000000000000000006032aa0081565b7f00000000000000000000000025f2226b597e8f9514b3f68f00f494cf4f28649181565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104ff5780601f106104d4576101008083540402835291602001916104ff565b7f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae981565b6000610ae833610ae133610894565b6000611314565b905060006000198314610afb5782610afd565b815b9050610b3a816040518060400160405280600e81526020016d1253959053125117d05353d5539560921b815250846115bd9092919063ffffffff16565b336000908152603d6020526040902055610b9f7f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae96001600160a01b03167f00000000000000000000000025f2226b597e8f9514b3f68f00f494cf4f28649186846116da565b836001600160a01b0316336001600160a01b03167f9310ccfcb8de723f578a9e4282ea9f521f05ae40dc08f3068dfad528a65ee3c783604051610be29190612863565b60405180910390a350505050565b600061052f610bfd61121a565b846107848560405180606001604052806025815260200161292f6025913960016000610c2761121a565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906115bd565b600061052f610c6561121a565b84846114f1565b601281565b80610c8e5760405162461bcd60e51b815260040161055c906124d2565b6000610c9983610894565b90506000610cb0843084610cab610539565b6116fb565b90508015610d2e577f2468f9268c60ad90e2d49edb0032c8a001e733ae888b3ab8e982edf535be1a768482604051610ce99291906123bf565b60405180910390a16001600160a01b0384166000908152603d6020526040902054610d1490826111f5565b6001600160a01b0385166000908152603d60205260409020555b610d3b600084868561101a565b6001600160a01b0385166000908152603e6020526040902055610d5e84846117ba565b610d936001600160a01b037f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9163330866116da565b836001600160a01b0316336001600160a01b03167f5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd785604051610be29190612863565b336001600160a01b037f0000000000000000000000008a2efd9a790199f4c94c6effe210fce0b4724f521614610e1e5760405162461bcd60e51b815260040161055c906125f2565b60005b81811015610f84576000603c6000858585818110610e3b57fe5b9050606002016040016020810190610e5391906120f6565b6001600160a01b03166001600160a01b031681526020019081526020016000209050610eb8848484818110610e8457fe5b9050606002016040016020810190610e9c91906120f6565b82868686818110610ea957fe5b9050606002016020013561186e565b50838383818110610ec557fe5b610edb92602060609092020190810191506122dc565b81546001600160801b0319166001600160801b0391909116178155838383818110610f0257fe5b9050606002016040016020810190610f1a91906120f6565b6001600160a01b03167f87fa03892a0556cb6b8f97e6d533a150d4d55fcbf275fff5fa003fa636bcc7fa858585818110610f5057fe5b610f6692602060609092020190810191506122dc565b604051610f739190612811565b60405180910390a250600101610e21565b505050565b6008546001600160a01b031681565b7f0000000000000000000000008a2efd9a790199f4c94c6effe210fce0b4724f5281565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600181565b603c60205260009081526040902080546001909101546001600160801b0380831692600160801b9004169083565b6001600160a01b0382166000908152603e602052604081205480611042576000915050611124565b60006110987f000000000000000000000000000000000000000000000000000000000002a300611092427f00000000000000000000000000000000000000000000000000000000000d2f006112d2565b906112d2565b9050818111156110ab5760009150611105565b60008782116110ba57876110bc565b425b9050828110156110d157829350505050611124565b6111016110de88876111f5565b6110fb6110eb888761192b565b6110f58b8661192b565b906111f5565b90611965565b9250505b506001600160a01b0384166000908152603e6020526040902081905590505b949350505050565b60006111366119a7565b905060095481116111595760405162461bcd60e51b815260040161055c906125a4565b6009819055604080516020601f880181900481028201810190925286815261119b9188908890819084018382808284376000920191909152506119ac92505050565b6111da84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119c392505050565b6111e3826119d6565b6111ec876119ec565b50505050505050565b60008282018381101561078d5760405162461bcd60e51b815260040161055c9061249b565b3390565b6001600160a01b0383166112445760405162461bcd60e51b815260040161055c906126de565b6001600160a01b03821661126a5760405162461bcd60e51b815260040161055c90612459565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906112c5908590612863565b60405180910390a3505050565b600061078d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506115bd565b600080611325853086610cab610539565b6001600160a01b0386166000908152603d60205260408120549192509061134c90836111f5565b905081156113b0578315611376576001600160a01b0386166000908152603d602052604090208190555b7f2468f9268c60ad90e2d49edb0032c8a001e733ae888b3ab8e982edf535be1a7686836040516113a79291906123bf565b60405180910390a15b95945050505050565b6001600160a01b0382166113df5760405162461bcd60e51b815260040161055c90612621565b6113eb82600083611a0e565b611428816040518060600160405280602281526020016128bf602291396001600160a01b03851660009081526020819052604090205491906115bd565b6001600160a01b03831660009081526020819052604090205560025461144e90826112d2565b6002556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061148f908590612863565b60405180910390a35050565b610f848363a9059cbb60e01b84846040516024016114ba9291906123bf565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611b06565b60006114fc84610894565b905061150a84826001611314565b50826001600160a01b0316846001600160a01b0316146115ac57600061152f84610894565b905061153d84826001611314565b506001600160a01b0385166000908152603e60205260409020546115638185878561101a565b6001600160a01b0386166000908152603e6020526040902055828414801561158a57508015155b156115a9576001600160a01b0386166000908152603e60205260408120555b50505b6115b7848484611beb565b50505050565b600081848411156115e15760405162461bcd60e51b815260040161055c91906123e3565b505050900390565b600080805b83518110156116d2576000603c600086848151811061160957fe5b602090810291909101810151516001600160a01b031682528101919091526040016000908120600181015481548851929450611671926001600160801b0380831692600160801b900416908a908890811061166057fe5b602002602001015160400151611d00565b90506116c66116bf87858151811061168557fe5b602002602001015160200151838560020160008c6001600160a01b03166001600160a01b0316815260200190815260200160002054611df9565b85906111f5565b935050506001016115ee565b509392505050565b6115b7846323b872dd60e01b8585856040516024016114ba93929190612371565b6001600160a01b038084166000908152603c60209081526040808320938816835260028401909152812054909190828061173688858861186e565b90508083146117ae57861561175357611750878285611df9565b91505b6001600160a01b03808a1660008181526002870160205260409081902084905551918a16917fbb123b5c06d5408bbea3c4fef481578175cfb432e3b482c6186f02ed9086585b906117a5908590612863565b60405180910390a35b50979650505050505050565b6001600160a01b0382166117e05760405162461bcd60e51b815260040161055c906127da565b6117ec60008383611a0e565b6002546117f990826111f5565b6002556001600160a01b03821660009081526020819052604090205461181f90826111f5565b6001600160a01b0383166000818152602081905260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061148f908590612863565b6001820154825460009190600160801b90046001600160801b0316428114156118995750905061078d565b84546000906118b49084906001600160801b03168488611d00565b905082811461190857808660010181905550866001600160a01b03167f5777ca300dfe5bead41006fbce4389794dbc0ed8d6cccebfaf94630aa04184bc826040516118ff9190612863565b60405180910390a25b85546001600160801b03428116600160801b029116178655925050509392505050565b60008261193a57506000610533565b8282028284828161194757fe5b041461078d5760405162461bcd60e51b815260040161055c90612563565b600061078d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e1b565b600190565b80516119bf90600390602084019061201c565b5050565b80516119bf90600490602084019061201c565b6005805460ff191660ff92909216919091179055565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b816001600160a01b0316836001600160a01b03161415611a2d57610f84565b6001600160a01b03831615611a5f576000611a4784610894565b9050611a5d8482611a5881866112d2565b611e52565b505b6001600160a01b03821615611a8c576000611a7983610894565b9050611a8a8382611a5881866111f5565b505b6008546001600160a01b031680156115b757604051634a39314960e01b81526001600160a01b03821690634a39314990611ace90879087908790600401612371565b600060405180830381600087803b158015611ae857600080fd5b505af1158015611afc573d6000803e3d6000fd5b5050505050505050565b611b18826001600160a01b0316611fb9565b611b345760405162461bcd60e51b815260040161055c906127a3565b60006060836001600160a01b031683604051611b509190612341565b6000604051808303816000865af19150503d8060008114611b8d576040519150601f19603f3d011682016040523d82523d6000602084013e611b92565b606091505b509150915081611bb45760405162461bcd60e51b815260040161055c906124ff565b8051156115b75780806020019051810190611bcf9190612225565b6115b75760405162461bcd60e51b815260040161055c90612722565b6001600160a01b038316611c115760405162461bcd60e51b815260040161055c90612662565b6001600160a01b038216611c375760405162461bcd60e51b815260040161055c90612416565b611c42838383611a0e565b611c7f816040518060600160405280602681526020016128e1602691396001600160a01b03861660009081526020819052604090205491906115bd565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611cae90826111f5565b6001600160a01b0380841660008181526020819052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906112c5908590612863565b6000831580611d0d575081155b80611d20575042836001600160801b0316145b80611d5457507f000000000000000000000000000000000000000000000000000000006032aa00836001600160801b031610155b15611d60575083611124565b60007f000000000000000000000000000000000000000000000000000000006032aa004211611d8f5742611db1565b7f000000000000000000000000000000000000000000000000000000006032aa005b90506000611dc8826001600160801b0387166112d2565b9050611dee876110f5866110fb670de0b6b3a7640000611de88c8861192b565b9061192b565b979650505050505050565b6000611124670de0b6b3a76400006110fb611e1486866112d2565b879061192b565b60008183611e3c5760405162461bcd60e51b815260040161055c91906123e3565b506000838581611e4857fe5b0495945050505050565b6001600160a01b03831660009081526007602090815260408083205460069092529091204391908115801590611eb757506001600160801b038316816000611e9b8560016112d2565b81526020810191909152604001600020546001600160801b0316145b15611efb5783816000611ecb8560016112d2565b8152602081019190915260400160002080546001600160801b03928316600160801b029216919091179055611f76565b6040805180820182526001600160801b0380861682528681166020808401918252600087815290869052939093209151825493518216600160801b029082166001600160801b03199094169390931716919091179055611f5c8260016111f5565b6001600160a01b0387166000908152600760205260409020555b7f2cd3c83ddac2953ee75f53265d9ea4463eaf05030e5459a1b7e63819b7ce88f7868686604051611fa993929190612395565b60405180910390a1505050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611124575050151592915050565b604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061205d57805160ff191683800117855561208a565b8280016001018555821561208a579182015b8281111561208a57825182559160200191906001019061206f565b5061209692915061209a565b5090565b5b80821115612096576000815560010161209b565b60008083601f8401126120c0578182fd5b50813567ffffffffffffffff8111156120d7578182fd5b6020830191508360208285010111156120ef57600080fd5b9250929050565b600060208284031215612107578081fd5b813561078d816128a6565b60008060408385031215612124578081fd5b823561212f816128a6565b9150602083013561213f816128a6565b809150509250929050565b60008060006060848603121561215e578081fd5b8335612169816128a6565b92506020840135612179816128a6565b929592945050506040919091013590565b6000806040838503121561219c578182fd5b82356121a7816128a6565b946020939093013593505050565b600080602083850312156121c7578182fd5b823567ffffffffffffffff808211156121de578384fd5b818501915085601f8301126121f1578384fd5b8135818111156121ff578485fd5b866020606083028501011115612213578485fd5b60209290920196919550909350505050565b600060208284031215612236578081fd5b8151801515811461078d578182fd5b6000806000806000806080878903121561225d578182fd5b8635612268816128a6565b9550602087013567ffffffffffffffff80821115612284578384fd5b6122908a838b016120af565b909750955060408901359150808211156122a8578384fd5b506122b589828a016120af565b909450925050606087013560ff811681146122ce578182fd5b809150509295509295509295565b6000602082840312156122ed578081fd5b81356001600160801b038116811461078d578182fd5b60008060008060808587031215612318578384fd5b84359350602085013592506040850135612331816128a6565b9396929550929360600135925050565b6000825161235381846020870161287a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039390931683526001600160801b03918216602084015216604082015260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252825180602084015261240281604085016020870161287a565b601f01601f19169190910160400192915050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601390820152721253959053125117d6915493d7d05353d55395606a1b604082015260600190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b60208082526015908201527424a729aaa32324a1a4a2a72a2fa1a7a7a62227aba760591b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526015908201527427a7262cafa2a6a4a9a9a4a7a72fa6a0a720a3a2a960591b604082015260600190565b60208082526021908201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526025908201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526017908201527f554e5354414b455f57494e444f575f46494e4953484544000000000000000000604082015260600190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646040820152637265737360e01b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601b908201527f494e56414c49445f42414c414e43455f4f4e5f434f4f4c444f574e0000000000604082015260600190565b6020808252601f908201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604082015260600190565b6020808252601f908201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b6001600160801b0391909116815260200190565b6001600160801b0392831681529116602082015260400190565b6001600160801b039384168152919092166020820152604081019190915260600190565b90815260200190565b60ff91909116815260200190565b60005b8381101561289557818101518382015260200161287d565b838111156115b75750506000910152565b6001600160a01b03811681146128bb57600080fd5b5056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212200aaf30318f6fba50199f5b888b6a82fb87c7ae90d3ffa0e30faacf2b6ff136ce64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae90000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae900000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000000002a30000000000000000000000000025f2226b597e8f9514b3f68f00f494cf4f2864910000000000000000000000008a2efd9a790199f4c94c6effe210fce0b4724f520000000000000000000000000000000000000000000000000000000000c5c100
-----Decoded View---------------
Arg [0] : stakedToken (address): 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9
Arg [1] : rewardToken (address): 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9
Arg [2] : cooldownSeconds (uint256): 864000
Arg [3] : unstakeWindow (uint256): 172800
Arg [4] : rewardsVault (address): 0x25F2226B597E8F9514B3F68F00f494cF4f286491
Arg [5] : emissionManager (address): 0x8a2Efd9A790199F4c94c6effE210fce0B4724f52
Arg [6] : distributionDuration (uint128): 12960000
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9
Arg [1] : 0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9
Arg [2] : 00000000000000000000000000000000000000000000000000000000000d2f00
Arg [3] : 000000000000000000000000000000000000000000000000000000000002a300
Arg [4] : 00000000000000000000000025f2226b597e8f9514b3f68f00f494cf4f286491
Arg [5] : 0000000000000000000000008a2efd9a790199f4c94c6effe210fce0b4724f52
Arg [6] : 0000000000000000000000000000000000000000000000000000000000c5c100
Deployed Bytecode Sourcemap
45411:611:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10973:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36231:51;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;12732:159::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;11420:94::-;;;:::i;38480:998::-;;;;;;:::i;:::-;;:::i;:::-;;13227:355;;;;;;:::i;:::-;;:::i;17097:68::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;35782:36::-;;;:::i;:::-;;;;;;;:::i;11269:86::-;;;:::i;:::-;;;;;;;:::i;35189:130::-;;;;;;:::i;:::-;;:::i;35994:39::-;;;:::i;13830:208::-;;;;;;:::i;:::-;;:::i;11574:113::-;;;;;;:::i;:::-;;:::i;35864:41::-;;;:::i;39605:236::-;;;:::i;36171:55::-;;;;;;:::i;:::-;;:::i;17172:52::-;;;;;;:::i;:::-;;:::i;44538:480::-;;;;;;:::i;:::-;;:::i;27720:41::-;;;:::i;36126:38::-;;;:::i;11118:90::-;;;:::i;35823:36::-;;;:::i;40003:521::-;;;;;;:::i;:::-;;:::i;14296:332::-;;;;;;:::i;:::-;;:::i;11949:165::-;;;;;;:::i;:::-;;:::i;27816:36::-;;;:::i;37541:785::-;;;;;;:::i;:::-;;:::i;28481:718::-;;;;;;:::i;:::-;;:::i;17521:36::-;;;:::i;27768:41::-;;;:::i;12388:173::-;;;;;;:::i;:::-;;:::i;35739:36::-;;;:::i;27859:43::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;43283:1104::-;;;;;;:::i;:::-;;:::i;37280:255::-;;;;;;:::i;:::-;;:::i;10973:86::-;11048:5;11041:12;;;;;;;;-1:-1:-1;;11041:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11019:13;;11041:12;;11048:5;;11041:12;;11048:5;11041:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10973:86;:::o;36231:51::-;;;;;;;;;;;;;:::o;12732:159::-;12815:4;12828:39;12837:12;:10;:12::i;:::-;12851:7;12860:6;12828:8;:39::i;:::-;-1:-1:-1;12881:4:0;12732:159;;;;;:::o;11420:94::-;11496:12;;11420:94;:::o;38480:998::-;38557:11;38549:43;;;;-1:-1:-1;;;38549:43:0;;;;;;;:::i;:::-;;;;;;;;;38681:10;38631:30;38664:28;;;:16;:28;;;;;;38733:44;38664:28;38760:16;38733:26;:44::i;:::-;38715:15;:62;38699:117;;;;-1:-1:-1;;;38699:117:0;;;;;;;:::i;:::-;38908:14;38839:65;38859:44;:22;38886:16;38859:26;:44::i;:::-;38839:15;;:19;:65::i;:::-;:83;;38823:140;;;;-1:-1:-1;;;38823:140:0;;;;;;;:::i;:::-;38970:30;39003:21;39013:10;39003:9;:21::i;:::-;38970:54;;39033:22;39068;39059:6;:31;39058:67;;39119:6;39058:67;;;39094:22;39058:67;39033:92;;39134:72;39165:10;39177:22;39201:4;39134:30;:72::i;:::-;;39215:33;39221:10;39233:14;39215:5;:33::i;:::-;39261:42;:22;39288:14;39261:26;:42::i;:::-;39257:102;;39336:10;39350:1;39319:28;;;:16;:28;;;;;:32;39257:102;39367:53;-1:-1:-1;;;;;39374:12:0;39367:33;39401:2;39405:14;39367:33;:53::i;:::-;39453:2;-1:-1:-1;;;;;39434:38:0;39441:10;-1:-1:-1;;;;;39434:38:0;;39457:14;39434:38;;;;;;:::i;:::-;;;;;;;;38480:998;;;;;:::o;13227:355::-;13353:4;13366:36;13376:6;13384:9;13395:6;13366:9;:36::i;:::-;13409:149;13426:6;13441:12;:10;:12::i;:::-;13462:89;13500:6;13462:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13462:19:0;;;;;;:11;:19;;;;;;13482:12;:10;:12::i;:::-;-1:-1:-1;;;;;13462:33:0;;;;;;;;;;;;-1:-1:-1;13462:33:0;;;:89;:37;:89::i;:::-;13409:8;:149::i;:::-;-1:-1:-1;13572:4:0;13227:355;;;;;;:::o;17097:68::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;17097:68:0;;;;-1:-1:-1;;;17097:68:0;;;;:::o;35782:36::-;;;:::o;11269:86::-;11340:9;;;;11269:86;:::o;35189:130::-;-1:-1:-1;;;;;35288:13:0;;;35265:7;35288:13;;;:6;:13;;;;;;;;:25;;;;;:19;;;;:25;;;;35189:130;;;;:::o;35994:39::-;;;:::o;13830:208::-;13918:4;13931:83;13940:12;:10;:12::i;:::-;13954:7;13963:50;14002:10;13963:11;:25;13975:12;:10;:12::i;:::-;-1:-1:-1;;;;;13963:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;13963:25:0;;;:34;;;;;;;;;;;:38;:50::i;11574:113::-;-1:-1:-1;;;;;11663:18:0;11640:7;11663:18;;;;;;;;;;;;11574:113::o;35864:41::-;;;:::o;39605:236::-;39658:21;39668:10;39658:9;:21::i;:::-;39650:66;;;;-1:-1:-1;;;39650:66:0;;;;;;;:::i;:::-;39772:10;39755:28;;;;:16;:28;;;;;;39786:15;39755:46;;39815:20;;;39755:28;39815:20;39605:236::o;36171:55::-;;;;;;;;;;;;;:::o;17172:52::-;;;;;;;;;;;;;:::o;44538:480::-;44695:41;;;44734:1;44695:41;;;;;;;;;44609:7;;44629:57;;44695:41;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;44629:107;;44764:155;;;;;;;;44831:4;-1:-1:-1;;;;;44764:155:0;;;;;44859:17;44869:6;44859:9;:17::i;:::-;44764:155;;;;44898:13;:11;:13::i;:::-;44764:155;;;44743:15;44759:1;44743:18;;;;;;;;;;;;;:176;;;;44933:79;44966:45;44987:6;44995:15;44966:20;:45::i;:::-;-1:-1:-1;;;;;44933:28:0;;;;;;:20;:28;;;;;;;:32;:79::i;27720:41::-;;;:::o;36126:38::-;;;:::o;11118:90::-;11195:7;11188:14;;;;;;;;-1:-1:-1;;11188:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11166:13;;11188:14;;11195:7;;11188:14;;11195:7;11188:14;;;;;;;;;;;;;;;;;;;;;;;;35823:36;;;:::o;40003:521::-;40078:23;40104:100;40143:10;40162:21;40172:10;40162:9;:21::i;:::-;40192:5;40104:30;:100::i;:::-;40078:126;;40211:21;-1:-1:-1;;40236:6:0;:27;40235:56;;40285:6;40235:56;;;40267:15;40235:56;40211:80;;40335:52;40355:13;40335:52;;;;;;;;;;;;;-1:-1:-1;;;40335:52:0;;;:15;:19;;:52;;;;;:::i;:::-;40321:10;40300:32;;;;:20;:32;;;;;:87;40396:63;:12;-1:-1:-1;;;;;40396:29:0;40426:13;40441:2;40445:13;40396:29;:63::i;:::-;40500:2;-1:-1:-1;;;;;40473:45:0;40488:10;-1:-1:-1;;;;;40473:45:0;;40504:13;40473:45;;;;;;:::i;:::-;;;;;;;;40003:521;;;;:::o;14296:332::-;14404:4;14420:184;14437:12;:10;:12::i;:::-;14458:7;14474:123;14523:15;14474:123;;;;;;;;;;;;;;;;;:11;:25;14486:12;:10;:12::i;:::-;-1:-1:-1;;;;;14474:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;14474:25:0;;;:34;;;;;;;;;;;:123;:38;:123::i;11949:165::-;12035:4;12048:42;12058:12;:10;:12::i;:::-;12072:9;12083:6;12048:9;:42::i;27816:36::-;27850:2;27816:36;:::o;37541:785::-;37625:11;37617:43;;;;-1:-1:-1;;;37617:43:0;;;;;;;:::i;:::-;37667:21;37691;37701:10;37691:9;:21::i;:::-;37667:45;;37721:22;37746:116;37779:10;37806:4;37820:13;37842;:11;:13::i;:::-;37746:24;:116::i;:::-;37721:141;-1:-1:-1;37873:19:0;;37869:185;;37908:42;37923:10;37935:14;37908:42;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;37994:32:0;;;;;;:20;:32;;;;;;:52;;38031:14;37994:36;:52::i;:::-;-1:-1:-1;;;;;37959:32:0;;;;;;:20;:32;;;;;:87;37869:185;38093:62;38118:1;38121:6;38129:10;38141:13;38093:24;:62::i;:::-;-1:-1:-1;;;;;38062:28:0;;;;;;:16;:28;;;;;:93;38164:25;38079:10;38182:6;38164:5;:25::i;:::-;38196:72;-1:-1:-1;;;;;38203:12:0;38196:37;38234:10;38254:4;38261:6;38196:37;:72::i;:::-;38301:10;-1:-1:-1;;;;;38282:38:0;38289:10;-1:-1:-1;;;;;38282:38:0;;38313:6;38282:38;;;;;;:::i;28481:718::-;28604:10;-1:-1:-1;;;;;28618:16:0;28604:30;;28596:64;;;;-1:-1:-1;;;28596:64:0;;;;;;;:::i;:::-;28674:9;28669:525;28689:28;;;28669:525;;;28733:29;28765:6;:44;28772:17;;28790:1;28772:20;;;;;;;;;;;;:36;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;28765:44:0;-1:-1:-1;;;;;28765:44:0;;;;;;;;;;;;28733:76;;28820:146;28856:17;;28874:1;28856:20;;;;;;;;;;;;:36;;;;;;;;;;:::i;:::-;28903:11;28925:17;;28943:1;28925:20;;;;;;;;;;;;:32;;;28820:25;:146::i;:::-;;29009:17;;29027:1;29009:20;;;;;;;:38;;;:20;;;;;:38;;;;-1:-1:-1;29009:38:0;:::i;:::-;28977:70;;-1:-1:-1;;;;;;28977:70:0;-1:-1:-1;;;;;28977:70:0;;;;;;;29092:17;;29110:1;29092:20;;;;;;;;;;;;:36;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;29063:123:0;;29139:17;;29157:1;29139:20;;;;;;;:38;;;:20;;;;;:38;;;;-1:-1:-1;29139:38:0;:::i;:::-;29063:123;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;28719:3:0;;28669:525;;;;28481:718;;:::o;17521:36::-;;;-1:-1:-1;;;;;17521:36:0;;:::o;27768:41::-;;;:::o;12388:173::-;-1:-1:-1;;;;;12528:18:0;;;12502:7;12528:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;12388:173::o;35739:36::-;35774:1;35739:36;:::o;27859:43::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;27859:43:0;;;;-1:-1:-1;;;27859:43:0;;;;;:::o;43283:1104::-;-1:-1:-1;;;;;43498:27:0;;43452:7;43498:27;;;:16;:27;;;;;;43536:24;43532:55;;43578:1;43571:8;;;;;43532:55;43595:37;43635:71;43685:14;43635:37;:15;43655:16;43635:19;:37::i;:::-;:41;;:71::i;:::-;43595:111;;43751:19;43719:29;:51;43715:576;;;43803:1;43781:23;;43715:576;;;43827:29;43892:21;43860:29;:53;43859:115;;43953:21;43859:115;;;43926:15;43859:115;43827:147;;44013:19;43989:21;:43;43985:299;;;44052:19;44045:26;;;;;;;43985:299;44120:154;44243:30;:15;44263:9;44243:19;:30::i;:::-;44133:82;44180:34;:9;44194:19;44180:13;:34::i;:::-;44133:42;:15;44153:21;44133:19;:42::i;:::-;:46;;:82::i;:::-;44120:122;;:154::i;:::-;44098:176;;43715:576;;-1:-1:-1;;;;;;44297:27:0;;;;;;:16;:27;;;;;:49;;;44327:19;-1:-1:-1;43283:1104:0;;;;;;;:::o;37280:255::-;26086:16;26105:13;:11;:13::i;:::-;26086:32;;26162:23;;26151:8;:34;26129:130;;;;-1:-1:-1;;;26129:130:0;;;;;;;:::i;:::-;26272:23;:34;;;37420:14:::1;::::0;;::::1;;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;;::::1;::::0;37429:4;;;;;;37420:14;::::1;37429:4:::0;;;;37420:14;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;37420:8:0::1;::::0;-1:-1:-1;;;37420:14:0:i:1;:::-;37441:18;37452:6;;37441:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;37441:10:0::1;::::0;-1:-1:-1;;;37441:18:0:i:1;:::-;37466:22;37479:8;37466:12;:22::i;:::-;37495:34;37514:14;37495:18;:34::i;:::-;37280:255:::0;;;;;;;:::o;5689:181::-;5747:7;5779:5;;;5803:6;;;;5795:46;;;;-1:-1:-1;;;5795:46:0;;;;;;;:::i;4008:106::-;4096:10;4008:106;:::o;15937:348::-;-1:-1:-1;;;;;16055:19:0;;16047:68;;;;-1:-1:-1;;;16047:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;16130:21:0;;16122:68;;;;-1:-1:-1;;;16122:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;16199:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;;:36;;;16247:32;;;;;16229:6;;16247:32;:::i;:::-;;;;;;;;15937:348;;;:::o;6145:136::-;6203:7;6230:43;6234:1;6237;6230:43;;;;;;;;;;;;;;;;;:3;:43::i;41893:584::-;42026:7;42042:22;42067:108;42100:4;42121;42135:11;42155:13;:11;:13::i;42067:108::-;-1:-1:-1;;;;;42209:26:0;;42182:24;42209:26;;;:20;:26;;;;;;42042:133;;-1:-1:-1;42182:24:0;42209:46;;42042:133;42209:30;:46::i;:::-;42182:73;-1:-1:-1;42268:19:0;;42264:176;;42302:13;42298:85;;;-1:-1:-1;;;;;42328:26:0;;;;;;:20;:26;;;;;:45;;;42298:85;42396:36;42411:4;42417:14;42396:36;;;;;;;:::i;:::-;;;;;;;;42264:176;42455:16;41893:584;-1:-1:-1;;;;;41893:584:0:o;15535:396::-;-1:-1:-1;;;;;15615:21:0;;15607:67;;;;-1:-1:-1;;;15607:67:0;;;;;;;:::i;:::-;15683:49;15704:7;15721:1;15725:6;15683:20;:49::i;:::-;15762:68;15785:6;15762:68;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15762:18:0;;:9;:18;;;;;;;;;;;;:68;:22;:68::i;:::-;-1:-1:-1;;;;;15741:18:0;;:9;:18;;;;;;;;;;:89;15852:12;;:24;;15869:6;15852:16;:24::i;:::-;15837:12;:39;15888:37;;15914:1;;-1:-1:-1;;;;;15888:37:0;;;;;;;15918:6;;15888:37;:::i;:::-;;;;;;;;15535:396;;:::o;23619:176::-;23702:85;23721:5;23751:23;;;23776:2;23780:5;23728:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;23728:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;23728:58:0;-1:-1:-1;;;;;;23728:58:0;;;;;;;;;;23702:18;:85::i;40733:805::-;40839:21;40863:15;40873:4;40863:9;:15::i;:::-;40839:39;;40900:57;40931:4;40937:13;40952:4;40900:30;:57::i;:::-;;40996:2;-1:-1:-1;;;;;40988:10:0;:4;-1:-1:-1;;;;;40988:10:0;;40984:507;;41009:19;41031:13;41041:2;41031:9;:13::i;:::-;41009:35;;41053:53;41084:2;41088:11;41101:4;41053:30;:53::i;:::-;-1:-1:-1;;;;;;41150:22:0;;41117:30;41150:22;;;:16;:22;;;;;;41204:73;41150:22;41253:6;41261:2;41265:11;41204:24;:73::i;:::-;-1:-1:-1;;;;;41181:20:0;;;;;;:16;:20;;;;;:96;41381:23;;;:54;;;;-1:-1:-1;41408:27:0;;;41381:54;41377:107;;;-1:-1:-1;;;;;41448:22:0;;41473:1;41448:22;;;:16;:22;;;;;:26;41377:107;40984:507;;;41499:33;41515:4;41521:2;41525:6;41499:15;:33::i;:::-;40733:805;;;;:::o;6576:226::-;6696:7;6732:12;6724:6;;;;6716:29;;;;-1:-1:-1;;;6716:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;6768:5:0;;;6576:226::o;32509:678::-;32641:7;;;32695:459;32719:6;:13;32715:1;:17;32695:459;;;32748:29;32780:6;:33;32787:6;32794:1;32787:9;;;;;;;;;;;;;;;;;;;:25;-1:-1:-1;;;;;32780:33:0;;;;;;;;;;;32787:25;32780:33;;;32868:17;;;;32896:29;;32978:9;;32780:33;;-1:-1:-1;32843:165:0;;-1:-1:-1;;;;;32896:29:0;;;;-1:-1:-1;;;32936:31:0;;;;32978:6;;32985:1;;32978:9;;;;;;;;;;;;:21;;;32843:14;:165::i;:::-;32822:186;;33036:110;33065:72;33077:6;33084:1;33077:9;;;;;;;;;;;;;;:22;;;33101:10;33113:11;:17;;:23;33131:4;-1:-1:-1;;;;;33113:23:0;-1:-1:-1;;;;;33113:23:0;;;;;;;;;;;;;33065:11;:72::i;:::-;33036:14;;:18;:110::i;:::-;33019:127;-1:-1:-1;;;32734:3:0;;32695:459;;;-1:-1:-1;33167:14:0;32509:678;-1:-1:-1;;;32509:678:0:o;23803:204::-;23904:95;23923:5;23953:27;;;23982:4;23988:2;23992:5;23930:68;;;;;;;;;;:::i;30774:663::-;-1:-1:-1;;;;;30969:13:0;;;30923:7;30969:13;;;:6;:13;;;;;;;;31009:21;;;;;:15;;;:21;;;;;;30923:7;;30969:13;30923:7;;31091:56;30976:5;30969:13;31135:11;31091:25;:56::i;:::-;31072:75;;31173:8;31160:9;:21;31156:246;;31196:17;;31192:107;;31243:46;31255:12;31269:8;31279:9;31243:11;:46::i;:::-;31226:63;;31192:107;-1:-1:-1;;;;;31309:21:0;;;;;;;:15;;;:21;;;;;;;:32;;;31355:39;;;;;;;;;31333:8;;31355:39;:::i;:::-;;;;;;;;31156:246;-1:-1:-1;31417:14:0;30774:663;-1:-1:-1;;;;;;;30774:663:0:o;15173:356::-;-1:-1:-1;;;;;15253:21:0;;15245:65;;;;-1:-1:-1;;;15245:65:0;;;;;;;:::i;:::-;15319:49;15348:1;15352:7;15361:6;15319:20;:49::i;:::-;15392:12;;:24;;15409:6;15392:16;:24::i;:::-;15377:12;:39;-1:-1:-1;;;;;15444:18:0;;:9;:18;;;;;;;;;;;:30;;15467:6;15444:22;:30::i;:::-;-1:-1:-1;;;;;15423:18:0;;:9;:18;;;;;;;;;;;:51;;;;15486:37;;15423:18;;:9;15486:37;;;;15516:6;;15486:37;:::i;29619:740::-;29804:17;;;;29858:31;;29769:7;;29804:17;-1:-1:-1;;;29858:31:0;;-1:-1:-1;;;;;29858:31:0;29902:15;:38;;29898:76;;;-1:-1:-1;29958:8:0;-1:-1:-1;29951:15:0;;29898:76;30041:29;;29982:16;;30001:124;;30024:8;;-1:-1:-1;;;;;30041:29:0;30079:19;30107:11;30001:14;:124::i;:::-;29982:143;;30150:8;30138;:20;30134:129;;30189:8;30169:11;:17;;:28;;;;30229:15;-1:-1:-1;;;;;30211:44:0;;30246:8;30211:44;;;;;;:::i;:::-;;;;;;;;30134:129;30271:58;;-1:-1:-1;;;;;30313:15:0;30271:58;;-1:-1:-1;;;30271:58:0;;;;;;30345:8;-1:-1:-1;;;29619:740:0;;;;;:::o;7053:471::-;7111:7;7356:6;7352:47;;-1:-1:-1;7386:1:0;7379:8;;7352:47;7423:5;;;7427:1;7423;:5;:1;7447:5;;;;;:10;7439:56;;;;-1:-1:-1;;;7439:56:0;;;;;;;:::i;7992:132::-;8050:7;8077:39;8081:1;8084;8077:39;;;;;;;;;;;;;;;;;:3;:39::i;45128:92::-;35774:1;45128:92;:::o;16291:78::-;16348:15;;;;:5;;:15;;;;;:::i;:::-;;16291:78;:::o;16375:86::-;16436:19;;;;:7;;:19;;;;;:::i;16467:86::-;16524:9;:23;;-1:-1:-1;;16524:23:0;;;;;;;;;;;;16467:86::o;17761:126::-;17847:15;:32;;-1:-1:-1;;;;;;17847:32:0;-1:-1:-1;;;;;17847:32:0;;;;;;;;;;17761:126::o;19340:782::-;19453:2;-1:-1:-1;;;;;19445:10:0;:4;-1:-1:-1;;;;;19445:10:0;;19441:49;;;19472:7;;19441:49;-1:-1:-1;;;;;19506:18:0;;;19502:179;;19541:19;19563:15;19573:4;19563:9;:15::i;:::-;19541:37;-1:-1:-1;19593:76:0;19608:4;19541:37;19644:23;19541:37;19660:6;19644:15;:23::i;:::-;19593:14;:76::i;:::-;19502:179;;-1:-1:-1;;;;;19695:16:0;;;19691:167;;19728:17;19748:13;19758:2;19748:9;:13::i;:::-;19728:33;-1:-1:-1;19776:70:0;19791:2;19728:33;19823:21;19728:33;19837:6;19823:13;:21::i;19776:70::-;19691:167;;19979:15;;-1:-1:-1;;;;;19979:15:0;20009:34;;20005:110;;20060:43;;-1:-1:-1;;;20060:43:0;;-1:-1:-1;;;;;20060:25:0;;;;;:43;;20086:4;;20092:2;;20096:6;;20060:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19340:782;;;;:::o;24374:598::-;24462:27;24470:5;-1:-1:-1;;;;;24462:25:0;;:27::i;:::-;24454:71;;;;-1:-1:-1;;;24454:71:0;;;;;;;:::i;:::-;24599:12;24613:23;24648:5;-1:-1:-1;;;;;24640:19:0;24660:4;24640:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24598:67;;;;24684:7;24676:52;;;;-1:-1:-1;;;24676:52:0;;;;;;;:::i;:::-;24745:17;;:21;24741:224;;24887:10;24876:30;;;;;;;;;;;;:::i;:::-;24868:85;;;;-1:-1:-1;;;24868:85:0;;;;;;;:::i;14634:533::-;-1:-1:-1;;;;;14756:20:0;;14748:70;;;;-1:-1:-1;;;14748:70:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;14833:23:0;;14825:71;;;;-1:-1:-1;;;14825:71:0;;;;;;;:::i;:::-;14905:47;14926:6;14934:9;14945:6;14905:20;:47::i;:::-;14981:71;15003:6;14981:71;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14981:17:0;;:9;:17;;;;;;;;;;;;:71;:21;:71::i;:::-;-1:-1:-1;;;;;14961:17:0;;;:9;:17;;;;;;;;;;;:91;;;;15082:20;;;;;;;:32;;15107:6;15082:24;:32::i;:::-;-1:-1:-1;;;;;15059:20:0;;;:9;:20;;;;;;;;;;;;:55;;;;15126:35;;;;;;;;;;15154:6;;15126:35;:::i;34249:722::-;34421:7;34449:22;;;:50;;-1:-1:-1;34482:17:0;;34449:50;:99;;;;34533:15;34510:19;-1:-1:-1;;;;;34510:38:0;;34449:99;:149;;;;34582:16;34559:19;-1:-1:-1;;;;;34559:39:0;;;34449:149;34437:205;;;-1:-1:-1;34622:12:0;34615:19;;34437:205;34650:24;34695:16;34677:15;:34;:85;;34747:15;34677:85;;;34721:16;34677:85;34650:112;-1:-1:-1;34769:17:0;34789:41;34650:112;-1:-1:-1;;;;;34789:41:0;;:20;:41::i;:::-;34769:61;-1:-1:-1;34851:114:0;34944:12;34851:78;34916:12;34851:60;34888:22;34851:32;:17;34769:61;34851:21;:32::i;:::-;:36;;:60::i;:114::-;34837:128;34249:722;-1:-1:-1;;;;;;;34249:722:0:o;33541:245::-;33676:7;33699:81;33757:22;33699:53;33724:27;:12;33741:9;33724:16;:27::i;:::-;33699:20;;:24;:53::i;8612:379::-;8732:7;8834:12;8827:5;8819:28;;;;-1:-1:-1;;;8819:28:0;;;;;;;;:::i;:::-;;8858:9;8874:1;8870;:5;;;;;;;8612:379;-1:-1:-1;;;;;8612:379:0:o;18161:801::-;-1:-1:-1;;;;;18353:23:0;;18264:20;18353:23;;;:16;:23;;;;;;;;;18442:10;:17;;;;;;18295:12;;18353:23;18532:26;;;;;:102;;-1:-1:-1;;;;;;18562:72:0;;:14;:44;18577:28;:21;18603:1;18577:25;:28::i;:::-;18562:44;;;;;;;;;;;-1:-1:-1;18562:44:0;:56;-1:-1:-1;;;;;18562:56:0;:72;18532:102;18528:370;;;18704:8;18651:14;:44;18666:28;:21;18692:1;18666:25;:28::i;:::-;18651:44;;;;;;;;;;;-1:-1:-1;18651:44:0;:61;;-1:-1:-1;;;;;18651:61:0;;;-1:-1:-1;;;18651:61:0;;;;;;;;;18528:370;;;18785:32;;;;;;;;-1:-1:-1;;;;;18785:32:0;;;;;;;;;;;;;;;-1:-1:-1;18745:37:0;;;;;;;;;;;:72;;;;;;;;-1:-1:-1;;;18745:72:0;;;;-1:-1:-1;;;;;;18745:72:0;;;;;;;;;;;;;;18858:28;18760:21;18745:72;18858:25;:28::i;:::-;-1:-1:-1;;;;;18832:23:0;;;;;;:16;:23;;;;;:54;18528:370;18915:39;18928:5;18935:8;18945;18915:39;;;;;;;;:::i;:::-;;;;;;;;18161:801;;;;;;:::o;20941:641::-;21001:4;21482:20;;21312:66;21531:23;;;;;;:42;;-1:-1:-1;;21558:15:0;;;21523:51;-1:-1:-1;;20941:641:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;919:337;;;1034:3;1027:4;1019:6;1015:17;1011:27;1001:2;;-1:-1;;1042:12;1001:2;-1:-1;1072:20;;1112:18;1101:30;;1098:2;;;-1:-1;;1134:12;1098:2;1178:4;1170:6;1166:17;1154:29;;1229:3;1178:4;1209:17;1170:6;1195:32;;1192:41;1189:2;;;1246:1;;1236:12;1189:2;994:262;;;;;:::o;1671:241::-;;1775:2;1763:9;1754:7;1750:23;1746:32;1743:2;;;-1:-1;;1781:12;1743:2;85:6;72:20;97:33;124:5;97:33;:::i;1919:366::-;;;2040:2;2028:9;2019:7;2015:23;2011:32;2008:2;;;-1:-1;;2046:12;2008:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;2098:63;-1:-1;2198:2;2237:22;;72:20;97:33;72:20;97:33;:::i;:::-;2206:63;;;;2002:283;;;;;:::o;2292:491::-;;;;2430:2;2418:9;2409:7;2405:23;2401:32;2398:2;;;-1:-1;;2436:12;2398:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;2488:63;-1:-1;2588:2;2627:22;;72:20;97:33;72:20;97:33;:::i;:::-;2392:391;;2596:63;;-1:-1;;;2696:2;2735:22;;;;1468:20;;2392:391::o;2790:366::-;;;2911:2;2899:9;2890:7;2886:23;2882:32;2879:2;;;-1:-1;;2917:12;2879:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;2969:63;3069:2;3108:22;;;;1468:20;;-1:-1;;;2873:283::o;3163:469::-;;;3338:2;3326:9;3317:7;3313:23;3309:32;3306:2;;;-1:-1;;3344:12;3306:2;3402:17;3389:31;3440:18;;3432:6;3429:30;3426:2;;;-1:-1;;3462:12;3426:2;3599:6;3588:9;3584:22;;;360:3;353:4;345:6;341:17;337:27;327:2;;-1:-1;;368:12;327:2;411:6;398:20;3440:18;430:6;427:30;424:2;;;-1:-1;;460:12;424:2;555:3;3338:2;547:4;539:6;535:17;496:6;521:32;;518:41;515:2;;;-1:-1;;562:12;515:2;3338;492:17;;;;;3482:134;;-1:-1;3300:332;;-1:-1;;;;3300:332::o;3639:257::-;;3751:2;3739:9;3730:7;3726:23;3722:32;3719:2;;;-1:-1;;3757:12;3719:2;671:6;665:13;27601:5;25751:13;25744:21;27579:5;27576:32;27566:2;;-1:-1;;27612:12;3903:907;;;;;;;4117:3;4105:9;4096:7;4092:23;4088:33;4085:2;;;-1:-1;;4124:12;4085:2;826:6;813:20;838:54;886:5;838:54;:::i;:::-;4176:84;-1:-1;4325:2;4310:18;;4297:32;4349:18;4338:30;;;4335:2;;;-1:-1;;4371:12;4335:2;4409:65;4466:7;4457:6;4446:9;4442:22;4409:65;:::i;:::-;4391:83;;-1:-1;4391:83;-1:-1;4539:2;4524:18;;4511:32;;-1:-1;4552:30;;;4549:2;;;-1:-1;;4585:12;4549:2;;4623:65;4680:7;4671:6;4660:9;4656:22;4623:65;:::i;:::-;4605:83;;-1:-1;4605:83;-1:-1;;4725:2;4762:22;;1603:20;26294:4;26283:16;;28109:33;;28099:2;;-1:-1;;28146:12;28099:2;4733:61;;;;4079:731;;;;;;;;:::o;4817:241::-;;4921:2;4909:9;4900:7;4896:23;4892:32;4889:2;;;-1:-1;;4927:12;4889:2;1344:6;1331:20;-1:-1;;;;;27891:5;25958:46;27866:5;27863:35;27853:2;;-1:-1;;27902:12;5065:617;;;;;5220:3;5208:9;5199:7;5195:23;5191:33;5188:2;;;-1:-1;;5227:12;5188:2;5310:22;1468:20;5279:63;;5379:2;5422:9;5418:22;1468:20;5387:63;;5487:2;5530:9;5526:22;72:20;97:33;124:5;97:33;:::i;:::-;5182:500;;;;-1:-1;5495:63;;5595:2;5634:22;1468:20;;-1:-1;;5182:500::o;13535:271::-;;6080:5;25092:12;6191:52;6236:6;6231:3;6224:4;6217:5;6213:16;6191:52;:::i;:::-;6255:16;;;;;13669:137;-1:-1;;13669:137::o;13813:222::-;-1:-1;;;;;26078:54;;;;5760:37;;13940:2;13925:18;;13911:124::o;14042:444::-;-1:-1;;;;;26078:54;;;5760:37;;26078:54;;;;14389:2;14374:18;;5760:37;14472:2;14457:18;;13372:37;;;;14225:2;14210:18;;14196:290::o;14493:444::-;-1:-1;;;;;26078:54;;;;5760:37;;-1:-1;;;;;25958:46;;;14840:2;14825:18;;13119:37;25958:46;14923:2;14908:18;;13119:37;14676:2;14661:18;;14647:290::o;14944:333::-;-1:-1;;;;;26078:54;;;;5760:37;;15263:2;15248:18;;13372:37;15099:2;15084:18;;15070:207::o;15284:210::-;25751:13;;25744:21;5874:34;;15405:2;15390:18;;15376:118::o;16027:310::-;;16174:2;16195:17;16188:47;6762:5;25092:12;25531:6;16174:2;16163:9;16159:18;25519:19;6856:52;6901:6;25559:14;16163:9;25559:14;16174:2;6882:5;6878:16;6856:52;:::i;:::-;27375:7;27359:14;-1:-1;;27355:28;6920:39;;;;25559:14;6920:39;;16145:192;-1:-1;;16145:192::o;16344:416::-;16544:2;16558:47;;;7196:2;16529:18;;;25519:19;7232:34;25559:14;;;7212:55;-1:-1;;;7287:12;;;7280:27;7326:12;;;16515:245::o;16767:416::-;16967:2;16981:47;;;7577:2;16952:18;;;25519:19;7613:34;25559:14;;;7593:55;-1:-1;;;7668:12;;;7661:26;7706:12;;;16938:245::o;17190:416::-;17390:2;17404:47;;;7957:2;17375:18;;;25519:19;7993:29;25559:14;;;7973:50;8042:12;;;17361:245::o;17613:416::-;17813:2;17827:47;;;8293:2;17798:18;;;25519:19;-1:-1;;;25559:14;;;8309:42;8370:12;;;17784:245::o;18036:416::-;18236:2;18250:47;;;18221:18;;;25519:19;8657:34;25559:14;;;8637:55;8711:12;;;18207:245::o;18459:416::-;18659:2;18673:47;;;8962:2;18644:18;;;25519:19;-1:-1;;;25559:14;;;8978:44;9041:12;;;18630:245::o;18882:416::-;19082:2;19096:47;;;9292:2;19067:18;;;25519:19;9328:34;25559:14;;;9308:55;-1:-1;;;9383:12;;;9376:25;9420:12;;;19053:245::o;19305:416::-;19505:2;19519:47;;;9671:2;19490:18;;;25519:19;9707:34;25559:14;;;9687:55;-1:-1;;;9762:12;;;9755:38;9812:12;;;19476:245::o;19728:416::-;19928:2;19942:47;;;10063:2;19913:18;;;25519:19;-1:-1;;;25559:14;;;10079:44;10142:12;;;19899:245::o;20151:416::-;20351:2;20365:47;;;10393:2;20336:18;;;25519:19;10429:34;25559:14;;;10409:55;-1:-1;;;10484:12;;;10477:25;10521:12;;;20322:245::o;20574:416::-;20774:2;20788:47;;;10772:2;20759:18;;;25519:19;10808:34;25559:14;;;10788:55;-1:-1;;;10863:12;;;10856:29;10904:12;;;20745:245::o;20997:416::-;21197:2;21211:47;;;11155:2;21182:18;;;25519:19;11191:25;25559:14;;;11171:46;11236:12;;;21168:245::o;21420:416::-;21620:2;21634:47;;;11487:2;21605:18;;;25519:19;11523:34;25559:14;;;11503:55;-1:-1;;;11578:12;;;11571:28;11618:12;;;21591:245::o;21843:416::-;22043:2;22057:47;;;11869:2;22028:18;;;25519:19;11905:34;25559:14;;;11885:55;-1:-1;;;11960:12;;;11953:34;12006:12;;;22014:245::o;22266:416::-;22466:2;22480:47;;;12257:2;22451:18;;;25519:19;12293:29;25559:14;;;12273:50;12342:12;;;22437:245::o;22689:416::-;22889:2;22903:47;;;12593:2;22874:18;;;25519:19;12629:33;25559:14;;;12609:54;12682:12;;;22860:245::o;23112:416::-;23312:2;23326:47;;;12933:2;23297:18;;;25519:19;12969:33;25559:14;;;12949:54;13022:12;;;23283:245::o;23535:222::-;-1:-1;;;;;25958:46;;;;13239:50;;23662:2;23647:18;;23633:124::o;23764:333::-;-1:-1;;;;;25958:46;;;13119:37;;25958:46;;24083:2;24068:18;;13119:37;23919:2;23904:18;;23890:207::o;24104:444::-;-1:-1;;;;;25958:46;;;13119:37;;25958:46;;;;24451:2;24436:18;;13119:37;24534:2;24519:18;;13372:37;;;;24287:2;24272:18;;24258:290::o;24555:222::-;13372:37;;;24682:2;24667:18;;24653:124::o;24784:214::-;26294:4;26283:16;;;;13488:35;;24907:2;24892:18;;24878:120::o;27015:268::-;27080:1;27087:101;27101:6;27098:1;27095:13;27087:101;;;27168:11;;;27162:18;27149:11;;;27142:39;27123:2;27116:10;27087:101;;;27203:6;27200:1;27197:13;27194:2;;;-1:-1;;27080:1;27250:16;;27243:27;27064:219::o;27396:117::-;-1:-1;;;;;26078:54;;27455:35;;27445:2;;27504:1;;27494:12;27445:2;27439:74;:::o
Swarm Source
ipfs://0aaf30318f6fba50199f5b888b6a82fb87c7ae90d3ffa0e30faacf2b6ff136ce
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.