Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Initialize | 18934797 | 354 days ago | IN | 0 ETH | 0.01694284 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Pool3
Compiler Version
v0.7.5+commit.eb77ed08
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; pragma abicoder v2; import "./SafeMathUpgradeable.sol"; import "./OwnablePausableUpgradeable.sol"; import "./IStakedEthToken.sol"; import "./IDepositContract.sol"; import "./IPoolValidators.sol"; import "./IPool3.sol"; import "./IWhiteListManager.sol"; /** * @title Pool * * @dev Pool contract accumulates deposits from the users, mints tokens and registers validators. */ contract Pool3 is IPool3, OwnablePausableUpgradeable { using SafeMathUpgradeable for uint256; // @dev Validator deposit amount. uint256 public constant override VALIDATOR_TOTAL_DEPOSIT = 32 ether; // @dev Total activated validators. uint256 public override activatedValidators; // @dev Pool validator withdrawal credentials. bytes32 public override withdrawalCredentials; // @dev Address of the ETH2 Deposit Contract (deployed by Ethereum). IDepositContract public override validatorRegistration; // @dev Address of the StakedEthToken contract. IStakedEthToken private stakedEthToken; // @dev Address of the PoolValidators contract. IPoolValidators private validators; // @dev Address of the Oracles contract. address private oracles; // @dev Address of the WhiteListManager contract. IWhiteListManager private whiteListManager; // @dev Maps senders to the validator index that it will be activated in. mapping(address => mapping(uint256 => uint256)) public override activations; // @dev Total pending validators. uint256 public override pendingValidators; // @dev Amount of deposited ETH that is not considered for the activation period. uint256 public override minActivatingDeposit; // @dev Pending validators percent limit. If it's not exceeded tokens can be minted immediately. uint256 public override pendingValidatorsLimit; mapping(bytes32 => bool) public override credentialsWhitelist; /** * @dev See {IPool-initialize}. */ function initialize( address admin, bytes32 _withdrawalCredentials, address _validatorRegistration, address _stakedEthToken, address _validators, address _oracles, address _whiteListManager, uint256 _minActivatingDeposit, uint256 _pendingValidatorsLimit ) external override initializer { require(admin != address(0), "Pool: invalid admin address"); require(_withdrawalCredentials != "", "Pool: invalid withdrawal credentials"); require(_validatorRegistration != address(0), "Pool: invalid ValidatorRegistration address"); require(_stakedEthToken != address(0), "Pool: invalid StakedEthToken address"); require(_validators != address(0), "Pool: invalid Validators address"); require(_oracles != address(0), "Pool: invalid Oracles address"); require(_pendingValidatorsLimit < 1e4, "Pool: invalid limit"); __OwnablePausableUpgradeable_init(admin); withdrawalCredentials = _withdrawalCredentials; validatorRegistration = IDepositContract(_validatorRegistration); stakedEthToken = IStakedEthToken(_stakedEthToken); validators = IPoolValidators(_validators); oracles = _oracles; whiteListManager = IWhiteListManager(_whiteListManager); minActivatingDeposit = _minActivatingDeposit; emit MinActivatingDepositUpdated(_minActivatingDeposit, msg.sender); pendingValidatorsLimit = _pendingValidatorsLimit; emit PendingValidatorsLimitUpdated(_pendingValidatorsLimit, msg.sender); } /** * @dev See {IPool-setMinActivatingDeposit}. */ function setMinActivatingDeposit(uint256 newMinActivatingDeposit) external override onlyAdmin { minActivatingDeposit = newMinActivatingDeposit; emit MinActivatingDepositUpdated(newMinActivatingDeposit, msg.sender); } /** * @dev See {IPool-setPendingValidatorsLimit}. */ function setPendingValidatorsLimit(uint256 newPendingValidatorsLimit) external override onlyAdmin { require(newPendingValidatorsLimit < 1e4, "Pool: invalid limit"); pendingValidatorsLimit = newPendingValidatorsLimit; emit PendingValidatorsLimitUpdated(newPendingValidatorsLimit, msg.sender); } /** * @dev See {IPool-setActivatedValidators}. */ function setActivatedValidators(uint256 newActivatedValidators) external override { require(msg.sender == oracles || hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Pool: access denied"); // subtract activated validators from pending validators pendingValidators = pendingValidators.sub(newActivatedValidators.sub(activatedValidators)); activatedValidators = newActivatedValidators; emit ActivatedValidatorsUpdated(newActivatedValidators, msg.sender); } function updateCredentialsWhitelist(bytes32 creds, bool allowed) external override onlyAdmin { credentialsWhitelist[creds] = allowed; } /** * @dev See {IPool-stake}. */ function stake() external payable override { _stake(msg.sender, msg.value); } /** * @dev See {IPool-stakeOnBehalf}. */ function stakeOnBehalf(address recipient) external payable override { _stake(recipient, msg.value); } /** * @dev See {IPool-receiveFees}. */ function receiveFees() external payable override {} /** * @dev Function for staking ETH using transfer. */ receive() external payable { _stake(msg.sender, msg.value); } /** * @dev See {IPool-stakeWithPartner}. */ function stakeWithPartner(address partner) external payable override { // stake amount _stake(msg.sender, msg.value); emit StakedWithPartner(partner, msg.value); } /** * @dev See {IPool-stakeWithPartnerOnBehalf}. */ function stakeWithPartnerOnBehalf(address partner, address recipient) external payable override { // stake amount _stake(recipient, msg.value); emit StakedWithPartner(partner, msg.value); } /** * @dev See {IPool-stakeWithReferrer}. */ function stakeWithReferrer(address referrer) external payable override { // stake amount _stake(msg.sender, msg.value); emit StakedWithReferrer(referrer, msg.value); } /** * @dev See {IPool-stakeWithReferrerOnBehalf}. */ function stakeWithReferrerOnBehalf(address referrer, address recipient) external payable override { // stake amount _stake(recipient, msg.value); emit StakedWithReferrer(referrer, msg.value); } function _stake(address recipient, uint256 value) internal whenNotPaused { require(whiteListManager.whitelistedAccounts(recipient), "Pool: invalid recipient address"); if (recipient != msg.sender) { require(whiteListManager.whitelistedAccounts(msg.sender), "Pool: invalid sender address"); } require(value > 0, "Pool: invalid deposit amount"); // mint tokens for small deposits immediately if (value <= minActivatingDeposit) { stakedEthToken.mint(recipient, value); return; } // mint tokens if current pending validators limit is not exceed uint256 _pendingValidators = pendingValidators.add((address(this).balance).div(VALIDATOR_TOTAL_DEPOSIT)); uint256 _activatedValidators = activatedValidators; // gas savings uint256 validatorIndex = _activatedValidators.add(_pendingValidators); if (validatorIndex.mul(1e4) <= _activatedValidators.mul(pendingValidatorsLimit.add(1e4))) { stakedEthToken.mint(recipient, value); } else { // lock deposit amount until validator activated activations[recipient][validatorIndex] = activations[recipient][validatorIndex].add(value); emit ActivationScheduled(recipient, validatorIndex, value); } } /** * @dev See {IPool-canActivate}. */ function canActivate(uint256 validatorIndex) external view override returns (bool) { return validatorIndex.mul(1e4) <= activatedValidators.mul(pendingValidatorsLimit.add(1e4)); } /** * @dev See {IPool-activate}. */ function activate(address account, uint256 validatorIndex) external override whenNotPaused { uint256 activatedAmount = _activateAmount( account, validatorIndex, activatedValidators.mul(pendingValidatorsLimit.add(1e4)) ); stakedEthToken.mint(account, activatedAmount); } /** * @dev See {IPool-activateMultiple}. */ function activateMultiple(address account, uint256[] calldata validatorIndexes) external override whenNotPaused { uint256 toMint; uint256 maxValidatorIndex = activatedValidators.mul(pendingValidatorsLimit.add(1e4)); for (uint256 i = 0; i < validatorIndexes.length; i++) { uint256 activatedAmount = _activateAmount(account, validatorIndexes[i], maxValidatorIndex); toMint = toMint.add(activatedAmount); } stakedEthToken.mint(account, toMint); } function _activateAmount( address account, uint256 validatorIndex, uint256 maxValidatorIndex ) internal returns (uint256 amount) { require(validatorIndex.mul(1e4) <= maxValidatorIndex, "Pool: validator is not active yet"); amount = activations[account][validatorIndex]; require(amount > 0, "Pool: invalid validator index"); delete activations[account][validatorIndex]; emit Activated(account, validatorIndex, amount, msg.sender); } /** * @dev See {IPool-registerValidator}. */ function registerValidator(IPoolValidators.DepositData calldata depositData) external override whenNotPaused { require(msg.sender == address(validators), "Pool: access denied"); require(credentialsWhitelist[depositData.withdrawalCredentials], "Pool: invalid withdrawal credentials"); // update number of pending validators pendingValidators = pendingValidators.add(1); emit ValidatorRegistered(depositData.publicKey, depositData.operator); // register validator validatorRegistration.deposit{value : VALIDATOR_TOTAL_DEPOSIT}( depositData.publicKey, abi.encodePacked(depositData.withdrawalCredentials), depositData.signature, depositData.depositDataRoot ); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./EnumerableSetUpgradeable.sol"; import "./AddressUpgradeable.sol"; import "./ContextUpgradeable.sol"; import "./Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable { function __AccessControl_init() internal initializer { __Context_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer { } using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; using AddressUpgradeable for address; struct RoleData { EnumerableSetUpgradeable.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // 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"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./Initializable.sol"; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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 ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; // This interface is designed to be compatible with the Vyper version. /// @notice This is the Ethereum 2.0 deposit contract interface. /// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs /// https://github.com/ethereum/eth2.0-specs/blob/dev/solidity_deposit_contract/deposit_contract.sol interface IDepositContract { /// @notice A processed deposit event. event DepositEvent( bytes pubkey, bytes withdrawal_credentials, bytes amount, bytes signature, bytes index ); /// @notice Submit a Phase 0 DepositData object. /// @param pubkey A BLS12-381 public key. /// @param withdrawal_credentials Commitment to a public key for withdrawals. /// @param signature A BLS12-381 signature. /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object. /// Used as a protection against malformed input. function deposit( bytes calldata pubkey, bytes calldata withdrawal_credentials, bytes calldata signature, bytes32 deposit_data_root ) external payable; /// @notice Query the current deposit root hash. /// @return The deposit root hash. function get_deposit_root() external view returns (bytes32); /// @notice Query the current deposit count. /// @return The deposit count encoded as a little endian 64-bit number. function get_deposit_count() external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; import "./AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; /** * @dev Interface of the OwnablePausableUpgradeable and OwnablePausable contracts. */ interface IOwnablePausable { /** * @dev Function for checking whether an account has an admin role. * @param _account - account to check. */ function isAdmin(address _account) external view returns (bool); /** * @dev Function for assigning an admin role to the account. * Can only be called by an account with an admin role. * @param _account - account to assign an admin role to. */ function addAdmin(address _account) external; /** * @dev Function for removing an admin role from the account. * Can only be called by an account with an admin role. * @param _account - account to remove an admin role from. */ function removeAdmin(address _account) external; /** * @dev Function for checking whether an account has a pauser role. * @param _account - account to check. */ function isPauser(address _account) external view returns (bool); /** * @dev Function for adding a pauser role to the account. * Can only be called by an account with an admin role. * @param _account - account to assign a pauser role to. */ function addPauser(address _account) external; /** * @dev Function for removing a pauser role from the account. * Can only be called by an account with an admin role. * @param _account - account to remove a pauser role from. */ function removePauser(address _account) external; /** * @dev Function for pausing the contract. */ function pause() external; /** * @dev Function for unpausing the contract. */ function unpause() external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; pragma abicoder v2; import "./IDepositContract.sol"; import "./IPoolValidators.sol"; /** * @dev Interface of the Pool contract. */ interface IPool3 { /** * @dev Event for tracking registered validators. * @param publicKey - validator public key. * @param operator - address of the validator operator. */ event ValidatorRegistered(bytes publicKey, address operator); /** * @dev Event for tracking scheduled deposit activation. * @param sender - address of the deposit sender. * @param validatorIndex - index of the activated validator. * @param value - deposit amount to be activated. */ event ActivationScheduled(address indexed sender, uint256 validatorIndex, uint256 value); /** * @dev Event for tracking activated deposits. * @param account - account the deposit was activated for. * @param validatorIndex - index of the activated validator. * @param value - amount activated. * @param sender - address of the transaction sender. */ event Activated(address indexed account, uint256 validatorIndex, uint256 value, address indexed sender); /** * @dev Event for tracking activated validators updates. * @param activatedValidators - new total amount of activated validators. * @param sender - address of the transaction sender. */ event ActivatedValidatorsUpdated(uint256 activatedValidators, address sender); /** * @dev Event for tracking updates to the minimal deposit amount considered for the activation period. * @param minActivatingDeposit - new minimal deposit amount considered for the activation. * @param sender - address of the transaction sender. */ event MinActivatingDepositUpdated(uint256 minActivatingDeposit, address sender); /** * @dev Event for tracking pending validators limit. * When it's exceeded, the deposits will be set for the activation. * @param pendingValidatorsLimit - pending validators percent limit. * @param sender - address of the transaction sender. */ event PendingValidatorsLimitUpdated(uint256 pendingValidatorsLimit, address sender); /** * @dev Event for tracking added deposits with partner. * @param partner - address of the partner. * @param amount - the amount added. */ event StakedWithPartner(address indexed partner, uint256 amount); /** * @dev Event for tracking added deposits with referrer. * @param referrer - address of the referrer. * @param amount - the amount added. */ event StakedWithReferrer(address indexed referrer, uint256 amount); /** * @dev Function for initializing the Pool contract. * @param admin - address of the contract admin. * @param _withdrawalCredentials - withdrawal credentials for the pool validators. * @param _validatorRegistration - address of the ValidatorRegistration contract. * @param _stakedEthToken - address of the StakedEthToken contract. * @param _validators - address of the Validators contract. * @param _oracles - address of the Oracles contract. * @param _whiteListManager - address of the WhiteListManager contract. * @param _minActivatingDeposit - minimal deposit amount considered for the activation. * @param _pendingValidatorsLimit - pending validators limit. When it's exceeded, the deposits will be set for the activation. */ function initialize( address admin, bytes32 _withdrawalCredentials, address _validatorRegistration, address _stakedEthToken, address _validators, address _oracles, address _whiteListManager, uint256 _minActivatingDeposit, uint256 _pendingValidatorsLimit ) external; /** * @dev Function for getting the total validator deposit. */ // solhint-disable-next-line func-name-mixedcase function VALIDATOR_TOTAL_DEPOSIT() external view returns (uint256); /** * @dev Function for retrieving the total amount of pending validators. */ function pendingValidators() external view returns (uint256); /** * @dev Function for retrieving the total amount of activated validators. */ function activatedValidators() external view returns (uint256); /** * @dev Function for retrieving the withdrawal credentials used to * initiate pool validators withdrawal from the beacon chain. */ function withdrawalCredentials() external view returns (bytes32); /** * @dev Function for getting the minimal deposit amount considered for the activation. */ function minActivatingDeposit() external view returns (uint256); /** * @dev Function for getting the pending validators percent limit. * When it's exceeded, the deposits will be set for the activation. */ function pendingValidatorsLimit() external view returns (uint256); /** * @dev Function for getting the amount of activating deposits. * @param account - address of the account to get the amount for. * @param validatorIndex - index of the activated validator. */ function activations(address account, uint256 validatorIndex) external view returns (uint256); /** * Mapping to store whether particular withdrawal credentials are * allowed or not. */ function credentialsWhitelist(bytes32 creds) external view returns (bool); /** * @dev Function for setting minimal deposit amount considered for the activation period. * @param newMinActivatingDeposit - new minimal deposit amount considered for the activation. */ function setMinActivatingDeposit(uint256 newMinActivatingDeposit) external; /** * @dev Function for changing the total amount of activated validators. * @param newActivatedValidators - new total amount of activated validators. */ function setActivatedValidators(uint256 newActivatedValidators) external; /** *@dev Updates the status of withdrawal credentials in the * whitelist. */ function updateCredentialsWhitelist(bytes32 creds, bool allowed) external; /** * @dev Function for changing pending validators limit. * @param newPendingValidatorsLimit - new pending validators limit. When it's exceeded, the deposits will be set for the activation. */ function setPendingValidatorsLimit(uint256 newPendingValidatorsLimit) external; /** * @dev Function for checking whether validator index can be activated. * @param validatorIndex - index of the validator to check. */ function canActivate(uint256 validatorIndex) external view returns (bool); /** * @dev Function for retrieving the validator registration contract address. */ function validatorRegistration() external view returns (IDepositContract); /** * @dev Function for receiving native tokens without minting sETH. */ function receiveFees() external payable; /** * @dev Function for staking ether to the pool to the different tokens' recipient. * @param recipient - address of the tokens recipient. */ function stakeOnBehalf(address recipient) external payable; /** * @dev Function for staking ether to the pool. */ function stake() external payable; /** * @dev Function for staking ether with the partner that will receive the revenue share from the protocol fee. * @param partner - address of partner who will get the revenue share. */ function stakeWithPartner(address partner) external payable; /** * @dev Function for staking ether with the partner that will receive the revenue share from the protocol fee * and the different tokens' recipient. * @param partner - address of partner who will get the revenue share. * @param recipient - address of the tokens recipient. */ function stakeWithPartnerOnBehalf(address partner, address recipient) external payable; /** * @dev Function for staking ether with the referrer who will receive the one time bonus. * @param referrer - address of referrer who will get its referral bonus. */ function stakeWithReferrer(address referrer) external payable; /** * @dev Function for staking ether with the referrer who will receive the one time bonus * and the different tokens' recipient. * @param referrer - address of referrer who will get its referral bonus. * @param recipient - address of the tokens recipient. */ function stakeWithReferrerOnBehalf(address referrer, address recipient) external payable; /** * @dev Function for minting account's tokens for the specific validator index. * @param account - account address to activate the tokens for. * @param validatorIndex - index of the activated validator. */ function activate(address account, uint256 validatorIndex) external; /** * @dev Function for minting account's tokens for the specific validator indexes. * @param account - account address to activate the tokens for. * @param validatorIndexes - list of activated validator indexes. */ function activateMultiple(address account, uint256[] calldata validatorIndexes) external; /** * @dev Function for registering new pool validator registration. * @param depositData - the deposit data to submit for the validator. */ function registerValidator(IPoolValidators.DepositData calldata depositData) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; pragma abicoder v2; /** * @dev Interface of the PoolValidators contract. */ interface IPoolValidators { /** * @dev Structure for storing operator data. * @param depositDataMerkleRoot - validators deposit data merkle root. * @param committed - defines whether operator has committed its readiness to host validators. */ struct Operator { bytes32 depositDataMerkleRoot; bool committed; } /** * @dev Structure for passing information about the validator deposit data. * @param operator - address of the operator. * @param withdrawalCredentials - withdrawal credentials used for generating the deposit data. * @param depositDataRoot - hash tree root of the deposit data, generated by the operator. * @param publicKey - BLS public key of the validator, generated by the operator. * @param signature - BLS signature of the validator, generated by the operator. */ struct DepositData { address operator; bytes32 withdrawalCredentials; bytes32 depositDataRoot; bytes publicKey; bytes signature; } /** * @dev Event for tracking new operators. * @param operator - address of the operator. * @param depositDataMerkleRoot - validators deposit data merkle root. * @param depositDataMerkleProofs - validators deposit data merkle proofs. */ event OperatorAdded( address indexed operator, bytes32 indexed depositDataMerkleRoot, string depositDataMerkleProofs ); /** * @dev Event for tracking operator's commitments. * @param operator - address of the operator that expressed its readiness to host validators. */ event OperatorCommitted(address indexed operator); /** * @dev Event for tracking operators' removals. * @param sender - address of the transaction sender. * @param operator - address of the operator. */ event OperatorRemoved( address indexed sender, address indexed operator ); /** * @dev Constructor for initializing the PoolValidators contract. * @param _admin - address of the contract admin. * @param _pool - address of the Pool contract. * @param _oracles - address of the Oracles contract. */ function initialize(address _admin, address _pool, address _oracles) external; /** * @dev Function for retrieving the operator. * @param _operator - address of the operator to retrieve the data for. */ function getOperator(address _operator) external view returns (bytes32, bool); /** * @dev Function for checking whether validator is registered. * @param validatorId - hash of the validator public key to receive the status for. */ function isValidatorRegistered(bytes32 validatorId) external view returns (bool); /** * @dev Function for adding new operator. * @param _operator - address of the operator to add or update. * @param depositDataMerkleRoot - validators deposit data merkle root. * @param depositDataMerkleProofs - validators deposit data merkle proofs. */ function addOperator( address _operator, bytes32 depositDataMerkleRoot, string calldata depositDataMerkleProofs ) external; /** * @dev Function for committing operator. Must be called by the operator address * specified through the `addOperator` function call. */ function commitOperator() external; /** * @dev Function for removing operator. Can be called either by operator or admin. * @param _operator - address of the operator to remove. */ function removeOperator(address _operator) external; /** * @dev Function for registering the validator. * @param depositData - deposit data of the validator. * @param merkleProof - an array of hashes to verify whether the deposit data is part of the merkle root. */ function registerValidator(DepositData calldata depositData, bytes32[] calldata merkleProof) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; import "./IERC20Upgradeable.sol"; /** * @dev Interface of the StakedEthToken contract. */ interface IStakedEthToken is IERC20Upgradeable { /** * @dev Function for initializing the StakedEthToken contract. * @param admin - address of the contract admin. * @param _pool - address of the Pool contract. * @param _rewardEthToken - address of the RewardEthToken contract. * @param _whiteListManager - address of the WhiteListManager contract. */ function initialize( address admin, address _pool, address _rewardEthToken, address _whiteListManager ) external; /** * @dev Function for retrieving the total deposits amount. */ function totalDeposits() external view returns (uint256); /** * @dev Function for retrieving the principal amount of the distributor. */ function distributorPrincipal() external view returns (uint256); /** * @dev Function for toggling rewards for the account. * @param account - address of the account. * @param isDisabled - whether to disable account's rewards distribution. */ function toggleRewards(address account, bool isDisabled) external; /** * @dev Function for creating `amount` tokens and assigning them to `account`. * Can only be called by Pool contract. * @param account - address of the account to assign tokens to. * @param amount - amount of tokens to assign. */ function mint(address account, uint256 amount) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; /** * @dev Interface of the WhiteListManager contract. */ interface IWhiteListManager { /** * @dev Event for tracking added managers. * @param account - address of added manager. */ event ManagerAdded(address account); /** * @dev Event for tracking removed managers. * @param account - address of removed manager. */ event ManagerRemoved(address account); /** * @dev Event for tracking white list updates. * @param account - address of the updated account. * @param approved - defines whether account is approved or not. */ event WhiteListUpdated(address indexed account, bool approved); /** * @dev Function for checking whether account is whitelisted. * @param account - address of the account to check. */ function whitelistedAccounts(address account) external view returns (bool); /** * @dev Constructor for initializing the WhiteListManager contract. * @param admin - address of the contract admin. */ function initialize(address admin) external; /** * @dev Function for updating white listed accounts. * @param account - account to update. * @param approved - defines whether account is approved or not. */ function updateWhiteList(address account, bool approved) external; /** * @dev Function for checking whether an account has a manager role. * @param account - account to check. */ function isManager(address account) external view returns (bool); /** * @dev Function for assigning manager role to the account. * Can only be called by an account with an admin role. * @param account - account to assign a manager role to. */ function addManager(address account) external; /** * @dev Function for removing manager role from the account. * Can only be called by an account with an admin role. * @param account - account to remove a manager role from. */ function removeManager(address account) external; }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; import "./AccessControlUpgradeable.sol"; import "./PausableUpgradeable.sol"; import "./IOwnablePausable.sol"; /** * @title OwnablePausableUpgradeable * * @dev Bundles Access Control, Pausable and Upgradeable contracts in one. * */ abstract contract OwnablePausableUpgradeable is IOwnablePausable, PausableUpgradeable, AccessControlUpgradeable { bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); /** * @dev Modifier for checking whether the caller is an admin. */ modifier onlyAdmin() { require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "OwnablePausable: access denied"); _; } /** * @dev Modifier for checking whether the caller is a pauser. */ modifier onlyPauser() { require(hasRole(PAUSER_ROLE, msg.sender), "OwnablePausable: access denied"); _; } // solhint-disable-next-line func-name-mixedcase function __OwnablePausableUpgradeable_init(address _admin) internal initializer { __Context_init_unchained(); __AccessControl_init_unchained(); __Pausable_init_unchained(); __OwnablePausableUpgradeable_init_unchained(_admin); } /** * @dev Grants `DEFAULT_ADMIN_ROLE`, `PAUSER_ROLE` to the admin account. */ // solhint-disable-next-line func-name-mixedcase function __OwnablePausableUpgradeable_init_unchained(address _admin) internal initializer { _setupRole(DEFAULT_ADMIN_ROLE, _admin); _setupRole(PAUSER_ROLE, _admin); } /** * @dev See {IOwnablePausable-isAdmin}. */ function isAdmin(address _account) external override view returns (bool) { return hasRole(DEFAULT_ADMIN_ROLE, _account); } /** * @dev See {IOwnablePausable-addAdmin}. */ function addAdmin(address _account) external override { grantRole(DEFAULT_ADMIN_ROLE, _account); } /** * @dev See {IOwnablePausable-removeAdmin}. */ function removeAdmin(address _account) external override { revokeRole(DEFAULT_ADMIN_ROLE, _account); } /** * @dev See {IOwnablePausable-isPauser}. */ function isPauser(address _account) external override view returns (bool) { return hasRole(PAUSER_ROLE, _account); } /** * @dev See {IOwnablePausable-addPauser}. */ function addPauser(address _account) external override { grantRole(PAUSER_ROLE, _account); } /** * @dev See {IOwnablePausable-removePauser}. */ function removePauser(address _account) external override { revokeRole(PAUSER_ROLE, _account); } /** * @dev See {IOwnablePausable-pause}. */ function pause() external override onlyPauser { _pause(); } /** * @dev See {IOwnablePausable-unpause}. */ function unpause() external override onlyPauser { _unpause(); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./ContextUpgradeable.sol"; import "./Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal initializer { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal initializer { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev 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 SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * 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); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"validatorIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"Activated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"activatedValidators","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"ActivatedValidatorsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"validatorIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ActivationScheduled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minActivatingDeposit","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"MinActivatingDepositUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pendingValidatorsLimit","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"PendingValidatorsLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"partner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakedWithPartner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakedWithReferrer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"publicKey","type":"bytes"},{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"ValidatorRegistered","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VALIDATOR_TOTAL_DEPOSIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"validatorIndex","type":"uint256"}],"name":"activate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"validatorIndexes","type":"uint256[]"}],"name":"activateMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activatedValidators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"activations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"addPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"validatorIndex","type":"uint256"}],"name":"canActivate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"credentialsWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"},{"internalType":"address","name":"_validatorRegistration","type":"address"},{"internalType":"address","name":"_stakedEthToken","type":"address"},{"internalType":"address","name":"_validators","type":"address"},{"internalType":"address","name":"_oracles","type":"address"},{"internalType":"address","name":"_whiteListManager","type":"address"},{"internalType":"uint256","name":"_minActivatingDeposit","type":"uint256"},{"internalType":"uint256","name":"_pendingValidatorsLimit","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isPauser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minActivatingDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingValidators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingValidatorsLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"receiveFees","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"},{"internalType":"bytes32","name":"depositDataRoot","type":"bytes32"},{"internalType":"bytes","name":"publicKey","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IPoolValidators.DepositData","name":"depositData","type":"tuple"}],"name":"registerValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"removePauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newActivatedValidators","type":"uint256"}],"name":"setActivatedValidators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinActivatingDeposit","type":"uint256"}],"name":"setMinActivatingDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPendingValidatorsLimit","type":"uint256"}],"name":"setPendingValidatorsLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"stakeOnBehalf","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"partner","type":"address"}],"name":"stakeWithPartner","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"partner","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"stakeWithPartnerOnBehalf","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"referrer","type":"address"}],"name":"stakeWithReferrer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"stakeWithReferrerOnBehalf","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"creds","type":"bytes32"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"updateCredentialsWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorRegistration","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalCredentials","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50613495806100206000396000f3fe6080604052600436106102e05760003560e01c80635cfbd610116101845780639cc776f5116100d6578063d547741f1161008a578063e7f9533411610064578063e7f9533414610754578063f44e383f14610774578063f60bb72014610789576102f1565b8063d547741f1461070a578063da44e9c51461072a578063e63ab1e91461073f576102f1565b8063a82f255b116100bb578063a82f255b146106b5578063ca11be69146106ca578063ca15c873146106ea576102f1565b80639cc776f51461068d578063a217fddf146106a0576102f1565b80638456cb591161013857806391d148541161011257806391d148541461063a578063972d7ac91461065a5780639a548a441461067a576102f1565b80638456cb59146105e3578063899b7c74146105f85780639010d07c1461060d576102f1565b80637048027511610169578063704802751461058e57806377aec521146105ae57806382dc1ec4146105c3576102f1565b80635cfbd6101461054e5780636b2c0f551461056e576102f1565b806336568abe1161023d578063461a9523116101f157806359c53656116101cb57806359c53656146105045780635b49dc08146105245780635c975abb14610539576102f1565b8063461a9523146104bc57806346fbf68e146104cf5780634cd79e0a146104ef576102f1565b80633a4b66f1116102225780633a4b66f11461047f5780633a76e0a2146104875780633f4ba83a146104a7576102f1565b806336568abe1461043f57806337a395381461045f576102f1565b806324d7806c116102945780632f2ff15d116102795780632f2ff15d146103df57806331f38f3e146103ff578063359b43591461041f576102f1565b806324d7806c1461039257806324f144ec146103bf576102f1565b8063111f052c116102c5578063111f052c1461031c5780631785f53c1461033c578063248a9ca31461035c576102f1565b80630395501f146102f6578063040dee8a14610309576102f1565b366102f1576102ef3334610791565b005b600080fd5b6102ef610304366004612b6d565b610c5e565b6102ef610317366004612b87565b610cb9565b34801561032857600080fd5b506102ef610337366004612d10565b610d15565b34801561034857600080fd5b506102ef610357366004612b6d565b610e08565b34801561036857600080fd5b5061037c610377366004612d10565b610e16565b6040516103899190612e1a565b60405180910390f35b34801561039e57600080fd5b506103b26103ad366004612b6d565b610e2e565b6040516103899190612e6a565b3480156103cb57600080fd5b506102ef6103da366004612c39565b610e40565b3480156103eb57600080fd5b506102ef6103fa366004612d28565b611257565b34801561040b57600080fd5b506103b261041a366004612d10565b6112d4565b34801561042b57600080fd5b506102ef61043a366004612d9a565b6112e9565b34801561044b57600080fd5b506102ef61045a366004612d28565b61153f565b34801561046b57600080fd5b506102ef61047a366004612d4a565b6115d4565b6102ef611688565b34801561049357600080fd5b506102ef6104a2366004612bb9565b611694565b3480156104b357600080fd5b506102ef611803565b6102ef6104ca366004612b6d565b6118a0565b3480156104db57600080fd5b506103b26104ea366004612b6d565b6118f0565b3480156104fb57600080fd5b5061037c61191c565b34801561051057600080fd5b506102ef61051f366004612d10565b611922565b34801561053057600080fd5b5061037c6119df565b34801561054557600080fd5b506103b26119e5565b34801561055a57600080fd5b506103b2610569366004612d10565b6119ee565b34801561057a57600080fd5b506102ef610589366004612b6d565b611a1e565b34801561059a57600080fd5b506102ef6105a9366004612b6d565b611a48565b3480156105ba57600080fd5b5061037c611a53565b3480156105cf57600080fd5b506102ef6105de366004612b6d565b611a60565b3480156105ef57600080fd5b506102ef611a8a565b34801561060457600080fd5b5061037c611b27565b34801561061957600080fd5b5061062d610628366004612d79565b611b2d565b6040516103899190612e23565b34801561064657600080fd5b506103b2610655366004612d28565b611b4c565b34801561066657600080fd5b506102ef610675366004612d10565b611b64565b6102ef610688366004612b87565b611c11565b6102ef61069b366004612b6d565b611c61565b3480156106ac57600080fd5b5061037c611c6b565b3480156106c157600080fd5b5061037c611c70565b3480156106d657600080fd5b506102ef6106e5366004612ccb565b611c76565b3480156106f657600080fd5b5061037c610705366004612d10565b611da0565b34801561071657600080fd5b506102ef610725366004612d28565b611db7565b34801561073657600080fd5b5061037c611e2a565b34801561074b57600080fd5b5061037c611e30565b34801561076057600080fd5b5061037c61076f366004612ccb565b611e54565b34801561078057600080fd5b5061062d611e71565b6102ef611692565b6107996119e5565b1561080557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b609d546040517ff6a6830f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f6a6830f9061085b908590600401612e23565b60206040518083038186803b15801561087357600080fd5b505afa158015610887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ab9190612cf4565b6108ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061307d565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821633146109e357609d546040517ff6a6830f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f6a6830f9061095d903390600401612e23565b60206040518083038186803b15801561097557600080fd5b505afa158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad9190612cf4565b6109e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061327f565b60008111610a1d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613111565b60a0548111610ab557609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f1990610a7e9085908590600401612e44565b600060405180830381600087803b158015610a9857600080fd5b505af1158015610aac573d6000803e3d6000fd5b50505050610c5a565b6000610ad6610acd476801bc16d674ec800000611e8d565b609f5490611f0e565b6097549091506000610ae88284611f0e565b9050610b0b610b0461271060a154611f0e90919063ffffffff16565b8390611f82565b610b1782612710611f82565b11610bab57609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f1990610b749088908890600401612e44565b600060405180830381600087803b158015610b8e57600080fd5b505af1158015610ba2573d6000803e3d6000fd5b50505050610c56565b73ffffffffffffffffffffffffffffffffffffffff85166000908152609e60209081526040808320848452909152902054610be69085611f0e565b73ffffffffffffffffffffffffffffffffffffffff86166000818152609e60209081526040808320868452909152908190209290925590517f120d5ad3462d3df3f0abd736b8b4770ec826cf7b160eafb242311244031a0d4190610c4d90849088906132da565b60405180910390a25b5050505b5050565b610c683334610791565b8073ffffffffffffffffffffffffffffffffffffffff167f7453795bdd80e63f3d8595c0aa3a0e0b431b2ffedb3f2a3256b67975e9dbdcc934604051610cae9190612e1a565b60405180910390a250565b610cc38134610791565b8173ffffffffffffffffffffffffffffffffffffffff167f2f6cbf015ae7f747147c62891da8bad454d58bd9fe94d218ecc3dbbfbd48c16e34604051610d099190612e1a565b60405180910390a25050565b610d20600033611b4c565b610d8b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b6127108110610dc6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613046565b60a18190556040517fa528a02bba19dba78e3479c018f780883587a8e5b68ccf22d26903e7b55ebd0f90610dfd90839033906132b6565b60405180910390a150565b610e13600082611db7565b50565b6000818152606560205260409020600201545b919050565b6000610e3a8183611b4c565b92915050565b600054610100900460ff1680610e595750610e59611ff5565b80610e67575060005460ff16155b610ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff16158015610f2257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b73ffffffffffffffffffffffffffffffffffffffff8a16610f6f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613248565b88610fa6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906131eb565b73ffffffffffffffffffffffffffffffffffffffff8816610ff3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612f55565b73ffffffffffffffffffffffffffffffffffffffff8716611040576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612fe9565b73ffffffffffffffffffffffffffffffffffffffff861661108d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061317f565b73ffffffffffffffffffffffffffffffffffffffff85166110da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613148565b6127108210611115576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613046565b61111e8a612006565b6098899055609980547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8b811691909117909255609a805482168a8416179055609b80548216898416179055609c80548216888416179055609d805490911691861691909117905560a08390556040517fb9fbf3c7352807cc0abd73e713e71e2b1592fd4ac8a6872e7ed12bfe8ebc3251906111d590859033906132b6565b60405180910390a160a18290556040517fa528a02bba19dba78e3479c018f780883587a8e5b68ccf22d26903e7b55ebd0f9061121490849033906132b6565b60405180910390a1801561124b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050505050565b6000828152606560205260409020600201546112759061065561213b565b6112ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180613383602f913960400191505060405180910390fd5b610c5a828261213f565b60a26020526000908152604090205460ff1681565b6112f16119e5565b1561135d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b609b5473ffffffffffffffffffffffffffffffffffffffff1633146113ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612fb2565b602080820135600090815260a2909152604090205460ff166113fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906131eb565b609f5461140a906001611f0e565b609f557f7cb7aef9bd2e5ee3f6073019691bb332fe3ef290465065aca1b9983f3dc66c5661143b60608301836132e8565b6114486020850185612b6d565b60405161145793929190612e75565b60405180910390a160995473ffffffffffffffffffffffffffffffffffffffff1663228951186801bc16d674ec80000061149460608501856132e8565b85602001356040516020016114a99190612e1a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526114e460808801886132e8565b88604001356040518863ffffffff1660e01b815260040161150a96959493929190612eaf565b6000604051808303818588803b15801561152357600080fd5b505af1158015611537573d6000803e3d6000fd5b505050505050565b61154761213b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146115ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180613431602f913960400191505060405180910390fd5b610c5a82826121c2565b6115df600033611b4c565b61164a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b600091825260a2602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6116923334610791565b565b61169c6119e5565b1561170857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b60008061172e61172561271060a154611f0e90919063ffffffff16565b60975490611f82565b905060005b8381101561177157600061175a8787878581811061174d57fe5b9050602002013585612245565b90506117668482611f0e565b935050600101611733565b50609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f19906117ca9088908690600401612e44565b600060405180830381600087803b1580156117e457600080fd5b505af11580156117f8573d6000803e3d6000fd5b505050505050505050565b61182d7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611b4c565b61189857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b61169261236c565b6118aa3334610791565b8073ffffffffffffffffffffffffffffffffffffffff167f2f6cbf015ae7f747147c62891da8bad454d58bd9fe94d218ecc3dbbfbd48c16e34604051610cae9190612e1a565b6000610e3a7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a83611b4c565b60985481565b609c5473ffffffffffffffffffffffffffffffffffffffff1633148061194e575061194e600033611b4c565b611984576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612fb2565b6119a561199c6097548361245a90919063ffffffff16565b609f549061245a565b609f5560978190556040517f9a6b27e7e3aa16c645fb0310171319c2e6c6545b09b8cbc647aa105c06afca1690610dfd90839033906132b6565b60a15481565b60335460ff1690565b6000611a0a61172561271060a154611f0e90919063ffffffff16565b611a1683612710611f82565b111592915050565b610e137f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a82611db7565b610e13600082611257565b6801bc16d674ec80000081565b610e137f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a82611257565b611ab47f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611b4c565b611b1f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b6116926124d1565b60975481565b6000828152606560205260408120611b459083612599565b9392505050565b6000828152606560205260408120611b4590836125a5565b611b6f600033611b4c565b611bda57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b60a08190556040517fb9fbf3c7352807cc0abd73e713e71e2b1592fd4ac8a6872e7ed12bfe8ebc325190610dfd90839033906132b6565b611c1b8134610791565b8173ffffffffffffffffffffffffffffffffffffffff167f7453795bdd80e63f3d8595c0aa3a0e0b431b2ffedb3f2a3256b67975e9dbdcc934604051610d099190612e1a565b610e138134610791565b600081565b609f5481565b611c7e6119e5565b15611cea57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b6000611d108383611d0b61172561271060a154611f0e90919063ffffffff16565b612245565b609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990611d699086908590600401612e44565b600060405180830381600087803b158015611d8357600080fd5b505af1158015611d97573d6000803e3d6000fd5b50505050505050565b6000818152606560205260408120610e3a906125c7565b600082815260656020526040902060020154611dd59061065561213b565b6115ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806133b26030913960400191505060405180910390fd5b60a05481565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b609e60209081526000928352604080842090915290825290205481565b60995473ffffffffffffffffffffffffffffffffffffffff1681565b6000808211611efd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611f0657fe5b049392505050565b600082820183811015611b4557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082611f9157506000610e3a565b82820282848281611f9e57fe5b0414611b45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806134106021913960400191505060405180910390fd5b6000612000306125d2565b15905090565b600054610100900460ff168061201f575061201f611ff5565b8061202d575060005460ff16155b612082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff161580156120e857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b6120f06125d8565b6120f86125d8565b6121006126eb565b61210982612826565b8015610c5a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b3390565b6000828152606560205260409020612157908261293d565b15610c5a5761216461213b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526065602052604090206121da908261295f565b15610c5a576121e761213b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008161225484612710611f82565b111561228c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906130b4565b5073ffffffffffffffffffffffffffffffffffffffff83166000908152609e60209081526040808320858452909152902054806122f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906131b4565b73ffffffffffffffffffffffffffffffffffffffff84166000818152609e6020908152604080832087845290915280822091909155513391907f5d5cc41341077fc8907130f1a5db8c754d0b286b8121170b6dc4741b1658849a9061235d90879086906132da565b60405180910390a39392505050565b6123746119e5565b6123df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015290519081900360640190fd5b603380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61243061213b565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190a1565b6000828211156124cb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6124d96119e5565b1561254557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b603380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861243061213b565b6000611b458383612981565b6000611b458373ffffffffffffffffffffffffffffffffffffffff84166129ff565b6000610e3a82612a17565b3b151590565b600054610100900460ff16806125f157506125f1611ff5565b806125ff575060005460ff16155b612654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff161580156126ba57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b8015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff16806127045750612704611ff5565b80612712575060005460ff16155b612767576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff161580156127cd57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff168061283f575061283f611ff5565b8061284d575060005460ff16155b6128a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff1615801561290857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b6129136000836112ca565b6121097f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a836112ca565b6000611b458373ffffffffffffffffffffffffffffffffffffffff8416612a1b565b6000611b458373ffffffffffffffffffffffffffffffffffffffff8416612a65565b815460009082106129dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806133616022913960400191505060405180910390fd5b8260000182815481106129ec57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000612a2783836129ff565b612a5d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e3a565b506000610e3a565b60008181526001830160205260408120548015612b3f5783547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8083019190810190600090879083908110612ab657fe5b9060005260206000200154905080876000018481548110612ad357fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612b0357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610e3a565b6000915050610e3a565b803573ffffffffffffffffffffffffffffffffffffffff81168114610e2957600080fd5b600060208284031215612b7e578081fd5b611b4582612b49565b60008060408385031215612b99578081fd5b612ba283612b49565b9150612bb060208401612b49565b90509250929050565b600080600060408486031215612bcd578081fd5b612bd684612b49565b9250602084013567ffffffffffffffff80821115612bf2578283fd5b818601915086601f830112612c05578283fd5b813581811115612c13578384fd5b8760208083028501011115612c26578384fd5b6020830194508093505050509250925092565b60008060008060008060008060006101208a8c031215612c57578485fd5b612c608a612b49565b985060208a01359750612c7560408b01612b49565b9650612c8360608b01612b49565b9550612c9160808b01612b49565b9450612c9f60a08b01612b49565b9350612cad60c08b01612b49565b925060e08a013591506101008a013590509295985092959850929598565b60008060408385031215612cdd578182fd5b612ce683612b49565b946020939093013593505050565b600060208284031215612d05578081fd5b8151611b4581613352565b600060208284031215612d21578081fd5b5035919050565b60008060408385031215612d3a578182fd5b82359150612bb060208401612b49565b60008060408385031215612d5c578182fd5b823591506020830135612d6e81613352565b809150509250929050565b60008060408385031215612d8b578182fd5b50508035926020909101359150565b600060208284031215612dab578081fd5b813567ffffffffffffffff811115612dc1578182fd5b820160a08185031215611b45578182fd5b600082845282826020860137806020848601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011685010190509392505050565b90815260200190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b901515815260200190565b600060408252612e89604083018587612dd2565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060808252612ec360808301888a612dd2565b6020838203818501528751808352835b81811015612eee578981018301518482018401528201612ed3565b81811115612efe57848383860101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091018381038201604085015290612f408183018789612dd2565b92505050826060830152979650505050505050565b6020808252602b908201527f506f6f6c3a20696e76616c69642056616c696461746f7252656769737472617460408201527f696f6e2061646472657373000000000000000000000000000000000000000000606082015260800190565b60208082526013908201527f506f6f6c3a206163636573732064656e69656400000000000000000000000000604082015260600190565b60208082526024908201527f506f6f6c3a20696e76616c6964205374616b6564457468546f6b656e2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526013908201527f506f6f6c3a20696e76616c6964206c696d697400000000000000000000000000604082015260600190565b6020808252601f908201527f506f6f6c3a20696e76616c696420726563697069656e74206164647265737300604082015260600190565b60208082526021908201527f506f6f6c3a2076616c696461746f72206973206e6f742061637469766520796560408201527f7400000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601c908201527f506f6f6c3a20696e76616c6964206465706f73697420616d6f756e7400000000604082015260600190565b6020808252601d908201527f506f6f6c3a20696e76616c6964204f7261636c65732061646472657373000000604082015260600190565b6020808252818101527f506f6f6c3a20696e76616c69642056616c696461746f72732061646472657373604082015260600190565b6020808252601d908201527f506f6f6c3a20696e76616c69642076616c696461746f7220696e646578000000604082015260600190565b60208082526024908201527f506f6f6c3a20696e76616c6964207769746864726177616c2063726564656e7460408201527f69616c7300000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f506f6f6c3a20696e76616c69642061646d696e20616464726573730000000000604082015260600190565b6020808252601c908201527f506f6f6c3a20696e76616c69642073656e646572206164647265737300000000604082015260600190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b918252602082015260400190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261331c578283fd5b83018035915067ffffffffffffffff821115613336578283fd5b60200191503681900382131561334b57600080fd5b9250929050565b8015158114610e1357600080fdfe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220fee5d4e14e2ff5478b0447c59aa27021e8d607e822f80e7f932a55431093ecbe64736f6c63430007050033
Deployed Bytecode
0x6080604052600436106102e05760003560e01c80635cfbd610116101845780639cc776f5116100d6578063d547741f1161008a578063e7f9533411610064578063e7f9533414610754578063f44e383f14610774578063f60bb72014610789576102f1565b8063d547741f1461070a578063da44e9c51461072a578063e63ab1e91461073f576102f1565b8063a82f255b116100bb578063a82f255b146106b5578063ca11be69146106ca578063ca15c873146106ea576102f1565b80639cc776f51461068d578063a217fddf146106a0576102f1565b80638456cb591161013857806391d148541161011257806391d148541461063a578063972d7ac91461065a5780639a548a441461067a576102f1565b80638456cb59146105e3578063899b7c74146105f85780639010d07c1461060d576102f1565b80637048027511610169578063704802751461058e57806377aec521146105ae57806382dc1ec4146105c3576102f1565b80635cfbd6101461054e5780636b2c0f551461056e576102f1565b806336568abe1161023d578063461a9523116101f157806359c53656116101cb57806359c53656146105045780635b49dc08146105245780635c975abb14610539576102f1565b8063461a9523146104bc57806346fbf68e146104cf5780634cd79e0a146104ef576102f1565b80633a4b66f1116102225780633a4b66f11461047f5780633a76e0a2146104875780633f4ba83a146104a7576102f1565b806336568abe1461043f57806337a395381461045f576102f1565b806324d7806c116102945780632f2ff15d116102795780632f2ff15d146103df57806331f38f3e146103ff578063359b43591461041f576102f1565b806324d7806c1461039257806324f144ec146103bf576102f1565b8063111f052c116102c5578063111f052c1461031c5780631785f53c1461033c578063248a9ca31461035c576102f1565b80630395501f146102f6578063040dee8a14610309576102f1565b366102f1576102ef3334610791565b005b600080fd5b6102ef610304366004612b6d565b610c5e565b6102ef610317366004612b87565b610cb9565b34801561032857600080fd5b506102ef610337366004612d10565b610d15565b34801561034857600080fd5b506102ef610357366004612b6d565b610e08565b34801561036857600080fd5b5061037c610377366004612d10565b610e16565b6040516103899190612e1a565b60405180910390f35b34801561039e57600080fd5b506103b26103ad366004612b6d565b610e2e565b6040516103899190612e6a565b3480156103cb57600080fd5b506102ef6103da366004612c39565b610e40565b3480156103eb57600080fd5b506102ef6103fa366004612d28565b611257565b34801561040b57600080fd5b506103b261041a366004612d10565b6112d4565b34801561042b57600080fd5b506102ef61043a366004612d9a565b6112e9565b34801561044b57600080fd5b506102ef61045a366004612d28565b61153f565b34801561046b57600080fd5b506102ef61047a366004612d4a565b6115d4565b6102ef611688565b34801561049357600080fd5b506102ef6104a2366004612bb9565b611694565b3480156104b357600080fd5b506102ef611803565b6102ef6104ca366004612b6d565b6118a0565b3480156104db57600080fd5b506103b26104ea366004612b6d565b6118f0565b3480156104fb57600080fd5b5061037c61191c565b34801561051057600080fd5b506102ef61051f366004612d10565b611922565b34801561053057600080fd5b5061037c6119df565b34801561054557600080fd5b506103b26119e5565b34801561055a57600080fd5b506103b2610569366004612d10565b6119ee565b34801561057a57600080fd5b506102ef610589366004612b6d565b611a1e565b34801561059a57600080fd5b506102ef6105a9366004612b6d565b611a48565b3480156105ba57600080fd5b5061037c611a53565b3480156105cf57600080fd5b506102ef6105de366004612b6d565b611a60565b3480156105ef57600080fd5b506102ef611a8a565b34801561060457600080fd5b5061037c611b27565b34801561061957600080fd5b5061062d610628366004612d79565b611b2d565b6040516103899190612e23565b34801561064657600080fd5b506103b2610655366004612d28565b611b4c565b34801561066657600080fd5b506102ef610675366004612d10565b611b64565b6102ef610688366004612b87565b611c11565b6102ef61069b366004612b6d565b611c61565b3480156106ac57600080fd5b5061037c611c6b565b3480156106c157600080fd5b5061037c611c70565b3480156106d657600080fd5b506102ef6106e5366004612ccb565b611c76565b3480156106f657600080fd5b5061037c610705366004612d10565b611da0565b34801561071657600080fd5b506102ef610725366004612d28565b611db7565b34801561073657600080fd5b5061037c611e2a565b34801561074b57600080fd5b5061037c611e30565b34801561076057600080fd5b5061037c61076f366004612ccb565b611e54565b34801561078057600080fd5b5061062d611e71565b6102ef611692565b6107996119e5565b1561080557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b609d546040517ff6a6830f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f6a6830f9061085b908590600401612e23565b60206040518083038186803b15801561087357600080fd5b505afa158015610887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ab9190612cf4565b6108ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061307d565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821633146109e357609d546040517ff6a6830f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f6a6830f9061095d903390600401612e23565b60206040518083038186803b15801561097557600080fd5b505afa158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad9190612cf4565b6109e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061327f565b60008111610a1d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613111565b60a0548111610ab557609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f1990610a7e9085908590600401612e44565b600060405180830381600087803b158015610a9857600080fd5b505af1158015610aac573d6000803e3d6000fd5b50505050610c5a565b6000610ad6610acd476801bc16d674ec800000611e8d565b609f5490611f0e565b6097549091506000610ae88284611f0e565b9050610b0b610b0461271060a154611f0e90919063ffffffff16565b8390611f82565b610b1782612710611f82565b11610bab57609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f1990610b749088908890600401612e44565b600060405180830381600087803b158015610b8e57600080fd5b505af1158015610ba2573d6000803e3d6000fd5b50505050610c56565b73ffffffffffffffffffffffffffffffffffffffff85166000908152609e60209081526040808320848452909152902054610be69085611f0e565b73ffffffffffffffffffffffffffffffffffffffff86166000818152609e60209081526040808320868452909152908190209290925590517f120d5ad3462d3df3f0abd736b8b4770ec826cf7b160eafb242311244031a0d4190610c4d90849088906132da565b60405180910390a25b5050505b5050565b610c683334610791565b8073ffffffffffffffffffffffffffffffffffffffff167f7453795bdd80e63f3d8595c0aa3a0e0b431b2ffedb3f2a3256b67975e9dbdcc934604051610cae9190612e1a565b60405180910390a250565b610cc38134610791565b8173ffffffffffffffffffffffffffffffffffffffff167f2f6cbf015ae7f747147c62891da8bad454d58bd9fe94d218ecc3dbbfbd48c16e34604051610d099190612e1a565b60405180910390a25050565b610d20600033611b4c565b610d8b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b6127108110610dc6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613046565b60a18190556040517fa528a02bba19dba78e3479c018f780883587a8e5b68ccf22d26903e7b55ebd0f90610dfd90839033906132b6565b60405180910390a150565b610e13600082611db7565b50565b6000818152606560205260409020600201545b919050565b6000610e3a8183611b4c565b92915050565b600054610100900460ff1680610e595750610e59611ff5565b80610e67575060005460ff16155b610ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff16158015610f2257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b73ffffffffffffffffffffffffffffffffffffffff8a16610f6f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613248565b88610fa6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906131eb565b73ffffffffffffffffffffffffffffffffffffffff8816610ff3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612f55565b73ffffffffffffffffffffffffffffffffffffffff8716611040576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612fe9565b73ffffffffffffffffffffffffffffffffffffffff861661108d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061317f565b73ffffffffffffffffffffffffffffffffffffffff85166110da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613148565b6127108210611115576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613046565b61111e8a612006565b6098899055609980547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8b811691909117909255609a805482168a8416179055609b80548216898416179055609c80548216888416179055609d805490911691861691909117905560a08390556040517fb9fbf3c7352807cc0abd73e713e71e2b1592fd4ac8a6872e7ed12bfe8ebc3251906111d590859033906132b6565b60405180910390a160a18290556040517fa528a02bba19dba78e3479c018f780883587a8e5b68ccf22d26903e7b55ebd0f9061121490849033906132b6565b60405180910390a1801561124b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050505050565b6000828152606560205260409020600201546112759061065561213b565b6112ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180613383602f913960400191505060405180910390fd5b610c5a828261213f565b60a26020526000908152604090205460ff1681565b6112f16119e5565b1561135d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b609b5473ffffffffffffffffffffffffffffffffffffffff1633146113ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612fb2565b602080820135600090815260a2909152604090205460ff166113fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906131eb565b609f5461140a906001611f0e565b609f557f7cb7aef9bd2e5ee3f6073019691bb332fe3ef290465065aca1b9983f3dc66c5661143b60608301836132e8565b6114486020850185612b6d565b60405161145793929190612e75565b60405180910390a160995473ffffffffffffffffffffffffffffffffffffffff1663228951186801bc16d674ec80000061149460608501856132e8565b85602001356040516020016114a99190612e1a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526114e460808801886132e8565b88604001356040518863ffffffff1660e01b815260040161150a96959493929190612eaf565b6000604051808303818588803b15801561152357600080fd5b505af1158015611537573d6000803e3d6000fd5b505050505050565b61154761213b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146115ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180613431602f913960400191505060405180910390fd5b610c5a82826121c2565b6115df600033611b4c565b61164a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b600091825260a2602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6116923334610791565b565b61169c6119e5565b1561170857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b60008061172e61172561271060a154611f0e90919063ffffffff16565b60975490611f82565b905060005b8381101561177157600061175a8787878581811061174d57fe5b9050602002013585612245565b90506117668482611f0e565b935050600101611733565b50609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f19906117ca9088908690600401612e44565b600060405180830381600087803b1580156117e457600080fd5b505af11580156117f8573d6000803e3d6000fd5b505050505050505050565b61182d7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611b4c565b61189857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b61169261236c565b6118aa3334610791565b8073ffffffffffffffffffffffffffffffffffffffff167f2f6cbf015ae7f747147c62891da8bad454d58bd9fe94d218ecc3dbbfbd48c16e34604051610cae9190612e1a565b6000610e3a7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a83611b4c565b60985481565b609c5473ffffffffffffffffffffffffffffffffffffffff1633148061194e575061194e600033611b4c565b611984576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190612fb2565b6119a561199c6097548361245a90919063ffffffff16565b609f549061245a565b609f5560978190556040517f9a6b27e7e3aa16c645fb0310171319c2e6c6545b09b8cbc647aa105c06afca1690610dfd90839033906132b6565b60a15481565b60335460ff1690565b6000611a0a61172561271060a154611f0e90919063ffffffff16565b611a1683612710611f82565b111592915050565b610e137f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a82611db7565b610e13600082611257565b6801bc16d674ec80000081565b610e137f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a82611257565b611ab47f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611b4c565b611b1f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b6116926124d1565b60975481565b6000828152606560205260408120611b459083612599565b9392505050565b6000828152606560205260408120611b4590836125a5565b611b6f600033611b4c565b611bda57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f776e61626c655061757361626c653a206163636573732064656e6965640000604482015290519081900360640190fd5b60a08190556040517fb9fbf3c7352807cc0abd73e713e71e2b1592fd4ac8a6872e7ed12bfe8ebc325190610dfd90839033906132b6565b611c1b8134610791565b8173ffffffffffffffffffffffffffffffffffffffff167f7453795bdd80e63f3d8595c0aa3a0e0b431b2ffedb3f2a3256b67975e9dbdcc934604051610d099190612e1a565b610e138134610791565b600081565b609f5481565b611c7e6119e5565b15611cea57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b6000611d108383611d0b61172561271060a154611f0e90919063ffffffff16565b612245565b609a546040517f40c10f1900000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff16906340c10f1990611d699086908590600401612e44565b600060405180830381600087803b158015611d8357600080fd5b505af1158015611d97573d6000803e3d6000fd5b50505050505050565b6000818152606560205260408120610e3a906125c7565b600082815260656020526040902060020154611dd59061065561213b565b6115ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806133b26030913960400191505060405180910390fd5b60a05481565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b609e60209081526000928352604080842090915290825290205481565b60995473ffffffffffffffffffffffffffffffffffffffff1681565b6000808211611efd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611f0657fe5b049392505050565b600082820183811015611b4557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082611f9157506000610e3a565b82820282848281611f9e57fe5b0414611b45576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806134106021913960400191505060405180910390fd5b6000612000306125d2565b15905090565b600054610100900460ff168061201f575061201f611ff5565b8061202d575060005460ff16155b612082576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff161580156120e857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b6120f06125d8565b6120f86125d8565b6121006126eb565b61210982612826565b8015610c5a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b3390565b6000828152606560205260409020612157908261293d565b15610c5a5761216461213b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526065602052604090206121da908261295f565b15610c5a576121e761213b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008161225484612710611f82565b111561228c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906130b4565b5073ffffffffffffffffffffffffffffffffffffffff83166000908152609e60209081526040808320858452909152902054806122f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906131b4565b73ffffffffffffffffffffffffffffffffffffffff84166000818152609e6020908152604080832087845290915280822091909155513391907f5d5cc41341077fc8907130f1a5db8c754d0b286b8121170b6dc4741b1658849a9061235d90879086906132da565b60405180910390a39392505050565b6123746119e5565b6123df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015290519081900360640190fd5b603380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61243061213b565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190a1565b6000828211156124cb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6124d96119e5565b1561254557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b603380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861243061213b565b6000611b458383612981565b6000611b458373ffffffffffffffffffffffffffffffffffffffff84166129ff565b6000610e3a82612a17565b3b151590565b600054610100900460ff16806125f157506125f1611ff5565b806125ff575060005460ff16155b612654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff161580156126ba57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b8015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff16806127045750612704611ff5565b80612712575060005460ff16155b612767576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff161580156127cd57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff168061283f575061283f611ff5565b8061284d575060005460ff16155b6128a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e8152602001806133e2602e913960400191505060405180910390fd5b600054610100900460ff1615801561290857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b6129136000836112ca565b6121097f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a836112ca565b6000611b458373ffffffffffffffffffffffffffffffffffffffff8416612a1b565b6000611b458373ffffffffffffffffffffffffffffffffffffffff8416612a65565b815460009082106129dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806133616022913960400191505060405180910390fd5b8260000182815481106129ec57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000612a2783836129ff565b612a5d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610e3a565b506000610e3a565b60008181526001830160205260408120548015612b3f5783547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8083019190810190600090879083908110612ab657fe5b9060005260206000200154905080876000018481548110612ad357fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612b0357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610e3a565b6000915050610e3a565b803573ffffffffffffffffffffffffffffffffffffffff81168114610e2957600080fd5b600060208284031215612b7e578081fd5b611b4582612b49565b60008060408385031215612b99578081fd5b612ba283612b49565b9150612bb060208401612b49565b90509250929050565b600080600060408486031215612bcd578081fd5b612bd684612b49565b9250602084013567ffffffffffffffff80821115612bf2578283fd5b818601915086601f830112612c05578283fd5b813581811115612c13578384fd5b8760208083028501011115612c26578384fd5b6020830194508093505050509250925092565b60008060008060008060008060006101208a8c031215612c57578485fd5b612c608a612b49565b985060208a01359750612c7560408b01612b49565b9650612c8360608b01612b49565b9550612c9160808b01612b49565b9450612c9f60a08b01612b49565b9350612cad60c08b01612b49565b925060e08a013591506101008a013590509295985092959850929598565b60008060408385031215612cdd578182fd5b612ce683612b49565b946020939093013593505050565b600060208284031215612d05578081fd5b8151611b4581613352565b600060208284031215612d21578081fd5b5035919050565b60008060408385031215612d3a578182fd5b82359150612bb060208401612b49565b60008060408385031215612d5c578182fd5b823591506020830135612d6e81613352565b809150509250929050565b60008060408385031215612d8b578182fd5b50508035926020909101359150565b600060208284031215612dab578081fd5b813567ffffffffffffffff811115612dc1578182fd5b820160a08185031215611b45578182fd5b600082845282826020860137806020848601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011685010190509392505050565b90815260200190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b901515815260200190565b600060408252612e89604083018587612dd2565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060808252612ec360808301888a612dd2565b6020838203818501528751808352835b81811015612eee578981018301518482018401528201612ed3565b81811115612efe57848383860101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091018381038201604085015290612f408183018789612dd2565b92505050826060830152979650505050505050565b6020808252602b908201527f506f6f6c3a20696e76616c69642056616c696461746f7252656769737472617460408201527f696f6e2061646472657373000000000000000000000000000000000000000000606082015260800190565b60208082526013908201527f506f6f6c3a206163636573732064656e69656400000000000000000000000000604082015260600190565b60208082526024908201527f506f6f6c3a20696e76616c6964205374616b6564457468546f6b656e2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526013908201527f506f6f6c3a20696e76616c6964206c696d697400000000000000000000000000604082015260600190565b6020808252601f908201527f506f6f6c3a20696e76616c696420726563697069656e74206164647265737300604082015260600190565b60208082526021908201527f506f6f6c3a2076616c696461746f72206973206e6f742061637469766520796560408201527f7400000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601c908201527f506f6f6c3a20696e76616c6964206465706f73697420616d6f756e7400000000604082015260600190565b6020808252601d908201527f506f6f6c3a20696e76616c6964204f7261636c65732061646472657373000000604082015260600190565b6020808252818101527f506f6f6c3a20696e76616c69642056616c696461746f72732061646472657373604082015260600190565b6020808252601d908201527f506f6f6c3a20696e76616c69642076616c696461746f7220696e646578000000604082015260600190565b60208082526024908201527f506f6f6c3a20696e76616c6964207769746864726177616c2063726564656e7460408201527f69616c7300000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f506f6f6c3a20696e76616c69642061646d696e20616464726573730000000000604082015260600190565b6020808252601c908201527f506f6f6c3a20696e76616c69642073656e646572206164647265737300000000604082015260600190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b918252602082015260400190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261331c578283fd5b83018035915067ffffffffffffffff821115613336578283fd5b60200191503681900382131561334b57600080fd5b9250929050565b8015158114610e1357600080fdfe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220fee5d4e14e2ff5478b0447c59aa27021e8d607e822f80e7f932a55431093ecbe64736f6c63430007050033
Deployed Bytecode Sourcemap
445:10178:14:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5573:29;5580:10;5592:9;5573:6;:29::i;:::-;445:10178;;;;;5673:191;;;;;;:::i;:::-;;:::i;6486:221::-;;;;;;:::i;:::-;;:::i;4001:321::-;;;;;;;;;;-1:-1:-1;4001:321:14;;;;;:::i;:::-;;:::i;2020:114:12:-;;;;;;;;;;-1:-1:-1;2020:114:12;;;;;:::i;:::-;;:::i;4624:112:0:-;;;;;;;;;;-1:-1:-1;4624:112:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1639:134:12;;;;;;;;;;-1:-1:-1;1639:134:12;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2012:1609:14:-;;;;;;;;;;-1:-1:-1;2012:1609:14;;;;;:::i;:::-;;:::i;4986:223:0:-;;;;;;;;;;-1:-1:-1;4986:223:0;;;;;:::i;:::-;;:::i;1892:61:14:-;;;;;;;;;;-1:-1:-1;1892:61:14;;;;;:::i;:::-;;:::i;9846:775::-;;;;;;;;;;-1:-1:-1;9846:775:14;;;;;:::i;:::-;;:::i;6160:205:0:-;;;;;;;;;;-1:-1:-1;6160:205:0;;;;;:::i;:::-;;:::i;4890:147:14:-;;;;;;;;;;-1:-1:-1;4890:147:14;;;;;:::i;:::-;;:::i;5090:89::-;;;:::i;8747:511::-;;;;;;;;;;-1:-1:-1;8747:511:14;;;;;:::i;:::-;;:::i;2881:75:12:-;;;;;;;;;;;;;:::i;6218:195:14:-;;;;;;:::i;:::-;;:::i;2201:128:12:-;;;;;;;;;;-1:-1:-1;2201:128:12;;;;;:::i;:::-;;:::i;801:45:14:-;;;;;;;;;;;;;:::i;4392:492::-;;;;;;;;;;-1:-1:-1;4392:492:14;;;;;:::i;:::-;;:::i;1839:46::-;;;;;;;;;;;;;:::i;1298:84:13:-;;;;;;;;;;;;;:::i;8103:190:14:-;;;;;;;;;;-1:-1:-1;8103:190:14;;;;;:::i;:::-;;:::i;2572:108:12:-;;;;;;;;;;-1:-1:-1;2572:108:12;;;;;:::i;:::-;;:::i;1840:110::-;;;;;;;;;;-1:-1:-1;1840:110:12;;;;;:::i;:::-;;:::i;586:67:14:-;;;;;;;;;;;;;:::i;2397:104:12:-;;;;;;;;;;-1:-1:-1;2397:104:12;;;;;:::i;:::-;;:::i;2744:71::-;;;;;;;;;;;;;:::i;700:43:14:-;;;;;;;;;;;;;:::i;4307:136:0:-;;;;;;;;;;-1:-1:-1;4307:136:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3292:137::-;;;;;;;;;;-1:-1:-1;3292:137:0;;;;;:::i;:::-;;:::i;3692:236:14:-;;;;;;;;;;-1:-1:-1;3692:236:14;;;;;:::i;:::-;;:::i;5936:217::-;;;;;;:::i;:::-;;:::i;5240:113::-;;;;;;:::i;:::-;;:::i;2069:49:0:-;;;;;;;;;;;;;:::i;1553:41:14:-;;;;;;;;;;;;;:::i;8349:334::-;;;;;;;;;;-1:-1:-1;8349:334:14;;;;;:::i;:::-;;:::i;3597:125:0:-;;;;;;;;;;-1:-1:-1;3597:125:0;;;;;:::i;:::-;;:::i;5443:226::-;;;;;;;;;;-1:-1:-1;5443:226:0;;;;;:::i;:::-;;:::i;1687:44:14:-;;;;;;;;;;;;;:::i;422:62:12:-;;;;;;;;;;;;;:::i;1433:75:14:-;;;;;;;;;;-1:-1:-1;1433:75:14;;;;;:::i;:::-;;:::i;926:54::-;;;;;;;;;;;;;:::i;5412:51::-;;;:::i;6713:1331::-;1612:8:13;:6;:8::i;:::-;1611:9;1603:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6804:16:14::1;::::0;:47:::1;::::0;;;;:16:::1;::::0;;::::1;::::0;:36:::1;::::0;:47:::1;::::0;6841:9;;6804:47:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6796:91;;;;;;;;;;;;:::i;:::-;;;;;;;;;6901:23;::::0;::::1;6914:10;6901:23;6897:143;;6948:16;::::0;:48:::1;::::0;;;;:16:::1;::::0;;::::1;::::0;:36:::1;::::0;:48:::1;::::0;6985:10:::1;::::0;6948:48:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6940:89;;;;;;;;;;;;:::i;:::-;7065:1;7057:5;:9;7049:50;;;;;;;;;;;;:::i;:::-;7177:20;;7168:5;:29;7164:117;;7213:14;::::0;:37:::1;::::0;;;;:14:::1;::::0;;::::1;::::0;:19:::1;::::0;:37:::1;::::0;7233:9;;7244:5;;7213:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;7264:7;;7164:117;7364:26;7393:75;7415:52;7416:21;645:8;7415:27;:52::i;:::-;7393:17;::::0;;:21:::1;:75::i;:::-;7509:19;::::0;7364:104;;-1:-1:-1;7478:28:14::1;7578:44;7509:19:::0;7364:104;7578:24:::1;:44::i;:::-;7553:69;;7663:57;7688:31;7715:3;7688:22;;:26;;:31;;;;:::i;:::-;7663:20:::0;;:24:::1;:57::i;:::-;7636:23;:14:::0;7655:3:::1;7636:18;:23::i;:::-;:84;7632:406;;7736:14;::::0;:37:::1;::::0;;;;:14:::1;::::0;;::::1;::::0;:19:::1;::::0;:37:::1;::::0;7756:9;;7767:5;;7736:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;7632:406;;;7906:22;::::0;::::1;;::::0;;;:11:::1;:22;::::0;;;;;;;:38;;;;;;;;;:49:::1;::::0;7949:5;7906:42:::1;:49::i;:::-;7865:22;::::0;::::1;;::::0;;;:11:::1;:22;::::0;;;;;;;:38;;;;;;;;;;:90;;;;7974:53;;::::1;::::0;::::1;::::0;7888:14;;8021:5;;7974:53:::1;:::i;:::-;;;;;;;;7632:406;1651:1:13;;;;6713:1331:14::0;;:::o;5673:191::-;5776:29;5783:10;5795:9;5776:6;:29::i;:::-;5838:7;5820:37;;;5847:9;5820:37;;;;;;:::i;:::-;;;;;;;;5673:191;:::o;6486:221::-;6618:28;6625:9;6636;6618:6;:28::i;:::-;6680:8;6661:39;;;6690:9;6661:39;;;;;;:::i;:::-;;;;;;;;6486:221;;:::o;4001:321::-;610:39:12;2114:4:0;638:10:12;610:7;:39::i;:::-;602:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4145:3:14::1;4117:25;:31;4109:63;;;;;;;;;;;;:::i;:::-;4182:22;:50:::0;;;4247:68:::1;::::0;::::1;::::0;::::1;::::0;4207:25;;4304:10:::1;::::0;4247:68:::1;:::i;:::-;;;;;;;;4001:321:::0;:::o;2020:114:12:-;2087:40;2114:4:0;2118:8:12;2087:10;:40::i;:::-;2020:114;:::o;4624:112:0:-;4681:7;4707:12;;;:6;:12;;;;;:22;;;4624:112;;;;:::o;1639:134:12:-;1706:4;1729:37;1706:4;1757:8;1729:7;:37::i;:::-;1722:44;1639:134;-1:-1:-1;;1639:134:12:o;2012:1609:14:-;1505:13:11;;;;;;;;:33;;;1522:16;:14;:16::i;:::-;1505:50;;;-1:-1:-1;1543:12:11;;;;1542:13;1505:50;1497:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1617:19;1640:13;;;;;;1639:14;1663:98;;;;1697:13;:20;;1731:19;1697:20;;;;;;1731:19;1713:4;1731:19;;;1663:98;2404:19:14::1;::::0;::::1;2396:59;;;;;;;;;;;;:::i;:::-;2473:28:::0;2465:77:::1;;;;;;;;;;;;:::i;:::-;2560:36;::::0;::::1;2552:92;;;;;;;;;;;;:::i;:::-;2662:29;::::0;::::1;2654:78;;;;;;;;;;;;:::i;:::-;2750:25;::::0;::::1;2742:70;;;;;;;;;;;;:::i;:::-;2830:22;::::0;::::1;2822:64;;;;;;;;;;;;:::i;:::-;2930:3;2904:23;:29;2896:61;;;;;;;;;;;;:::i;:::-;2968:40;3002:5;2968:33;:40::i;:::-;3019:21;:46:::0;;;3075:21:::1;:64:::0;;;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;3149:14:::1;:49:::0;;;::::1;::::0;;::::1;;::::0;;3208:10:::1;:41:::0;;;::::1;::::0;;::::1;;::::0;;3259:7:::1;:18:::0;;;::::1;::::0;;::::1;;::::0;;3287:16:::1;:55:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;3353:20:::1;:44:::0;;;3412:62:::1;::::0;::::1;::::0;::::1;::::0;3353:44;;3463:10:::1;::::0;3412:62:::1;:::i;:::-;;;;;;;;3485:22;:48:::0;;;3548:66:::1;::::0;::::1;::::0;::::1;::::0;3510:23;;3603:10:::1;::::0;3548:66:::1;:::i;:::-;;;;;;;;1787:14:11::0;1783:66;;;1833:5;1817:21;;;;;;1783:66;2012:1609:14;;;;;;;;;;:::o;4986:223:0:-;5077:12;;;;:6;:12;;;;;:22;;;5069:45;;5101:12;:10;:12::i;5069:45::-;5061:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5177:25;5188:4;5194:7;5177:10;:25::i;1892:61:14:-;;;;;;;;;;;;;;;:::o;9846:775::-;1612:8:13;:6;:8::i;:::-;1611:9;1603:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9995:10:14::1;::::0;::::1;;9973;:33;9965:65;;;;;;;;;;;;:::i;:::-;10069:33;::::0;;::::1;;10048:55;::::0;;;:20:::1;:55:::0;;;;;;;::::1;;10040:104;;;;;;;;;;;;:::i;:::-;10222:17;::::0;:24:::1;::::0;10244:1:::1;10222:21;:24::i;:::-;10202:17;:44:::0;10261:64:::1;10281:21;;::::0;::::1;:11:::0;:21:::1;:::i;:::-;10304:20;;::::0;::::1;:11:::0;:20:::1;:::i;:::-;10261:64;;;;;;;;:::i;:::-;;;;;;;;10366:21;::::0;::::1;;:29;645:8;10442:21;;::::0;::::1;:11:::0;:21:::1;:::i;:::-;10494:11;:33;;;10477:51;;;;;;;;:::i;:::-;;::::0;;;;;::::1;::::0;;;;;;10542:21:::1;;::::0;::::1;:11:::0;:21:::1;:::i;:::-;10577:11;:27;;;10366:248;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;9846:775:::0;:::o;6160:205:0:-;6257:12;:10;:12::i;:::-;6246:23;;:7;:23;;;6238:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6332:26;6344:4;6350:7;6332:11;:26::i;4890:147:14:-;610:39:12;2114:4:0;638:10:12;610:7;:39::i;:::-;602:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4993:27:14::1;::::0;;;:20:::1;:27;::::0;;;;;:37;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;4890:147::o;5090:89::-;5143:29;5150:10;5162:9;5143:6;:29::i;:::-;5090:89::o;8747:511::-;1612:8:13;:6;:8::i;:::-;1611:9;1603:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8869:14:14::1;8893:25:::0;8921:56:::1;8945:31;8972:3;8945:22;;:26;;:31;;;;:::i;:::-;8921:19;::::0;;:23:::1;:56::i;:::-;8893:84;;8992:9;8987:219;9007:27:::0;;::::1;8987:219;;;9055:23;9081:64;9097:7;9106:16;;9123:1;9106:19;;;;;;;;;;;;;9127:17;9081:15;:64::i;:::-;9055:90:::0;-1:-1:-1;9168:27:14::1;:6:::0;9055:90;9168:10:::1;:27::i;:::-;9159:36:::0;-1:-1:-1;;9036:3:14::1;;8987:219;;;-1:-1:-1::0;9215:14:14::1;::::0;:36:::1;::::0;;;;:14:::1;::::0;;::::1;::::0;:19:::1;::::0;:36:::1;::::0;9235:7;;9244:6;;9215:36:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1651:1:13;;8747:511:14::0;;;:::o;2881:75:12:-;828:32;460:24;849:10;828:7;:32::i;:::-;820:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2939:10:::1;:8;:10::i;6218:195:14:-:0;6323:29;6330:10;6342:9;6323:6;:29::i;:::-;6386:8;6367:39;;;6396:9;6367:39;;;;;;:::i;2201:128:12:-;2269:4;2292:30;460:24;2313:8;2292:7;:30::i;801:45:14:-;;;;:::o;4392:492::-;4506:7;;;;4492:10;:21;;:64;;-1:-1:-1;4517:39:14;2114:4:0;4545:10:14;4517:7;:39::i;:::-;4484:96;;;;;;;;;;;;:::i;:::-;4676:70;4698:47;4725:19;;4698:22;:26;;:47;;;;:::i;:::-;4676:17;;;:21;:70::i;:::-;4656:17;:90;4756:19;:44;;;4815:62;;;;;;4778:22;;4866:10;;4815:62;:::i;1839:46::-;;;;:::o;1298:84:13:-;1368:7;;;;1298:84;:::o;8103:190:14:-;8180:4;8230:56;8254:31;8281:3;8254:22;;:26;;:31;;;;:::i;8230:56::-;8203:23;:14;8222:3;8203:18;:23::i;:::-;:83;;;8103:190;-1:-1:-1;;8103:190:14:o;2572:108:12:-;2640:33;460:24;2664:8;2640:10;:33::i;1840:110::-;1904:39;2114:4:0;1934:8:12;1904:9;:39::i;586:67:14:-;645:8;586:67;:::o;2397:104:12:-;2462:32;460:24;2485:8;2462:9;:32::i;2744:71::-;828:32;460:24;849:10;828:7;:32::i;:::-;820:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2800:8:::1;:6;:8::i;700:43:14:-:0;;;;:::o;4307:136:0:-;4380:7;4406:12;;;:6;:12;;;;;:30;;4430:5;4406:23;:30::i;:::-;4399:37;4307:136;-1:-1:-1;;;4307:136:0:o;3292:137::-;3361:4;3384:12;;;:6;:12;;;;;:38;;3414:7;3384:29;:38::i;3692:236:14:-;610:39:12;2114:4:0;638:10:12;610:7;:39::i;:::-;602:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3796:20:14::1;:46:::0;;;3857:64:::1;::::0;::::1;::::0;::::1;::::0;3819:23;;3910:10:::1;::::0;3857:64:::1;:::i;5936:217::-:0;6066:28;6073:9;6084;6066:6;:28::i;:::-;6127:7;6109:37;;;6136:9;6109:37;;;;;;:::i;5240:113::-;5318:28;5325:9;5336;5318:6;:28::i;2069:49:0:-;2114:4;2069:49;:::o;1553:41:14:-;;;;:::o;8349:334::-;1612:8:13;:6;:8::i;:::-;1611:9;1603:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8450:23:14::1;8476:144;8505:7;8526:14;8554:56;8578:31;8605:3;8578:22;;:26;;:31;;;;:::i;8554:56::-;8476:15;:144::i;:::-;8631:14;::::0;:45:::1;::::0;;;;8450:170;;-1:-1:-1;8631:14:14::1;;::::0;:19:::1;::::0;:45:::1;::::0;8651:7;;8450:170;;8631:45:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1651:1:13;8349:334:14::0;;:::o;3597:125:0:-;3660:7;3686:12;;;:6;:12;;;;;:29;;:27;:29::i;5443:226::-;5535:12;;;;:6;:12;;;;;:22;;;5527:45;;5559:12;:10;:12::i;5527:45::-;5519:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1687:44:14;;;;:::o;422:62:12:-;460:24;422:62;:::o;1433:75:14:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;926:54::-;;;;;;:::o;4228:150:15:-;4286:7;4317:1;4313;:5;4305:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4370:1;4366;:5;;;;;;;4228:150;-1:-1:-1;;;4228:150:15:o;2701:175::-;2759:7;2790:5;;;2813:6;;;;2805:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3549:215;3607:7;3630:6;3626:20;;-1:-1:-1;3645:1:15;3638:8;;3626:20;3668:5;;;3672:1;3668;:5;:1;3691:5;;;;;:10;3683:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1945:123:11;1993:4;2017:44;2055:4;2017:29;:44::i;:::-;2016:45;2009:52;;1945:123;:::o;972:263:12:-;1505:13:11;;;;;;;;:33;;;1522:16;:14;:16::i;:::-;1505:50;;;-1:-1:-1;1543:12:11;;;;1542:13;1505:50;1497:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1617:19;1640:13;;;;;;1639:14;1663:98;;;;1697:13;:20;;1731:19;1697:20;;;;;;1731:19;1713:4;1731:19;;;1663:98;1062:26:12::1;:24;:26::i;:::-;1098:32;:30;:32::i;:::-;1140:27;:25;:27::i;:::-;1177:51;1221:6;1177:43;:51::i;:::-;1787:14:11::0;1783:66;;;1833:5;1817:21;;;;;;972:263:12;;:::o;821:104:2:-;908:10;821:104;:::o;7367:184:0:-;7440:12;;;;:6;:12;;;;;:33;;7465:7;7440:24;:33::i;:::-;7436:109;;;7521:12;:10;:12::i;:::-;7494:40;;7512:7;7494:40;;7506:4;7494:40;;;;;;;;;;7367:184;;:::o;7557:188::-;7631:12;;;;:6;:12;;;;;:36;;7659:7;7631:27;:36::i;:::-;7627:112;;;7715:12;:10;:12::i;:::-;7688:40;;7706:7;7688:40;;7700:4;7688:40;;;;;;;;;;7557:188;;:::o;9264:517:14:-;9413:14;9478:17;9451:23;:14;9470:3;9451:18;:23::i;:::-;:44;;9443:90;;;;;;;;;;;;:::i;:::-;-1:-1:-1;9553:20:14;;;;;;;:11;:20;;;;;;;;:36;;;;;;;;;9607:10;9599:52;;;;;;;;;;;;:::i;:::-;9669:20;;;;;;;:11;:20;;;;;;;;:36;;;;;;;;;9662:43;;;;9720:54;9763:10;;9669:20;9720:54;;;;9690:14;;9755:6;;9720:54;:::i;:::-;;;;;;;;9264:517;;;;;:::o;2310:117:13:-;1877:8;:6;:8::i;:::-;1869:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2368:7:::1;:15:::0;;;::::1;::::0;;2398:22:::1;2407:12;:10;:12::i;:::-;2398:22;::::0;;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;2310:117::o:0;3147:155:15:-;3205:7;3237:1;3232;:6;;3224:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3290:5:15;;;3147:155::o;2063:115:13:-;1612:8;:6;:8::i;:::-;1611:9;1603:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2122:7:::1;:14:::0;;;::::1;2132:4;2122:14;::::0;;2151:20:::1;2158:12;:10;:12::i;7688:156:3:-:0;7762:7;7812:22;7816:3;7828:5;7812:3;:22::i;6995:165::-;7075:4;7098:55;7108:3;7128:23;;;7098:9;:55::i;7241:115::-;7304:7;7330:19;7338:3;7330:7;:19::i;737:413:1:-;1097:20;1135:8;;;737:413::o;752:64:2:-;1505:13:11;;;;;;;;:33;;;1522:16;:14;:16::i;:::-;1505:50;;;-1:-1:-1;1543:12:11;;;;1542:13;1505:50;1497:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1617:19;1640:13;;;;;;1639:14;1663:98;;;;1697:13;:20;;1731:19;1697:20;;;;;;1731:19;1713:4;1731:19;;;1663:98;1787:14;1783:66;;;1833:5;1817:21;;;;;;752:64:2;:::o;1113:90:13:-;1505:13:11;;;;;;;;:33;;;1522:16;:14;:16::i;:::-;1505:50;;;-1:-1:-1;1543:12:11;;;;1542:13;1505:50;1497:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1617:19;1640:13;;;;;;1639:14;1663:98;;;;1697:13;:20;;1731:19;1697:20;;;;;;1731:19;1713:4;1731:19;;;1663:98;1181:7:13::1;:15:::0;;;::::1;::::0;;1783:66:11;;;;1833:5;1817:21;;;;;;1113:90:13;:::o;1387:186:12:-;1505:13:11;;;;;;;;:33;;;1522:16;:14;:16::i;:::-;1505:50;;;-1:-1:-1;1543:12:11;;;;1542:13;1505:50;1497:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1617:19;1640:13;;;;;;1639:14;1663:98;;;;1697:13;:20;;1731:19;1697:20;;;;;;1731:19;1713:4;1731:19;;;1663:98;1487:38:12::1;2114:4:0;1518:6:12::0;1487:10:::1;:38::i;:::-;1535:31;460:24;1559:6;1535:10;:31::i;6440:150:3:-:0;6510:4;6533:50;6538:3;6558:23;;;6533:4;:50::i;6758:156::-;6831:4;6854:53;6862:3;6882:23;;;6854:7;:53::i;4463:201::-;4557:18;;4530:7;;4557:26;-1:-1:-1;4549:73:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4639:3;:11;;4651:5;4639:18;;;;;;;;;;;;;;;;4632:25;;4463:201;;;;:::o;3816:127::-;3889:4;3912:19;;;:12;;;;;:19;;;;;;:24;;;3816:127::o;4024:107::-;4106:18;;4024:107::o;1651:404::-;1714:4;1735:21;1745:3;1750:5;1735:9;:21::i;:::-;1730:319;;-1:-1:-1;1772:23:3;;;;;;;;:11;:23;;;;;;;;;;;;;1952:18;;1930:19;;;:12;;;:19;;;;;;:40;;;;1984:11;;1730:319;-1:-1:-1;2033:5:3;2026:12;;2223:1512;2289:4;2426:19;;;:12;;;:19;;;;;;2460:15;;2456:1273;;2889:18;;2841:14;;;;;2889:22;;;;2817:21;;2889:3;;:22;;3171;;;;;;;;;;;;;;3151:42;;3314:9;3285:3;:11;;3297:13;3285:26;;;;;;;;;;;;;;;;;;;:38;;;;3389:23;;;3431:1;3389:12;;;:23;;;;;;3415:17;;;3389:43;;3538:17;;3389:3;;3538:17;;;;;;;;;;;;;;;;;;;;;;3630:3;:12;;:19;3643:5;3630:19;;;;;;;;;;;3623:26;;;3671:4;3664:11;;;;;;;;2456:1273;3713:5;3706:12;;;;;14:198:16;84:20;;144:42;133:54;;123:65;;113:2;;202:1;199;192:12;217:198;;329:2;317:9;308:7;304:23;300:32;297:2;;;350:6;342;335:22;297:2;378:31;399:9;378:31;:::i;420:274::-;;;549:2;537:9;528:7;524:23;520:32;517:2;;;570:6;562;555:22;517:2;598:31;619:9;598:31;:::i;:::-;588:41;;648:40;684:2;673:9;669:18;648:40;:::i;:::-;638:50;;507:187;;;;;:::o;699:742::-;;;;863:2;851:9;842:7;838:23;834:32;831:2;;;884:6;876;869:22;831:2;912:31;933:9;912:31;:::i;:::-;902:41;;994:2;983:9;979:18;966:32;1017:18;1058:2;1050:6;1047:14;1044:2;;;1079:6;1071;1064:22;1044:2;1122:6;1111:9;1107:22;1097:32;;1167:7;1160:4;1156:2;1152:13;1148:27;1138:2;;1194:6;1186;1179:22;1138:2;1239;1226:16;1265:2;1257:6;1254:14;1251:2;;;1286:6;1278;1271:22;1251:2;1345:7;1340:2;1334;1326:6;1322:15;1318:2;1314:24;1310:33;1307:46;1304:2;;;1371:6;1363;1356:22;1304:2;1407;1403;1399:11;1389:21;;1429:6;1419:16;;;;;821:620;;;;;:::o;1446:788::-;;;;;;;;;;1694:3;1682:9;1673:7;1669:23;1665:33;1662:2;;;1716:6;1708;1701:22;1662:2;1744:31;1765:9;1744:31;:::i;:::-;1734:41;;1822:2;1811:9;1807:18;1794:32;1784:42;;1845:40;1881:2;1870:9;1866:18;1845:40;:::i;:::-;1835:50;;1904:40;1940:2;1929:9;1925:18;1904:40;:::i;:::-;1894:50;;1963:41;1999:3;1988:9;1984:19;1963:41;:::i;:::-;1953:51;;2023:41;2059:3;2048:9;2044:19;2023:41;:::i;:::-;2013:51;;2083:41;2119:3;2108:9;2104:19;2083:41;:::i;:::-;2073:51;;2171:3;2160:9;2156:19;2143:33;2133:43;;2223:3;2212:9;2208:19;2195:33;2185:43;;1652:582;;;;;;;;;;;:::o;2239:266::-;;;2368:2;2356:9;2347:7;2343:23;2339:32;2336:2;;;2389:6;2381;2374:22;2336:2;2417:31;2438:9;2417:31;:::i;:::-;2407:41;2495:2;2480:18;;;;2467:32;;-1:-1:-1;;;2326:179:16:o;2510:257::-;;2630:2;2618:9;2609:7;2605:23;2601:32;2598:2;;;2651:6;2643;2636:22;2598:2;2688:9;2682:16;2707:30;2731:5;2707:30;:::i;2772:190::-;;2884:2;2872:9;2863:7;2859:23;2855:32;2852:2;;;2905:6;2897;2890:22;2852:2;-1:-1:-1;2933:23:16;;2842:120;-1:-1:-1;2842:120:16:o;2967:266::-;;;3096:2;3084:9;3075:7;3071:23;3067:32;3064:2;;;3117:6;3109;3102:22;3064:2;3158:9;3145:23;3135:33;;3187:40;3223:2;3212:9;3208:18;3187:40;:::i;3238:321::-;;;3364:2;3352:9;3343:7;3339:23;3335:32;3332:2;;;3385:6;3377;3370:22;3332:2;3426:9;3413:23;3403:33;;3486:2;3475:9;3471:18;3458:32;3499:30;3523:5;3499:30;:::i;:::-;3548:5;3538:15;;;3322:237;;;;;:::o;3564:258::-;;;3693:2;3681:9;3672:7;3668:23;3664:32;3661:2;;;3714:6;3706;3699:22;3661:2;-1:-1:-1;;3742:23:16;;;3812:2;3797:18;;;3784:32;;-1:-1:-1;3651:171:16:o;3827:421::-;;3970:2;3958:9;3949:7;3945:23;3941:32;3938:2;;;3991:6;3983;3976:22;3938:2;4036:9;4023:23;4069:18;4061:6;4058:30;4055:2;;;4106:6;4098;4091:22;4055:2;4134:22;;4190:3;4172:16;;;4168:26;4165:2;;;4212:6;4204;4197:22;4448:329;;4538:6;4533:3;4526:19;4590:6;4583:5;4576:4;4571:3;4567:14;4554:43;4642:3;4635:4;4626:6;4621:3;4617:16;4613:27;4606:40;4766:4;4696:66;4691:2;4683:6;4679:15;4675:88;4670:3;4666:98;4662:109;4655:116;;4516:261;;;;;:::o;4782:182::-;4911:19;;;4955:2;4946:12;;4901:63::o;4969:226::-;5145:42;5133:55;;;;5115:74;;5103:2;5088:18;;5070:125::o;5439:297::-;5643:42;5631:55;;;;5613:74;;5718:2;5703:18;;5696:34;5601:2;5586:18;;5568:168::o;5741:187::-;5906:14;;5899:22;5881:41;;5869:2;5854:18;;5836:92::o;6115:366::-;;6300:2;6289:9;6282:21;6320:63;6379:2;6368:9;6364:18;6356:6;6348;6320:63;:::i;:::-;6312:71;;6431:42;6423:6;6419:55;6414:2;6403:9;6399:18;6392:83;6272:209;;;;;;:::o;6486:1099::-;;6773:3;6762:9;6755:22;6800:64;6859:3;6848:9;6844:19;6836:6;6828;6800:64;:::i;:::-;6883:2;6933:9;6925:6;6921:22;6916:2;6905:9;6901:18;6894:50;6973:6;6967:13;7004:6;6996;6989:22;7029:4;7042:137;7056:6;7053:1;7050:13;7042:137;;;7148:14;;;7144:23;;7138:30;7117:14;;;7113:23;;7106:63;7071:10;;7042:137;;;7197:6;7194:1;7191:13;7188:2;;;7264:4;7259:2;7250:6;7242;7238:19;7234:28;7227:42;7188:2;-1:-1:-1;7326:2:16;7314:15;7331:66;7310:88;7298:101;;;;7439:18;;;7435:27;;7430:2;7415:18;;7408:55;7298:101;7480:56;7524:11;;;7516:6;7508;7480:56;:::i;:::-;7472:64;;;;7572:6;7567:2;7556:9;7552:18;7545:34;6745:840;;;;;;;;;:::o;7846:407::-;8048:2;8030:21;;;8087:2;8067:18;;;8060:30;8126:34;8121:2;8106:18;;8099:62;8197:13;8192:2;8177:18;;8170:41;8243:3;8228:19;;8020:233::o;8258:343::-;8460:2;8442:21;;;8499:2;8479:18;;;8472:30;8538:21;8533:2;8518:18;;8511:49;8592:2;8577:18;;8432:169::o;8606:400::-;8808:2;8790:21;;;8847:2;8827:18;;;8820:30;8886:34;8881:2;8866:18;;8859:62;8957:6;8952:2;8937:18;;8930:34;8996:3;8981:19;;8780:226::o;9011:343::-;9213:2;9195:21;;;9252:2;9232:18;;;9225:30;9291:21;9286:2;9271:18;;9264:49;9345:2;9330:18;;9185:169::o;9359:355::-;9561:2;9543:21;;;9600:2;9580:18;;;9573:30;9639:33;9634:2;9619:18;;9612:61;9705:2;9690:18;;9533:181::o;9719:397::-;9921:2;9903:21;;;9960:2;9940:18;;;9933:30;9999:34;9994:2;9979:18;;9972:62;10070:3;10065:2;10050:18;;10043:31;10106:3;10091:19;;9893:223::o;10121:352::-;10323:2;10305:21;;;10362:2;10342:18;;;10335:30;10401;10396:2;10381:18;;10374:58;10464:2;10449:18;;10295:178::o;10478:353::-;10680:2;10662:21;;;10719:2;10699:18;;;10692:30;10758:31;10753:2;10738:18;;10731:59;10822:2;10807:18;;10652:179::o;10836:356::-;11038:2;11020:21;;;11057:18;;;11050:30;11116:34;11111:2;11096:18;;11089:62;11183:2;11168:18;;11010:182::o;11197:353::-;11399:2;11381:21;;;11438:2;11418:18;;;11411:30;11477:31;11472:2;11457:18;;11450:59;11541:2;11526:18;;11371:179::o;11555:400::-;11757:2;11739:21;;;11796:2;11776:18;;;11769:30;11835:34;11830:2;11815:18;;11808:62;11906:6;11901:2;11886:18;;11879:34;11945:3;11930:19;;11729:226::o;11960:351::-;12162:2;12144:21;;;12201:2;12181:18;;;12174:30;12240:29;12235:2;12220:18;;12213:57;12302:2;12287:18;;12134:177::o;12316:352::-;12518:2;12500:21;;;12557:2;12537:18;;;12530:30;12596;12591:2;12576:18;;12569:58;12659:2;12644:18;;12490:178::o;12855:305::-;13037:25;;;13110:42;13098:55;13093:2;13078:18;;13071:83;13025:2;13010:18;;12992:168::o;13165:248::-;13339:25;;;13395:2;13380:18;;13373:34;13327:2;13312:18;;13294:119::o;13418:592::-;;;13561:11;13548:25;13651:66;13640:8;13624:14;13620:29;13616:102;13596:18;13592:127;13582:2;;13736:4;13730;13723:18;13582:2;13766:33;;13818:20;;;-1:-1:-1;13861:18:16;13850:30;;13847:2;;;13896:4;13890;13883:18;13847:2;13932:4;13920:17;;-1:-1:-1;13963:14:16;13959:27;;;13949:38;;13946:2;;;14000:1;13997;13990:12;13946:2;13512:498;;;;;:::o;14015:120::-;14103:5;14096:13;14089:21;14082:5;14079:32;14069:2;;14125:1;14122;14115:12
Swarm Source
ipfs://fee5d4e14e2ff5478b0447c59aa27021e8d607e822f80e7f932a55431093ecbe
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 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.