Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been partially verified via Sourcify.
- Contract name:
- StakingContractV2
- Optimization enabled
- true
- Compiler version
- v0.8.26+commit.8a97fa7a
- Optimization runs
- 200
- EVM Version
- london
- Verified at
- 2024-07-12T09:02:40.306622Z
Contract source code
// File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { if (a == 0) { return 0; } c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } } pragma solidity ^0.8.20; /** * @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 proxied contracts do not make use of 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. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * 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 {ERC1967Proxy-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. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } } // File: @openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @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 onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { 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()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { /// @custom:storage-location erc7201:openzeppelin.storage.Ownable struct OwnableStorage { address _owner; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300; function _getOwnableStorage() private pure returns (OwnableStorage storage $) { assembly { $.slot := OwnableStorageLocation } } /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ function __Ownable_init(address initialOwner) internal onlyInitializing { __Ownable_init_unchained(initialOwner); } function __Ownable_init_unchained(address initialOwner) internal onlyInitializing { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { OwnableStorage storage $ = _getOwnableStorage(); return $._owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { OwnableStorage storage $ = _getOwnableStorage(); address oldOwner = $._owner; $._owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: StakingUpgrade/NativeStakin.sol pragma solidity ^0.8.0; contract StakingContractV2 is Initializable, OwnableUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable { using SafeMath for uint256; uint256 public MIN_STAKE_AMOUNT; uint256 public perBlockReward; uint256 public numberOfBlocksPerSecond; uint256 public deploymentTime; uint256 public currentBlockTimestamp; uint256 public daysAfterRewardIsDistributed; address public stakingContractAddress; address[] public stakers; mapping(address => uint256) public stakingAmount; mapping(address => uint256) public addressToRewardAmount; mapping(address => Claim[]) public userToClaimedReward; event RewardDistributed(address indexed staker, uint256 amount); event HalvedReward(uint256 newReward); // Constants for clarity and maintainability uint256 public constant SECONDS_PER_DAY = 86400; // 24 * 60 * 60 uint256 public constant HALVING_PERIOD = 730 days; struct Claim { uint256 amount; uint256 timestamp; } function initialize( uint256 _numberOfBlocksPerSecond, uint256 rewardPerBlock, address _stakingContract, uint _daysAfterReward ) initializer public { __Ownable_init(msg.sender); __ReentrancyGuard_init(); __Pausable_init(); MIN_STAKE_AMOUNT = 50000 ether; numberOfBlocksPerSecond = _numberOfBlocksPerSecond; deploymentTime = block.timestamp; currentBlockTimestamp = deploymentTime; perBlockReward = rewardPerBlock; stakingContractAddress = _stakingContract; daysAfterRewardIsDistributed = _daysAfterReward; } function setPaused(bool _setPaused) public onlyOwner { if (_setPaused) { _pause(); } else { _unpause(); } } function setStakers() internal { uint256 length = stakers.length; for (uint256 i = 0; i < length; i++) { address staker = stakers[i]; stakingAmount[staker] = getStakedAmountPerValidator(staker); } } function getStakedAmountPerValidator(address validatorAddress) internal view returns (uint256) { bytes4 selector = bytes4(keccak256("accountStake(address)")); (bool success, bytes memory result) = stakingContractAddress.staticcall(abi.encodeWithSelector(selector, validatorAddress)); require(success, "Staking contract call failed"); return abi.decode(result, (uint256)); } function callValidatorsFunction() internal view returns (address[] memory) { (bool success, bytes memory result) = stakingContractAddress.staticcall(abi.encodeWithSelector(bytes4(keccak256("validators()")))); require(success, "Validators function call failed"); return abi.decode(result, (address[])); } function payout() external nonReentrant onlyStaker whenNotPaused { require(stakingAmount[msg.sender] >= MIN_STAKE_AMOUNT, "Stake amount is below minimum"); require(block.timestamp >= currentBlockTimestamp.add(daysAfterRewardIsDistributed), "Payout not yet available"); // Halve perBlockReward if period has passed if (block.timestamp >= deploymentTime.add(HALVING_PERIOD)) { deploymentTime = block.timestamp; perBlockReward = perBlockReward.div(2); emit HalvedReward(perBlockReward); } uint256 reward = calculateReward(); require(address(this).balance >= reward, "Insufficient balance"); distributeReward(reward); currentBlockTimestamp = block.timestamp; } function calculateReward() internal view returns (uint256) { uint256 reward = perBlockReward.mul(numberOfBlocksPerSecond).mul(block.timestamp.sub(currentBlockTimestamp)).div(10000); return reward; } function distributeReward(uint256 reward) internal { stakers = callValidatorsFunction(); setStakers(); uint256 stakedAmountTotal = getTotalStakedAmount(); for (uint256 i = 0; i < stakers.length; i++) { address staker = stakers[i]; if (stakingAmount[staker] > 0) { uint256 userReward = (stakingAmount[staker].mul(reward)).div(stakedAmountTotal); addressToRewardAmount[staker] = addressToRewardAmount[staker].add(userReward); // Record the claim userToClaimedReward[staker].push(Claim({ amount: userReward, timestamp: block.timestamp })); } } } function claimReward() external nonReentrant { uint256 reward = addressToRewardAmount[msg.sender]; require(reward > 0, "No rewards to claim"); addressToRewardAmount[msg.sender] = 0; payable(msg.sender).transfer(reward); emit RewardDistributed(msg.sender, reward); } function getTotalStakedAmount() internal view returns (uint256 total) { for (uint256 i = 0; i < stakers.length; i++) { total = total.add(stakingAmount[stakers[i]]); } } function emergencyDrain() external onlyOwner { require(address(this).balance > 0, "Balance is 0"); payable(owner()).transfer(address(this).balance); // Clear staking data after draining delete stakers; } function emergencyDrainAmount(uint256 _amount) external onlyOwner { require(address(this).balance >= _amount, "Less Balance"); payable(owner()).transfer(_amount); } modifier onlyStaker() { require(stakingAmount[msg.sender] > 0, "Not a staker"); _; } // Getter functions function getMinStakeAmount() external view returns (uint256) { return MIN_STAKE_AMOUNT; } function getPerBlockReward() external view returns (uint256) { return perBlockReward; } function getNumberOfBlocksPerSecond() external view returns (uint256) { return numberOfBlocksPerSecond; } function getDeploymentTime() external view returns (uint256) { return deploymentTime; } function getCurrentBlockTimestamp() external view returns (uint256) { return currentBlockTimestamp; } function getDaysAfterRewardIsDistributed() external view returns (uint256) { return daysAfterRewardIsDistributed; } function getStakers() external view returns (address[] memory) { return stakers; } function getStakingContractAddress() external view returns (address) { return stakingContractAddress; } function getStakingAmount(address staker) external view returns (uint256) { require(stakingAmount[staker] >= MIN_STAKE_AMOUNT, "Stake amount is below minimum"); return stakingAmount[staker]; } function getAddressToRewardAmount(address account) external view returns (uint256) { return addressToRewardAmount[account]; } function getClaimDetails(address userAddress) external view returns (Claim[] memory) { return userToClaimedReward[userAddress]; } receive() external payable { // Handle incoming Ether with an event or specific logic if needed }}
Contract ABI
[{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"event","name":"HalvedReward","inputs":[{"type":"uint256","name":"newReward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint64","name":"version","internalType":"uint64","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"RewardDistributed","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"HALVING_PERIOD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_STAKE_AMOUNT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"SECONDS_PER_DAY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"addressToRewardAmount","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentBlockTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"daysAfterRewardIsDistributed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"deploymentTime","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"emergencyDrain","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"emergencyDrainAmount","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAddressToRewardAmount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct StakingContractV2.Claim[]","components":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}]}],"name":"getClaimDetails","inputs":[{"type":"address","name":"userAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentBlockTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getDaysAfterRewardIsDistributed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getDeploymentTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMinStakeAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getNumberOfBlocksPerSecond","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPerBlockReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getStakers","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getStakingAmount","inputs":[{"type":"address","name":"staker","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getStakingContractAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"uint256","name":"_numberOfBlocksPerSecond","internalType":"uint256"},{"type":"uint256","name":"rewardPerBlock","internalType":"uint256"},{"type":"address","name":"_stakingContract","internalType":"address"},{"type":"uint256","name":"_daysAfterReward","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"numberOfBlocksPerSecond","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"payout","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"perBlockReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPaused","inputs":[{"type":"bool","name":"_setPaused","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"stakers","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakingAmount","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"stakingContractAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"userToClaimedReward","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x6080604052348015600f57600080fd5b5061197c8061001f6000396000f3fe6080604052600436106101fd5760003560e01c80638da5cb5b1161010d578063cf9640b4116100a0578063ec2400b71161006f578063ec2400b714610581578063ecda10f514610596578063efc79d35146105ac578063f2fde38b146105c1578063fd5e6dd1146105e157600080fd5b8063cf9640b414610509578063d71411b114610529578063d724a5471461053e578063e8f7b1ee1461055457600080fd5b8063b06ec804116100dc578063b06ec80414610489578063b88a802f1461049e578063bacb0e3a146104b3578063beb32c38146104e957600080fd5b80638da5cb5b1461041b578063905e78201461043057806394ec82771461045d578063abf812721461047357600080fd5b8063527cb1d7116101905780636afe57951161015f5780636afe57951461037c57806370e463291461039a578063715018a6146103cf57806374363daa146103e457806374f0314f1461040457600080fd5b8063527cb1d7146103025780635475ce81146103175780635c975abb1461034457806363bd1d4a1461036757600080fd5b80633535f48b116101cc5780633535f48b1461027a5780633adde9c1146102b25780634003f81b146102ca57806343352d61146102e057600080fd5b80630f28c97d1461020957806316c38b3c1461022d57806327ed71881461024f5780632caac08b1461026557600080fd5b3661020457005b600080fd5b34801561021557600080fd5b506068545b6040519081526020015b60405180910390f35b34801561023957600080fd5b5061024d6102483660046115ff565b610601565b005b34801561025b57600080fd5b5061021a60645481565b34801561027157600080fd5b5061024d610622565b34801561028657600080fd5b50606a5461029a906001600160a01b031681565b6040516001600160a01b039091168152602001610224565b3480156102be57600080fd5b5061021a6303c2670081565b3480156102d657600080fd5b5061021a60665481565b3480156102ec57600080fd5b506102f56106bd565b6040516102249190611621565b34801561030e57600080fd5b5060645461021a565b34801561032357600080fd5b50610337610332366004611682565b61071f565b604051610224919061169f565b34801561035057600080fd5b5060325460ff166040519015158152602001610224565b34801561037357600080fd5b5061024d6107a8565b34801561038857600080fd5b50606a546001600160a01b031661029a565b3480156103a657600080fd5b506103ba6103b53660046116e3565b61098f565b60408051928352602083019190915201610224565b3480156103db57600080fd5b5061024d6109cb565b3480156103f057600080fd5b5061021a6103ff366004611682565b6109dd565b34801561041057600080fd5b5061021a6201518081565b34801561042757600080fd5b5061029a610a65565b34801561043c57600080fd5b5061021a61044b366004611682565b606d6020526000908152604090205481565b34801561046957600080fd5b5061021a60655481565b34801561047f57600080fd5b5061021a60685481565b34801561049557600080fd5b5060675461021a565b3480156104aa57600080fd5b5061024d610a93565b3480156104bf57600080fd5b5061021a6104ce366004611682565b6001600160a01b03166000908152606d602052604090205490565b3480156104f557600080fd5b5061024d61050436600461170f565b610b6a565b34801561051557600080fd5b5061024d610524366004611728565b610bf5565b34801561053557600080fd5b5060665461021a565b34801561054a57600080fd5b5061021a60695481565b34801561056057600080fd5b5061021a61056f366004611682565b606c6020526000908152604090205481565b34801561058d57600080fd5b5060655461021a565b3480156105a257600080fd5b5061021a60675481565b3480156105b857600080fd5b5060695461021a565b3480156105cd57600080fd5b5061024d6105dc366004611682565b610d59565b3480156105ed57600080fd5b5061029a6105fc36600461170f565b610d94565b610609610dbe565b801561061a57610617610df0565b50565b610617610e4a565b61062a610dbe565b6000471161066e5760405162461bcd60e51b815260206004820152600c60248201526b042616c616e636520697320360a41b60448201526064015b60405180910390fd5b610676610a65565b6001600160a01b03166108fc479081150290604051600060405180830381858888f193505050501580156106ae573d6000803e3d6000fd5b506106bb606b600061156f565b565b6060606b80548060200260200160405190810160405280929190818152602001828054801561071557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106f7575b5050505050905090565b6001600160a01b0381166000908152606e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561079d57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610757565b505050509050919050565b6107b0610e83565b336000908152606c60205260409020546107fb5760405162461bcd60e51b815260206004820152600c60248201526b2737ba10309039ba30b5b2b960a11b6044820152606401610665565b610803610edc565b606454336000908152606c602052604090205410156108645760405162461bcd60e51b815260206004820152601d60248201527f5374616b6520616d6f756e742069732062656c6f77206d696e696d756d0000006044820152606401610665565b60695460685461087391610f22565b4210156108c25760405162461bcd60e51b815260206004820152601860248201527f5061796f7574206e6f742079657420617661696c61626c6500000000000000006044820152606401610665565b6067546108d3906303c26700610f22565b421061092457426067556065546108eb906002610f46565b60658190556040519081527f29bce5f66a5f305935773341a6a6d78d7b2dab37a07cab8ca5dae362253205919060200160405180910390a15b600061092e610f59565b9050804710156109775760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610665565b61098081610f95565b50426068556106bb6001600055565b606e60205281600052604060002081815481106109ab57600080fd5b600091825260209091206002909102018054600190910154909250905082565b6109d3610dbe565b6106bb60006110d3565b6064546001600160a01b0382166000908152606c602052604081205490911115610a495760405162461bcd60e51b815260206004820152601d60248201527f5374616b6520616d6f756e742069732062656c6f77206d696e696d756d0000006044820152606401610665565b506001600160a01b03166000908152606c602052604090205490565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b610a9b610e83565b336000908152606d602052604090205480610aee5760405162461bcd60e51b81526020600482015260136024820152724e6f207265776172647320746f20636c61696d60681b6044820152606401610665565b336000818152606d60205260408082208290555183156108fc0291849190818181858888f19350505050158015610b29573d6000803e3d6000fd5b5060405181815233907fe34918ff1c7084970068b53fd71ad6d8b04e9f15d3886cbf006443e6cdc52ea69060200160405180910390a2506106bb6001600055565b610b72610dbe565b80471015610bb15760405162461bcd60e51b815260206004820152600c60248201526b4c6573732042616c616e636560a01b6044820152606401610665565b610bb9610a65565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610bf1573d6000803e3d6000fd5b5050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff16600081158015610c3b5750825b905060008267ffffffffffffffff166001148015610c585750303b155b905081158015610c66575080155b15610c845760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610cae57845460ff60401b1916600160401b1785555b610cb733611144565b610cbf611155565b610cc7611165565b690a968163f0a57b40000060645560668990554260678190556068556065889055606a80546001600160a01b0319166001600160a01b03891617905560698690558315610d4e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b610d61610dbe565b6001600160a01b038116610d8b57604051631e4fbdf760e01b815260006004820152602401610665565b610617816110d3565b606b8181548110610da457600080fd5b6000918252602090912001546001600160a01b0316905081565b33610dc7610a65565b6001600160a01b0316146106bb5760405163118cdaa760e01b8152336004820152602401610665565b610df8610edc565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610e2d3390565b6040516001600160a01b03909116815260200160405180910390a1565b610e52611175565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33610e2d565b600260005403610ed55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610665565b6002600055565b60325460ff16156106bb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610665565b6000610f2e828461177d565b905082811015610f4057610f40611790565b92915050565b6000610f5282846117a6565b9392505050565b600080610f40612710610f8f610f7a606854426111be90919063ffffffff16565b606654606554610f89916111da565b906111da565b90610f46565b610f9d611210565b8051610fb191606b9160209091019061158d565b50610fba611308565b6000610fc461136d565b905060005b606b548110156110c7576000606b8281548110610fe857610fe86117c8565b60009182526020808320909101546001600160a01b0316808352606c909152604090912054909150156110be576001600160a01b0381166000908152606c602052604081205461103e908590610f8f90886111da565b6001600160a01b0383166000908152606d60205260409020549091506110649082610f22565b6001600160a01b0383166000908152606d6020908152604080832093909355606e81528282208351808501909452938352428382019081528454600181810187559584529190922092516002909102909201918255519101555b50600101610fc9565b505050565b6001600055565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b61114c6113cf565b61061781611418565b61115d6113cf565b6106bb611420565b61116d6113cf565b6106bb611428565b60325460ff166106bb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610665565b6000828211156111d0576111d0611790565b610f5282846117de565b6000826000036111ec57506000610f40565b6111f682846117f1565b90508161120384836117a6565b14610f4057610f40611790565b606a5460408051600481526024810182526020810180516001600160e01b031663ca1e781960e01b179052905160609260009283926001600160a01b039092169161125b9190611808565b600060405180830381855afa9150503d8060008114611296576040519150601f19603f3d011682016040523d82523d6000602084013e61129b565b606091505b5091509150816112ed5760405162461bcd60e51b815260206004820152601f60248201527f56616c696461746f72732066756e6374696f6e2063616c6c206661696c6564006044820152606401610665565b80806020019051810190611301919061185d565b9250505090565b606b5460005b81811015610bf1576000606b828154811061132b5761132b6117c8565b6000918252602090912001546001600160a01b0316905061134b8161143c565b6001600160a01b039091166000908152606c602052604090205560010161130e565b6000805b606b548110156113cb576113c1606c6000606b8481548110611395576113956117c8565b60009182526020808320909101546001600160a01b031683528201929092526040019020548390610f22565b9150600101611371565b5090565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166106bb57604051631afcd79f60e31b815260040160405180910390fd5b610d616113cf565b6110cc6113cf565b6114306113cf565b6032805460ff19169055565b606a546040516001600160a01b0383811660248301526000927f2367f6b50ab7882389c2b3c35c760f853bdfe052223bd31c46aff9c510797a0892849283921690849060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516114c09190611808565b600060405180830381855afa9150503d80600081146114fb576040519150601f19603f3d011682016040523d82523d6000602084013e611500565b606091505b5091509150816115525760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e6720636f6e74726163742063616c6c206661696c6564000000006044820152606401610665565b80806020019051810190611566919061192d565b95945050505050565b508054600082559060005260206000209081019061061791906115ea565b8280548282559060005260206000209081019282156115e2579160200282015b828111156115e257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906115ad565b506113cb9291505b5b808211156113cb57600081556001016115eb565b60006020828403121561161157600080fd5b81358015158114610f5257600080fd5b602080825282518282018190526000918401906040840190835b818110156116625783516001600160a01b031683526020938401939092019160010161163b565b509095945050505050565b6001600160a01b038116811461061757600080fd5b60006020828403121561169457600080fd5b8135610f528161166d565b602080825282518282018190526000918401906040840190835b818110156116625783518051845260209081015181850152909301926040909201916001016116b9565b600080604083850312156116f657600080fd5b82356117018161166d565b946020939093013593505050565b60006020828403121561172157600080fd5b5035919050565b6000806000806080858703121561173e57600080fd5b843593506020850135925060408501356117578161166d565b9396929550929360600135925050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610f4057610f40611767565b634e487b7160e01b600052600160045260246000fd5b6000826117c357634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b81810381811115610f4057610f40611767565b8082028115828204841417610f4057610f40611767565b6000825160005b81811015611829576020818601810151858301520161180f565b506000920191825250919050565b634e487b7160e01b600052604160045260246000fd5b80516118588161166d565b919050565b60006020828403121561186f57600080fd5b815167ffffffffffffffff81111561188657600080fd5b8201601f8101841361189757600080fd5b805167ffffffffffffffff8111156118b1576118b1611837565b8060051b604051601f19603f830116810181811067ffffffffffffffff821117156118de576118de611837565b6040529182526020818401810192908101878411156118fc57600080fd5b6020850194505b83851015611922576119148561184d565b815260209485019401611903565b509695505050505050565b60006020828403121561193f57600080fd5b505191905056fea26469706673582212208dfade8ac39d4e07de730d5aca4142b95e89d8792e65c9c7f706b1eae6594d4364736f6c634300081a0033
Deployed ByteCode
0x6080604052600436106101fd5760003560e01c80638da5cb5b1161010d578063cf9640b4116100a0578063ec2400b71161006f578063ec2400b714610581578063ecda10f514610596578063efc79d35146105ac578063f2fde38b146105c1578063fd5e6dd1146105e157600080fd5b8063cf9640b414610509578063d71411b114610529578063d724a5471461053e578063e8f7b1ee1461055457600080fd5b8063b06ec804116100dc578063b06ec80414610489578063b88a802f1461049e578063bacb0e3a146104b3578063beb32c38146104e957600080fd5b80638da5cb5b1461041b578063905e78201461043057806394ec82771461045d578063abf812721461047357600080fd5b8063527cb1d7116101905780636afe57951161015f5780636afe57951461037c57806370e463291461039a578063715018a6146103cf57806374363daa146103e457806374f0314f1461040457600080fd5b8063527cb1d7146103025780635475ce81146103175780635c975abb1461034457806363bd1d4a1461036757600080fd5b80633535f48b116101cc5780633535f48b1461027a5780633adde9c1146102b25780634003f81b146102ca57806343352d61146102e057600080fd5b80630f28c97d1461020957806316c38b3c1461022d57806327ed71881461024f5780632caac08b1461026557600080fd5b3661020457005b600080fd5b34801561021557600080fd5b506068545b6040519081526020015b60405180910390f35b34801561023957600080fd5b5061024d6102483660046115ff565b610601565b005b34801561025b57600080fd5b5061021a60645481565b34801561027157600080fd5b5061024d610622565b34801561028657600080fd5b50606a5461029a906001600160a01b031681565b6040516001600160a01b039091168152602001610224565b3480156102be57600080fd5b5061021a6303c2670081565b3480156102d657600080fd5b5061021a60665481565b3480156102ec57600080fd5b506102f56106bd565b6040516102249190611621565b34801561030e57600080fd5b5060645461021a565b34801561032357600080fd5b50610337610332366004611682565b61071f565b604051610224919061169f565b34801561035057600080fd5b5060325460ff166040519015158152602001610224565b34801561037357600080fd5b5061024d6107a8565b34801561038857600080fd5b50606a546001600160a01b031661029a565b3480156103a657600080fd5b506103ba6103b53660046116e3565b61098f565b60408051928352602083019190915201610224565b3480156103db57600080fd5b5061024d6109cb565b3480156103f057600080fd5b5061021a6103ff366004611682565b6109dd565b34801561041057600080fd5b5061021a6201518081565b34801561042757600080fd5b5061029a610a65565b34801561043c57600080fd5b5061021a61044b366004611682565b606d6020526000908152604090205481565b34801561046957600080fd5b5061021a60655481565b34801561047f57600080fd5b5061021a60685481565b34801561049557600080fd5b5060675461021a565b3480156104aa57600080fd5b5061024d610a93565b3480156104bf57600080fd5b5061021a6104ce366004611682565b6001600160a01b03166000908152606d602052604090205490565b3480156104f557600080fd5b5061024d61050436600461170f565b610b6a565b34801561051557600080fd5b5061024d610524366004611728565b610bf5565b34801561053557600080fd5b5060665461021a565b34801561054a57600080fd5b5061021a60695481565b34801561056057600080fd5b5061021a61056f366004611682565b606c6020526000908152604090205481565b34801561058d57600080fd5b5060655461021a565b3480156105a257600080fd5b5061021a60675481565b3480156105b857600080fd5b5060695461021a565b3480156105cd57600080fd5b5061024d6105dc366004611682565b610d59565b3480156105ed57600080fd5b5061029a6105fc36600461170f565b610d94565b610609610dbe565b801561061a57610617610df0565b50565b610617610e4a565b61062a610dbe565b6000471161066e5760405162461bcd60e51b815260206004820152600c60248201526b042616c616e636520697320360a41b60448201526064015b60405180910390fd5b610676610a65565b6001600160a01b03166108fc479081150290604051600060405180830381858888f193505050501580156106ae573d6000803e3d6000fd5b506106bb606b600061156f565b565b6060606b80548060200260200160405190810160405280929190818152602001828054801561071557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106f7575b5050505050905090565b6001600160a01b0381166000908152606e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561079d57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610757565b505050509050919050565b6107b0610e83565b336000908152606c60205260409020546107fb5760405162461bcd60e51b815260206004820152600c60248201526b2737ba10309039ba30b5b2b960a11b6044820152606401610665565b610803610edc565b606454336000908152606c602052604090205410156108645760405162461bcd60e51b815260206004820152601d60248201527f5374616b6520616d6f756e742069732062656c6f77206d696e696d756d0000006044820152606401610665565b60695460685461087391610f22565b4210156108c25760405162461bcd60e51b815260206004820152601860248201527f5061796f7574206e6f742079657420617661696c61626c6500000000000000006044820152606401610665565b6067546108d3906303c26700610f22565b421061092457426067556065546108eb906002610f46565b60658190556040519081527f29bce5f66a5f305935773341a6a6d78d7b2dab37a07cab8ca5dae362253205919060200160405180910390a15b600061092e610f59565b9050804710156109775760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610665565b61098081610f95565b50426068556106bb6001600055565b606e60205281600052604060002081815481106109ab57600080fd5b600091825260209091206002909102018054600190910154909250905082565b6109d3610dbe565b6106bb60006110d3565b6064546001600160a01b0382166000908152606c602052604081205490911115610a495760405162461bcd60e51b815260206004820152601d60248201527f5374616b6520616d6f756e742069732062656c6f77206d696e696d756d0000006044820152606401610665565b506001600160a01b03166000908152606c602052604090205490565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b610a9b610e83565b336000908152606d602052604090205480610aee5760405162461bcd60e51b81526020600482015260136024820152724e6f207265776172647320746f20636c61696d60681b6044820152606401610665565b336000818152606d60205260408082208290555183156108fc0291849190818181858888f19350505050158015610b29573d6000803e3d6000fd5b5060405181815233907fe34918ff1c7084970068b53fd71ad6d8b04e9f15d3886cbf006443e6cdc52ea69060200160405180910390a2506106bb6001600055565b610b72610dbe565b80471015610bb15760405162461bcd60e51b815260206004820152600c60248201526b4c6573732042616c616e636560a01b6044820152606401610665565b610bb9610a65565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610bf1573d6000803e3d6000fd5b5050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff16600081158015610c3b5750825b905060008267ffffffffffffffff166001148015610c585750303b155b905081158015610c66575080155b15610c845760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610cae57845460ff60401b1916600160401b1785555b610cb733611144565b610cbf611155565b610cc7611165565b690a968163f0a57b40000060645560668990554260678190556068556065889055606a80546001600160a01b0319166001600160a01b03891617905560698690558315610d4e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b610d61610dbe565b6001600160a01b038116610d8b57604051631e4fbdf760e01b815260006004820152602401610665565b610617816110d3565b606b8181548110610da457600080fd5b6000918252602090912001546001600160a01b0316905081565b33610dc7610a65565b6001600160a01b0316146106bb5760405163118cdaa760e01b8152336004820152602401610665565b610df8610edc565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610e2d3390565b6040516001600160a01b03909116815260200160405180910390a1565b610e52611175565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33610e2d565b600260005403610ed55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610665565b6002600055565b60325460ff16156106bb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610665565b6000610f2e828461177d565b905082811015610f4057610f40611790565b92915050565b6000610f5282846117a6565b9392505050565b600080610f40612710610f8f610f7a606854426111be90919063ffffffff16565b606654606554610f89916111da565b906111da565b90610f46565b610f9d611210565b8051610fb191606b9160209091019061158d565b50610fba611308565b6000610fc461136d565b905060005b606b548110156110c7576000606b8281548110610fe857610fe86117c8565b60009182526020808320909101546001600160a01b0316808352606c909152604090912054909150156110be576001600160a01b0381166000908152606c602052604081205461103e908590610f8f90886111da565b6001600160a01b0383166000908152606d60205260409020549091506110649082610f22565b6001600160a01b0383166000908152606d6020908152604080832093909355606e81528282208351808501909452938352428382019081528454600181810187559584529190922092516002909102909201918255519101555b50600101610fc9565b505050565b6001600055565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b61114c6113cf565b61061781611418565b61115d6113cf565b6106bb611420565b61116d6113cf565b6106bb611428565b60325460ff166106bb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610665565b6000828211156111d0576111d0611790565b610f5282846117de565b6000826000036111ec57506000610f40565b6111f682846117f1565b90508161120384836117a6565b14610f4057610f40611790565b606a5460408051600481526024810182526020810180516001600160e01b031663ca1e781960e01b179052905160609260009283926001600160a01b039092169161125b9190611808565b600060405180830381855afa9150503d8060008114611296576040519150601f19603f3d011682016040523d82523d6000602084013e61129b565b606091505b5091509150816112ed5760405162461bcd60e51b815260206004820152601f60248201527f56616c696461746f72732066756e6374696f6e2063616c6c206661696c6564006044820152606401610665565b80806020019051810190611301919061185d565b9250505090565b606b5460005b81811015610bf1576000606b828154811061132b5761132b6117c8565b6000918252602090912001546001600160a01b0316905061134b8161143c565b6001600160a01b039091166000908152606c602052604090205560010161130e565b6000805b606b548110156113cb576113c1606c6000606b8481548110611395576113956117c8565b60009182526020808320909101546001600160a01b031683528201929092526040019020548390610f22565b9150600101611371565b5090565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166106bb57604051631afcd79f60e31b815260040160405180910390fd5b610d616113cf565b6110cc6113cf565b6114306113cf565b6032805460ff19169055565b606a546040516001600160a01b0383811660248301526000927f2367f6b50ab7882389c2b3c35c760f853bdfe052223bd31c46aff9c510797a0892849283921690849060440160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516114c09190611808565b600060405180830381855afa9150503d80600081146114fb576040519150601f19603f3d011682016040523d82523d6000602084013e611500565b606091505b5091509150816115525760405162461bcd60e51b815260206004820152601c60248201527f5374616b696e6720636f6e74726163742063616c6c206661696c6564000000006044820152606401610665565b80806020019051810190611566919061192d565b95945050505050565b508054600082559060005260206000209081019061061791906115ea565b8280548282559060005260206000209081019282156115e2579160200282015b828111156115e257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906115ad565b506113cb9291505b5b808211156113cb57600081556001016115eb565b60006020828403121561161157600080fd5b81358015158114610f5257600080fd5b602080825282518282018190526000918401906040840190835b818110156116625783516001600160a01b031683526020938401939092019160010161163b565b509095945050505050565b6001600160a01b038116811461061757600080fd5b60006020828403121561169457600080fd5b8135610f528161166d565b602080825282518282018190526000918401906040840190835b818110156116625783518051845260209081015181850152909301926040909201916001016116b9565b600080604083850312156116f657600080fd5b82356117018161166d565b946020939093013593505050565b60006020828403121561172157600080fd5b5035919050565b6000806000806080858703121561173e57600080fd5b843593506020850135925060408501356117578161166d565b9396929550929360600135925050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610f4057610f40611767565b634e487b7160e01b600052600160045260246000fd5b6000826117c357634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b81810381811115610f4057610f40611767565b8082028115828204841417610f4057610f40611767565b6000825160005b81811015611829576020818601810151858301520161180f565b506000920191825250919050565b634e487b7160e01b600052604160045260246000fd5b80516118588161166d565b919050565b60006020828403121561186f57600080fd5b815167ffffffffffffffff81111561188657600080fd5b8201601f8101841361189757600080fd5b805167ffffffffffffffff8111156118b1576118b1611837565b8060051b604051601f19603f830116810181811067ffffffffffffffff821117156118de576118de611837565b6040529182526020818401810192908101878411156118fc57600080fd5b6020850194505b83851015611922576119148561184d565b815260209485019401611903565b509695505050505050565b60006020828403121561193f57600080fd5b505191905056fea26469706673582212208dfade8ac39d4e07de730d5aca4142b95e89d8792e65c9c7f706b1eae6594d4364736f6c634300081a0033