Source Code
Latest 25 from a total of 390 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 22767157 | 21 hrs ago | IN | 0 ETH | 0.00020949 | ||||
Stake | 22766975 | 22 hrs ago | IN | 0 ETH | 0.00027439 | ||||
Withdraw | 22766962 | 22 hrs ago | IN | 0 ETH | 0.00015069 | ||||
Withdraw | 22766957 | 22 hrs ago | IN | 0 ETH | 0.00018651 | ||||
Renounce Role | 22756644 | 2 days ago | IN | 0 ETH | 0.00001482 | ||||
Withdraw | 22756617 | 2 days ago | IN | 0 ETH | 0.00058029 | ||||
Stake | 22740739 | 4 days ago | IN | 0 ETH | 0.00015593 | ||||
Withdraw | 22737569 | 5 days ago | IN | 0 ETH | 0.00021851 | ||||
Stake | 22733052 | 5 days ago | IN | 0 ETH | 0.00056502 | ||||
Stake | 22732957 | 5 days ago | IN | 0 ETH | 0.00050243 | ||||
Update Reward Po... | 22727461 | 6 days ago | IN | 0 ETH | 0.00002712 | ||||
Grant Role | 22727443 | 6 days ago | IN | 0 ETH | 0.00004217 | ||||
Update Reward Po... | 22727431 | 6 days ago | IN | 0 ETH | 0.00002019 | ||||
Withdraw | 22723351 | 7 days ago | IN | 0 ETH | 0.00016824 | ||||
Withdraw | 22714044 | 8 days ago | IN | 0 ETH | 0.00004013 | ||||
Withdraw | 22705160 | 9 days ago | IN | 0 ETH | 0.00004765 | ||||
Withdraw | 22699964 | 10 days ago | IN | 0 ETH | 0.00004791 | ||||
Stake | 22683780 | 12 days ago | IN | 0 ETH | 0.0007258 | ||||
Withdraw | 22683773 | 12 days ago | IN | 0 ETH | 0.00035019 | ||||
Grant Manager Ro... | 22674191 | 13 days ago | IN | 0 ETH | 0.00027691 | ||||
Renounce Role | 22672631 | 14 days ago | IN | 0 ETH | 0.00005073 | ||||
Renounce Role | 22672629 | 14 days ago | IN | 0 ETH | 0.00005173 | ||||
Grant Role | 22672618 | 14 days ago | IN | 0 ETH | 0.00010827 | ||||
Grant Role | 22672612 | 14 days ago | IN | 0 ETH | 0.00011045 | ||||
Stake | 22667764 | 14 days ago | IN | 0 ETH | 0.0007346 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SkaiStaking
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2025-01-06 */ // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/interfaces/IERC1363.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); } // File: @openzeppelin/contracts/utils/Errors.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } } // File: @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @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. */ 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. This account bears the admin role (for the granted role). * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; } // File: @openzeppelin/contracts/utils/Context.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 Context { 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/utils/introspection/ERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * 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}: * * ```solidity * 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. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @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 virtual 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. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } } // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @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 EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // 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; } } // File: @openzeppelin/contracts/utils/Pausable.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { bool private _paused; /** * @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); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ constructor() { _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 { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @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()); } } // File: contracts/SkaiStaking.sol pragma solidity ^0.8.20; /** * @title SkaiStaking * @author Ralph Kuepper * @notice This contract manages the staking of SKAI tokens with various lock periods and APY rewards * @dev Implements role-based access control with three levels: Admin, Manager, and Emergency roles */ contract SkaiStaking is AccessControl, ReentrancyGuard, Pausable { using SafeERC20 for IERC20; // Role definitions bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); /// @notice Running total of staked tokens uint256 public totalStaked; /// @notice The ERC20 token used for staking and rewards IERC20 public immutable stakingToken; /// @notice Total rewards that can be distributed by the contract uint256 public totalPotentialRewards; /// @notice Total rewards currently reserved for active stakes uint256 public reservedRewards; /** * @notice Structure defining a reward block with staking period and APY * @dev APY is stored in basis points (1% = 100) */ struct RewardBlock { uint256 daysToStake; // Duration of the staking period in days uint256 apy; // Annual Percentage Yield in basis points bool enabled; // Whether this reward block is currently active } /** * @notice Structure containing information about a single stake * @dev Time is stored as block.timestamp */ struct Deposit { address user; // Address of the staker uint256 stakedAmount; // Amount of tokens staked uint256 time; // Timestamp when the stake was created bool paid; // Whether the stake has been withdrawn uint256 rewardBlockIndex; // Index of the reward block used for this stake uint256 potentialReward; // Calculated reward at time of staking uint256 apy; // APY rate locked at time of staking } /// @notice Array containing all available reward blocks RewardBlock[] public rewardBlocks; /// @notice Array containing all deposits ever made Deposit[] public deposits; /// @notice Mapping to track total staked amount per user mapping(address => uint256) public userTotalStaked; // Events event RewardBlockAdded( uint256 indexed blockIndex, uint256 daysToStake, uint256 apy ); event RewardBlockUpdated(uint256 indexed blockIndex, uint256 newApy); event RewardBlockAvailabilityUpdated( uint256 indexed blockIndex, bool enabled ); event Staked( address indexed user, uint256 indexed depositIndex, uint256 amount, uint256 blockIndex ); event Withdrawn( address indexed user, uint256 indexed depositIndex, uint256 amount, uint256 reward ); event EmergencyWithdrawn( address indexed user, uint256 indexed depositIndex, uint256 amount ); event RewardPoolUpdated(address indexed updater, uint256 newTotal); /** * @notice Contract constructor * @param _stakingToken Address of the ERC20 token used for staking * @dev Sets up initial roles and role hierarchies */ constructor(address _stakingToken) { require(_stakingToken != address(0), "Invalid token address"); stakingToken = IERC20(_stakingToken); // Setup initial roles _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(ADMIN_ROLE, msg.sender); _grantRole(MANAGER_ROLE, msg.sender); // Set role hierarchies _setRoleAdmin(MANAGER_ROLE, ADMIN_ROLE); } // ============ Role Management Functions ============ /** * @notice Updates the total reward pool available for distribution * @param _newTotal New total reward pool amount * @dev Transfers additional tokens if increasing the pool, or returns excess tokens if decreasing */ function updateRewardPool( uint256 _newTotal ) external onlyRole(MANAGER_ROLE) { require( _newTotal >= reservedRewards, "Cannot set below reserved rewards" ); uint256 currentBalance = stakingToken.balanceOf(address(this)); uint256 currentAvailableRewards = currentBalance - totalStaked; if (_newTotal > totalPotentialRewards) { // If increasing reward pool, transfer additional tokens uint256 additionalRewards = _newTotal - totalPotentialRewards; require( stakingToken.transferFrom( msg.sender, address(this), additionalRewards ), "Transfer failed" ); } else if (_newTotal < totalPotentialRewards) { uint256 returnable = totalPotentialRewards - _newTotal; require( stakingToken.transfer(msg.sender, returnable), "Transfer failed" ); } else { //withdraw directly sent tokens uint256 directSend = currentAvailableRewards - totalPotentialRewards; if (directSend > 0) { require( stakingToken.transfer(msg.sender, directSend), "Transfer failed" ); } } totalPotentialRewards = _newTotal; emit RewardPoolUpdated(msg.sender, _newTotal); } /** * @notice Gets the total amount of staked tokens * @return uint256 Total staked amount */ function getTotalStaked() public view returns (uint256) { return totalStaked; } /** * @notice Grants manager role to an address * @param _account Address to receive the manager role * @dev Only callable by addresses with ADMIN_ROLE */ function grantManagerRole(address _account) external onlyRole(ADMIN_ROLE) { grantRole(MANAGER_ROLE, _account); } /** * @notice Revokes manager role from an address * @param _account Address to lose the manager role * @dev Only callable by addresses with ADMIN_ROLE */ function revokeManagerRole(address _account) external onlyRole(ADMIN_ROLE) { revokeRole(MANAGER_ROLE, _account); } // ============ Manager Functions ============ /** * @notice Adds a new reward block with specified staking period and APY * @param _daysToStake Duration of the staking period in days * @param _apy Annual Percentage Yield in basis points (1% = 100) * @dev Only callable by addresses with MANAGER_ROLE */ function addRewardBlock( uint256 _daysToStake, uint256 _apy ) external onlyRole(MANAGER_ROLE) { require(_daysToStake > 0, "Days must be greater than 0"); require(_apy > 0, "APY must be greater than 0"); require(_apy < 30000, "APY must be greater smaller than 30000"); rewardBlocks.push( RewardBlock({daysToStake: _daysToStake, apy: _apy, enabled: false}) ); emit RewardBlockAdded(rewardBlocks.length - 1, _daysToStake, _apy); } /** * @notice Updates the APY for an existing reward block * @param _blockIndex Index of the reward block to update * @param _newApy New Annual Percentage Yield in basis points * @dev Only callable by addresses with MANAGER_ROLE */ function updateBlockAPY( uint256 _blockIndex, uint256 _newApy ) external onlyRole(MANAGER_ROLE) { require(_blockIndex < rewardBlocks.length, "Invalid block index"); require(_newApy > 0, "APY must be greater than 0"); require(_newApy < 30000, "APY must be greater smaller than 30000"); rewardBlocks[_blockIndex].apy = _newApy; emit RewardBlockUpdated(_blockIndex, _newApy); } /** * @notice Enables or disables a reward block * @param _blockIndex Index of the reward block to modify * @param _enabled New enabled status * @dev Only callable by addresses with MANAGER_ROLE */ function setBlockEnabled( uint256 _blockIndex, bool _enabled ) external onlyRole(MANAGER_ROLE) { require(_blockIndex < rewardBlocks.length, "Invalid block index"); rewardBlocks[_blockIndex].enabled = _enabled; emit RewardBlockAvailabilityUpdated(_blockIndex, _enabled); } // ============ User Functions ============ /** * @notice Stakes tokens for a specific reward block * @param _amount Amount of tokens to stake * @param _blockIndex Index of the reward block to use * @dev Requires approval of tokens before staking. Checks reward capacity before accepting stake. */ function stake( uint256 _amount, uint256 _blockIndex ) external nonReentrant whenNotPaused { require(_amount > 0, "Amount must be greater than 0"); require(_blockIndex < rewardBlocks.length, "Invalid block index"); require(rewardBlocks[_blockIndex].enabled, "Reward block not enabled"); RewardBlock storage rewardBlock = rewardBlocks[_blockIndex]; uint256 potentialReward = calculateReward( _amount, rewardBlock.apy, rewardBlock.daysToStake ); // Users should not stake without rewards. require(potentialReward > 0, "Staking amount too little"); require( reservedRewards + potentialReward <= totalPotentialRewards, "Insufficient reward capacity" ); require( stakingToken.transferFrom(msg.sender, address(this), _amount), "Transfer failed" ); reservedRewards += potentialReward; totalStaked += _amount; deposits.push( Deposit({ user: msg.sender, stakedAmount: _amount, time: block.timestamp, paid: false, rewardBlockIndex: _blockIndex, potentialReward: potentialReward, apy: rewardBlock.apy }) ); userTotalStaked[msg.sender] += _amount; emit Staked(msg.sender, deposits.length - 1, _amount, _blockIndex); } /** * @notice Withdraws staked tokens and rewards after lock period * @param _depositIndex Index of the deposit to withdraw * @dev Calculates and transfers both original stake and rewards */ function withdraw(uint256 _depositIndex) external nonReentrant { require(_depositIndex < deposits.length, "Invalid deposit index"); Deposit storage deposit = deposits[_depositIndex]; require(deposit.user == msg.sender, "Not deposit owner"); require(!deposit.paid, "Already withdrawn"); RewardBlock memory rewardBlock = rewardBlocks[deposit.rewardBlockIndex]; require( block.timestamp >= deposit.time + (rewardBlock.daysToStake * 1 days), "Lock period not ended" ); deposit.paid = true; userTotalStaked[msg.sender] -= deposit.stakedAmount; totalStaked -= deposit.stakedAmount; reservedRewards -= deposit.potentialReward; totalPotentialRewards -= deposit.potentialReward; require( stakingToken.transfer( msg.sender, deposit.stakedAmount + deposit.potentialReward ), "Transfer failed" ); emit Withdrawn( msg.sender, _depositIndex, deposit.stakedAmount, deposit.potentialReward ); } /** * @notice Allows withdrawal of staked tokens without rewards * @param _depositIndex Index of the deposit to withdraw * @dev Emergency function that forfeits rewards */ function emergencyWithdraw(uint256 _depositIndex) external nonReentrant { require(_depositIndex < deposits.length, "Invalid deposit index"); Deposit storage deposit = deposits[_depositIndex]; require(deposit.user == msg.sender, "Not deposit owner"); require(!deposit.paid, "Already withdrawn"); RewardBlock memory rewardBlock = rewardBlocks[deposit.rewardBlockIndex]; require( block.timestamp < deposit.time + (rewardBlock.daysToStake * 1 days), "No need, simply withdraw including your rewards using withdraw(depositIndex)" ); deposit.paid = true; userTotalStaked[msg.sender] -= deposit.stakedAmount; totalStaked -= deposit.stakedAmount; reservedRewards -= deposit.potentialReward; require( stakingToken.transfer(msg.sender, deposit.stakedAmount), "Transfer failed" ); emit EmergencyWithdrawn( msg.sender, _depositIndex, deposit.stakedAmount ); } // ============ View Functions ============ /** * @notice Calculates reward amount based on stake amount and duration * @param _amount Amount of tokens staked * @param _apy Annual Percentage Yield in basis points * @param _days Duration of the stake in days * @return uint256 Reward amount */ function calculateReward( uint256 _amount, uint256 _apy, uint256 _days ) public pure returns (uint256) { return (_amount * _apy * _days) / (365 * 10000); // APY in basis points } /** * @notice Gets details of a reward block * @param _index Index of the reward block * @return daysToStake Duration of the staking period * @return apy Annual Percentage Yield * @return enabled Whether the block is currently active */ function getRewardBlock( uint256 _index ) external view returns (uint256 daysToStake, uint256 apy, bool enabled) { require(_index < rewardBlocks.length, "Invalid block index"); RewardBlock memory rewardBlock = rewardBlocks[_index]; return (rewardBlock.daysToStake, rewardBlock.apy, rewardBlock.enabled); } /** * @notice Gets total number of deposits * @return uint256 Number of deposits */ function getDepositCount() external view returns (uint256) { return deposits.length; } /** * @notice Gets total number of reward blocks * @return uint256 Number of reward blocks */ function getRewardBlockCount() external view returns (uint256) { return rewardBlocks.length; } /** * @notice Calculates pending rewards for a deposit * @param _depositIndex Index of the deposit * @return uint256 Pending reward amount */ function getRewardEstimate( uint256 _depositIndex ) external view returns (uint256) { require(_depositIndex < deposits.length, "Invalid deposit index"); Deposit storage deposit = deposits[_depositIndex]; if (deposit.paid) return 0; RewardBlock memory rewardBlock = rewardBlocks[deposit.rewardBlockIndex]; return calculateReward( deposit.stakedAmount, deposit.apy, rewardBlock.daysToStake ); } // ============ Emergency Functions ============ /** * @notice Pauses the contract * @dev Only callable by addresses with ADMIN_ROLE */ function pause() external onlyRole(ADMIN_ROLE) { _pause(); } /** * @notice Unpauses the contract * @dev Only callable by addresses with ADMIN_ROLE */ function unpause() external onlyRole(ADMIN_ROLE) { _unpause(); } /** * @notice Implementation of ERC165 interface detection * @param interfaceId Interface identifier to check * @return bool Whether the interface is supported */ function supportsInterface( bytes4 interfaceId ) public view virtual override(AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"depositIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"blockIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"daysToStake","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"apy","type":"uint256"}],"name":"RewardBlockAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"blockIndex","type":"uint256"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"RewardBlockAvailabilityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"blockIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newApy","type":"uint256"}],"name":"RewardBlockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"uint256","name":"newTotal","type":"uint256"}],"name":"RewardPoolUpdated","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":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"depositIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockIndex","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"depositIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_daysToStake","type":"uint256"},{"internalType":"uint256","name":"_apy","type":"uint256"}],"name":"addRewardBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_apy","type":"uint256"},{"internalType":"uint256","name":"_days","type":"uint256"}],"name":"calculateReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deposits","outputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"stakedAmount","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"bool","name":"paid","type":"bool"},{"internalType":"uint256","name":"rewardBlockIndex","type":"uint256"},{"internalType":"uint256","name":"potentialReward","type":"uint256"},{"internalType":"uint256","name":"apy","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositIndex","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getDepositCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getRewardBlock","outputs":[{"internalType":"uint256","name":"daysToStake","type":"uint256"},{"internalType":"uint256","name":"apy","type":"uint256"},{"internalType":"bool","name":"enabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardBlockCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositIndex","type":"uint256"}],"name":"getRewardEstimate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"grantManagerRole","outputs":[],"stateMutability":"nonpayable","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":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"revokeManagerRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardBlocks","outputs":[{"internalType":"uint256","name":"daysToStake","type":"uint256"},{"internalType":"uint256","name":"apy","type":"uint256"},{"internalType":"bool","name":"enabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockIndex","type":"uint256"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setBlockEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_blockIndex","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPotentialRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockIndex","type":"uint256"},{"internalType":"uint256","name":"_newApy","type":"uint256"}],"name":"updateBlockAPY","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTotal","type":"uint256"}],"name":"updateRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userTotalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositIndex","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405234801561000f575f80fd5b50604051613964380380613964833981810160405281019061003191906103f5565b600180819055505f60025f6101000a81548160ff0219169083151502179055505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100b69061047a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250506101055f801b336101be60201b60201c565b506101367fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775336101be60201b60201c565b506101677f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08336101be60201b60201c565b506101b87f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b087fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c217756102b360201b60201c565b50610498565b5f6101cf838361031160201b60201c565b6102a95760015f808581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061024661037460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506102ad565b5f90505b92915050565b5f6102c38361037b60201b60201c565b9050815f808581526020019081526020015f20600101819055508181847fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a4505050565b5f805f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f33905090565b5f805f8381526020019081526020015f20600101549050919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6103c48261039b565b9050919050565b6103d4816103ba565b81146103de575f80fd5b50565b5f815190506103ef816103cb565b92915050565b5f6020828403121561040a57610409610397565b5b5f610417848285016103e1565b91505092915050565b5f82825260208201905092915050565b7f496e76616c696420746f6b656e206164647265737300000000000000000000005f82015250565b5f610464601583610420565b915061046f82610430565b602082019050919050565b5f6020820190508181035f83015261049181610458565b9050919050565b6080516134836104e15f395f81816109e20152818161109c015281816114e70152818161170301528181611d6101528181611e2701528181611f24015261201d01526134835ff3fe608060405234801561000f575f80fd5b5060043610610204575f3560e01c8063719de1ef11610118578063a217fddf116100ab578063b02c43d01161007a578063b02c43d0146105c8578063be4dc94f146105fe578063cc39a89c1461061a578063d547741f14610636578063ec87621c1461065257610204565b8063a217fddf14610540578063a3d01d681461055e578063a8e62b971461057a578063af5ce104146105aa57610204565b8063817b1cd2116100e7578063817b1cd2146104ca5780638456cb59146104e857806391d14854146104f25780639363a1411461052257610204565b8063719de1ef1461044257806372f702f31461047257806375b238fc146104905780637b0472f0146104ae57610204565b806336568abe1161019b5780635312ea8e1161016a5780635312ea8e1461039e5780635ae287c7146103ba5780635b5dc502146103d65780635c975abb146103f257806362bc78551461041057610204565b806336568abe146103285780633f4ba83a1461034457806343ef5c1a1461034e57806343f753141461038057610204565b806326e885e3116101d757806326e885e3146102a45780632e1a7d4d146102c05780632f2ff15d146102dc57806330ecb285146102f857610204565b806301ffc9a714610208578063083d9f86146102385780630917e77614610256578063248a9ca314610274575b5f80fd5b610222600480360381019061021d91906126a6565b610670565b60405161022f91906126eb565b60405180910390f35b610240610681565b60405161024d919061271c565b60405180910390f35b61025e610687565b60405161026b919061271c565b60405180910390f35b61028e60048036038101906102899190612768565b610690565b60405161029b91906127a2565b60405180910390f35b6102be60048036038101906102b99190612815565b6106ac565b005b6102da60048036038101906102d5919061286a565b610704565b005b6102f660048036038101906102f19190612895565b610b33565b005b610312600480360381019061030d919061286a565b610b55565b60405161031f919061271c565b60405180910390f35b610342600480360381019061033d9190612895565b610c5e565b005b61034c610cd9565b005b6103686004803603810190610363919061286a565b610d0e565b604051610377939291906128d3565b60405180910390f35b610388610dcf565b604051610395919061271c565b60405180910390f35b6103b860048036038101906103b3919061286a565b610ddb565b005b6103d460048036038101906103cf9190612908565b6111d8565b005b6103f060048036038101906103eb9190612970565b611392565b005b6103fa61147a565b60405161040791906126eb565b60405180910390f35b61042a6004803603810190610425919061286a565b61148f565b604051610439939291906128d3565b60405180910390f35b61045c60048036038101906104579190612815565b6114d0565b604051610469919061271c565b60405180910390f35b61047a6114e5565b6040516104879190612a09565b60405180910390f35b610498611509565b6040516104a591906127a2565b60405180910390f35b6104c860048036038101906104c39190612908565b61152d565b005b6104d26119de565b6040516104df919061271c565b60405180910390f35b6104f06119e4565b005b61050c60048036038101906105079190612895565b611a19565b60405161051991906126eb565b60405180910390f35b61052a611a7c565b604051610537919061271c565b60405180910390f35b610548611a88565b60405161055591906127a2565b60405180910390f35b61057860048036038101906105739190612908565b611a8e565b005b610594600480360381019061058f9190612a22565b611bea565b6040516105a1919061271c565b60405180910390f35b6105b2611c19565b6040516105bf919061271c565b60405180910390f35b6105e260048036038101906105dd919061286a565b611c1f565b6040516105f59796959493929190612a81565b60405180910390f35b61061860048036038101906106139190612815565b611c97565b005b610634600480360381019061062f919061286a565b611cef565b005b610650600480360381019061064b9190612895565b612154565b005b61065a612176565b60405161066791906127a2565b60405180910390f35b5f61067a8261219a565b9050919050565b60045481565b5f600354905090565b5f805f8381526020019081526020015f20600101549050919050565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c217756106d681612213565b6107007f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0883610b33565b5050565b61070c612227565b6007805490508110610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074a90612b48565b60405180910390fd5b5f6007828154811061076857610767612b66565b5b905f5260205f20906007020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610806576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fd90612bdd565b60405180910390fd5b806003015f9054906101000a900460ff1615610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e90612c45565b60405180910390fd5b5f60068260040154815481106108705761086f612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff161515151581525050905062015180815f01516108c89190612c90565b82600201546108d79190612cd1565b421015610919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091090612d4e565b60405180910390fd5b6001826003015f6101000a81548160ff021916908315150217905550816001015460085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546109859190612d6c565b92505081905550816001015460035f8282546109a19190612d6c565b92505081905550816005015460055f8282546109bd9190612d6c565b92505081905550816005015460045f8282546109d99190612d6c565b925050819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3384600501548560010154610a319190612cd1565b6040518363ffffffff1660e01b8152600401610a4e929190612d9f565b6020604051808303815f875af1158015610a6a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8e9190612dda565b610acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac490612e4f565b60405180910390fd5b823373ffffffffffffffffffffffffffffffffffffffff167f75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a2184600101548560050154604051610b1e929190612e6d565b60405180910390a35050610b3061226d565b50565b610b3c82610690565b610b4581612213565b610b4f8383612276565b50505050565b5f6007805490508210610b9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9490612b48565b60405180910390fd5b5f60078381548110610bb257610bb1612b66565b5b905f5260205f2090600702019050806003015f9054906101000a900460ff1615610bdf575f915050610c59565b5f6006826004015481548110610bf857610bf7612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff1615151515815250509050610c5482600101548360060154835f0151611bea565b925050505b919050565b610c6661235f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cca576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd48282612366565b505050565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775610d0381612213565b610d0b61244f565b50565b5f805f6006805490508410610d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4f90612ede565b60405180910390fd5b5f60068581548110610d6d57610d6c612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff1615151515815250509050805f015181602001518260400151935093509350509193909250565b5f600680549050905090565b610de3612227565b6007805490508110610e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2190612b48565b60405180910390fd5b5f60078281548110610e3f57610e3e612b66565b5b905f5260205f20906007020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610edd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed490612bdd565b60405180910390fd5b806003015f9054906101000a900460ff1615610f2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2590612c45565b60405180910390fd5b5f6006826004015481548110610f4757610f46612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff161515151581525050905062015180815f0151610f9f9190612c90565b8260020154610fae9190612cd1565b4210610fef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe690612f92565b60405180910390fd5b6001826003015f6101000a81548160ff021916908315150217905550816001015460085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461105b9190612d6c565b92505081905550816001015460035f8282546110779190612d6c565b92505081905550816005015460055f8282546110939190612d6c565b925050819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3384600101546040518363ffffffff1660e01b81526004016110f9929190612d9f565b6020604051808303815f875af1158015611115573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111399190612dda565b611178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116f90612e4f565b60405180910390fd5b823373ffffffffffffffffffffffffffffffffffffffff167fb47853100b79d8afa66237bdb4f7f09d96628ee23aa8aac8a8c21a901c67ddb284600101546040516111c3919061271c565b60405180910390a350506111d561226d565b50565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0861120281612213565b5f8311611244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123b90612ffa565b60405180910390fd5b5f8211611286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127d90613062565b60405180910390fd5b61753082106112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c1906130f0565b60405180910390fd5b600660405180606001604052808581526020018481526020015f1515815250908060018154018082558091505060019003905f5260205f2090600302015f909190919091505f820151815f0155602082015181600101556040820151816002015f6101000a81548160ff021916908315150217905550505060016006805490506113549190612d6c565b7fe2e3574bef51c6ccb1bcd12648f35cb9fc5c2da079ae8a65e363966027e1efb28484604051611385929190612e6d565b60405180910390a2505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086113bc81612213565b6006805490508310611403576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113fa90612ede565b60405180910390fd5b816006848154811061141857611417612b66565b5b905f5260205f2090600302016002015f6101000a81548160ff021916908315150217905550827f22a0356e34b00dae2cc4132c94f9e15b57e9754225508cf6f9710eb5dba2bfc48360405161146d91906126eb565b60405180910390a2505050565b5f60025f9054906101000a900460ff16905090565b6006818154811061149e575f80fd5b905f5260205f2090600302015f91509050805f015490806001015490806002015f9054906101000a900460ff16905083565b6008602052805f5260405f205f915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b611535612227565b61153d6124b0565b5f821161157f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157690613158565b60405180910390fd5b60068054905081106115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90612ede565b60405180910390fd5b600681815481106115da576115d9612b66565b5b905f5260205f2090600302016002015f9054906101000a900460ff16611635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161162c906131c0565b60405180910390fd5b5f6006828154811061164a57611649612b66565b5b905f5260205f20906003020190505f61166b848360010154845f0154611bea565b90505f81116116af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a690613228565b60405180910390fd5b600454816005546116c09190612cd1565b1115611701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f890613290565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330876040518463ffffffff1660e01b815260040161175e939291906132ae565b6020604051808303815f875af115801561177a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061179e9190612dda565b6117dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d490612e4f565b60405180910390fd5b8060055f8282546117ee9190612cd1565b925050819055508360035f8282546118069190612cd1565b9250508190555060076040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018681526020014281526020015f151581526020018581526020018381526020018460010154815250908060018154018082558091505060019003905f5260205f2090600702015f909190919091505f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201556060820151816003015f6101000a81548160ff0219169083151502179055506080820151816004015560a0820151816005015560c0820151816006015550508360085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546119679190612cd1565b9250508190555060016007805490506119809190612d6c565b3373ffffffffffffffffffffffffffffffffffffffff167fb4caaf29adda3eefee3ad552a8e85058589bf834c7466cae4ee58787f70589ed86866040516119c8929190612e6d565b60405180910390a350506119da61226d565b5050565b60035481565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775611a0e81612213565b611a166124f1565b50565b5f805f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f600780549050905090565b5f801b81565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611ab881612213565b6006805490508310611aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af690612ede565b60405180910390fd5b5f8211611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890613062565b60405180910390fd5b6175308210611b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7c906130f0565b60405180910390fd5b8160068481548110611b9a57611b99612b66565b5b905f5260205f20906003020160010181905550827f55fb5e89ca36baf16337ac3eb669da37c6528c33dba1f16d350226b20e0800e783604051611bdd919061271c565b60405180910390a2505050565b5f6237b1d0828486611bfc9190612c90565b611c069190612c90565b611c109190613310565b90509392505050565b60055481565b60078181548110611c2e575f80fd5b905f5260205f2090600702015f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002015490806003015f9054906101000a900460ff16908060040154908060050154908060060154905087565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775611cc181612213565b611ceb7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0883612154565b5050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611d1981612213565b600554821015611d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d55906133b0565b60405180910390fd5b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611db891906133ce565b602060405180830381865afa158015611dd3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611df791906133fb565b90505f60035482611e089190612d6c565b9050600454841115611f07575f60045485611e239190612d6c565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401611e82939291906132ae565b6020604051808303815f875af1158015611e9e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ec29190612dda565b611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890612e4f565b60405180910390fd5b506120f9565b600454841015612002575f84600454611f209190612d6c565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401611f7d929190612d9f565b6020604051808303815f875af1158015611f99573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fbd9190612dda565b611ffc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff390612e4f565b60405180910390fd5b506120f8565b5f600454826120119190612d6c565b90505f8111156120f6577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401612076929190612d9f565b6020604051808303815f875af1158015612092573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120b69190612dda565b6120f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ec90612e4f565b60405180910390fd5b5b505b5b836004819055503373ffffffffffffffffffffffffffffffffffffffff167f0333f461325c5d525713dc8a37127163b51366ee35acf64f22cc0472f343c75a85604051612146919061271c565b60405180910390a250505050565b61215d82610690565b61216681612213565b6121708383612366565b50505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061220c575061220b82612553565b5b9050919050565b6122248161221f61235f565b6125bc565b50565b600260015403612263576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b60018081905550565b5f6122818383611a19565b6123555760015f808581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506122f261235f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050612359565b5f90505b92915050565b5f33905090565b5f6123718383611a19565b15612445575f805f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506123e261235f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050612449565b5f90505b92915050565b61245761260d565b5f60025f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61249961235f565b6040516124a691906133ce565b60405180910390a1565b6124b861147a565b156124ef576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6124f96124b0565b600160025f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861253c61235f565b60405161254991906133ce565b60405180910390a1565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6125c68282611a19565b6126095780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401612600929190613426565b60405180910390fd5b5050565b61261561147a565b61264b576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61268581612651565b811461268f575f80fd5b50565b5f813590506126a08161267c565b92915050565b5f602082840312156126bb576126ba61264d565b5b5f6126c884828501612692565b91505092915050565b5f8115159050919050565b6126e5816126d1565b82525050565b5f6020820190506126fe5f8301846126dc565b92915050565b5f819050919050565b61271681612704565b82525050565b5f60208201905061272f5f83018461270d565b92915050565b5f819050919050565b61274781612735565b8114612751575f80fd5b50565b5f813590506127628161273e565b92915050565b5f6020828403121561277d5761277c61264d565b5b5f61278a84828501612754565b91505092915050565b61279c81612735565b82525050565b5f6020820190506127b55f830184612793565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6127e4826127bb565b9050919050565b6127f4816127da565b81146127fe575f80fd5b50565b5f8135905061280f816127eb565b92915050565b5f6020828403121561282a5761282961264d565b5b5f61283784828501612801565b91505092915050565b61284981612704565b8114612853575f80fd5b50565b5f8135905061286481612840565b92915050565b5f6020828403121561287f5761287e61264d565b5b5f61288c84828501612856565b91505092915050565b5f80604083850312156128ab576128aa61264d565b5b5f6128b885828601612754565b92505060206128c985828601612801565b9150509250929050565b5f6060820190506128e65f83018661270d565b6128f3602083018561270d565b61290060408301846126dc565b949350505050565b5f806040838503121561291e5761291d61264d565b5b5f61292b85828601612856565b925050602061293c85828601612856565b9150509250929050565b61294f816126d1565b8114612959575f80fd5b50565b5f8135905061296a81612946565b92915050565b5f80604083850312156129865761298561264d565b5b5f61299385828601612856565b92505060206129a48582860161295c565b9150509250929050565b5f819050919050565b5f6129d16129cc6129c7846127bb565b6129ae565b6127bb565b9050919050565b5f6129e2826129b7565b9050919050565b5f6129f3826129d8565b9050919050565b612a03816129e9565b82525050565b5f602082019050612a1c5f8301846129fa565b92915050565b5f805f60608486031215612a3957612a3861264d565b5b5f612a4686828701612856565b9350506020612a5786828701612856565b9250506040612a6886828701612856565b9150509250925092565b612a7b816127da565b82525050565b5f60e082019050612a945f83018a612a72565b612aa1602083018961270d565b612aae604083018861270d565b612abb60608301876126dc565b612ac8608083018661270d565b612ad560a083018561270d565b612ae260c083018461270d565b98975050505050505050565b5f82825260208201905092915050565b7f496e76616c6964206465706f73697420696e64657800000000000000000000005f82015250565b5f612b32601583612aee565b9150612b3d82612afe565b602082019050919050565b5f6020820190508181035f830152612b5f81612b26565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e6f74206465706f736974206f776e65720000000000000000000000000000005f82015250565b5f612bc7601183612aee565b9150612bd282612b93565b602082019050919050565b5f6020820190508181035f830152612bf481612bbb565b9050919050565b7f416c72656164792077697468647261776e0000000000000000000000000000005f82015250565b5f612c2f601183612aee565b9150612c3a82612bfb565b602082019050919050565b5f6020820190508181035f830152612c5c81612c23565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612c9a82612704565b9150612ca583612704565b9250828202612cb381612704565b91508282048414831517612cca57612cc9612c63565b5b5092915050565b5f612cdb82612704565b9150612ce683612704565b9250828201905080821115612cfe57612cfd612c63565b5b92915050565b7f4c6f636b20706572696f64206e6f7420656e64656400000000000000000000005f82015250565b5f612d38601583612aee565b9150612d4382612d04565b602082019050919050565b5f6020820190508181035f830152612d6581612d2c565b9050919050565b5f612d7682612704565b9150612d8183612704565b9250828203905081811115612d9957612d98612c63565b5b92915050565b5f604082019050612db25f830185612a72565b612dbf602083018461270d565b9392505050565b5f81519050612dd481612946565b92915050565b5f60208284031215612def57612dee61264d565b5b5f612dfc84828501612dc6565b91505092915050565b7f5472616e73666572206661696c656400000000000000000000000000000000005f82015250565b5f612e39600f83612aee565b9150612e4482612e05565b602082019050919050565b5f6020820190508181035f830152612e6681612e2d565b9050919050565b5f604082019050612e805f83018561270d565b612e8d602083018461270d565b9392505050565b7f496e76616c696420626c6f636b20696e646578000000000000000000000000005f82015250565b5f612ec8601383612aee565b9150612ed382612e94565b602082019050919050565b5f6020820190508181035f830152612ef581612ebc565b9050919050565b7f4e6f206e6565642c2073696d706c7920776974686472617720696e636c7564695f8201527f6e6720796f75722072657761726473207573696e67207769746864726177286460208201527f65706f736974496e646578290000000000000000000000000000000000000000604082015250565b5f612f7c604c83612aee565b9150612f8782612efc565b606082019050919050565b5f6020820190508181035f830152612fa981612f70565b9050919050565b7f44617973206d7573742062652067726561746572207468616e203000000000005f82015250565b5f612fe4601b83612aee565b9150612fef82612fb0565b602082019050919050565b5f6020820190508181035f83015261301181612fd8565b9050919050565b7f415059206d7573742062652067726561746572207468616e20300000000000005f82015250565b5f61304c601a83612aee565b915061305782613018565b602082019050919050565b5f6020820190508181035f83015261307981613040565b9050919050565b7f415059206d757374206265206772656174657220736d616c6c6572207468616e5f8201527f2033303030300000000000000000000000000000000000000000000000000000602082015250565b5f6130da602683612aee565b91506130e582613080565b604082019050919050565b5f6020820190508181035f830152613107816130ce565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e20300000005f82015250565b5f613142601d83612aee565b915061314d8261310e565b602082019050919050565b5f6020820190508181035f83015261316f81613136565b9050919050565b7f52657761726420626c6f636b206e6f7420656e61626c656400000000000000005f82015250565b5f6131aa601883612aee565b91506131b582613176565b602082019050919050565b5f6020820190508181035f8301526131d78161319e565b9050919050565b7f5374616b696e6720616d6f756e7420746f6f206c6974746c65000000000000005f82015250565b5f613212601983612aee565b915061321d826131de565b602082019050919050565b5f6020820190508181035f83015261323f81613206565b9050919050565b7f496e73756666696369656e7420726577617264206361706163697479000000005f82015250565b5f61327a601c83612aee565b915061328582613246565b602082019050919050565b5f6020820190508181035f8301526132a78161326e565b9050919050565b5f6060820190506132c15f830186612a72565b6132ce6020830185612a72565b6132db604083018461270d565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61331a82612704565b915061332583612704565b925082613335576133346132e3565b5b828204905092915050565b7f43616e6e6f74207365742062656c6f77207265736572766564207265776172645f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f61339a602183612aee565b91506133a582613340565b604082019050919050565b5f6020820190508181035f8301526133c78161338e565b9050919050565b5f6020820190506133e15f830184612a72565b92915050565b5f815190506133f581612840565b92915050565b5f602082840312156134105761340f61264d565b5b5f61341d848285016133e7565b91505092915050565b5f6040820190506134395f830185612a72565b6134466020830184612793565b939250505056fea26469706673582212205fd66e7375c1bb146a704b265cfebf3186e605caac08069ab2ece658cde9bb6964736f6c634300081a0033000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d49
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610204575f3560e01c8063719de1ef11610118578063a217fddf116100ab578063b02c43d01161007a578063b02c43d0146105c8578063be4dc94f146105fe578063cc39a89c1461061a578063d547741f14610636578063ec87621c1461065257610204565b8063a217fddf14610540578063a3d01d681461055e578063a8e62b971461057a578063af5ce104146105aa57610204565b8063817b1cd2116100e7578063817b1cd2146104ca5780638456cb59146104e857806391d14854146104f25780639363a1411461052257610204565b8063719de1ef1461044257806372f702f31461047257806375b238fc146104905780637b0472f0146104ae57610204565b806336568abe1161019b5780635312ea8e1161016a5780635312ea8e1461039e5780635ae287c7146103ba5780635b5dc502146103d65780635c975abb146103f257806362bc78551461041057610204565b806336568abe146103285780633f4ba83a1461034457806343ef5c1a1461034e57806343f753141461038057610204565b806326e885e3116101d757806326e885e3146102a45780632e1a7d4d146102c05780632f2ff15d146102dc57806330ecb285146102f857610204565b806301ffc9a714610208578063083d9f86146102385780630917e77614610256578063248a9ca314610274575b5f80fd5b610222600480360381019061021d91906126a6565b610670565b60405161022f91906126eb565b60405180910390f35b610240610681565b60405161024d919061271c565b60405180910390f35b61025e610687565b60405161026b919061271c565b60405180910390f35b61028e60048036038101906102899190612768565b610690565b60405161029b91906127a2565b60405180910390f35b6102be60048036038101906102b99190612815565b6106ac565b005b6102da60048036038101906102d5919061286a565b610704565b005b6102f660048036038101906102f19190612895565b610b33565b005b610312600480360381019061030d919061286a565b610b55565b60405161031f919061271c565b60405180910390f35b610342600480360381019061033d9190612895565b610c5e565b005b61034c610cd9565b005b6103686004803603810190610363919061286a565b610d0e565b604051610377939291906128d3565b60405180910390f35b610388610dcf565b604051610395919061271c565b60405180910390f35b6103b860048036038101906103b3919061286a565b610ddb565b005b6103d460048036038101906103cf9190612908565b6111d8565b005b6103f060048036038101906103eb9190612970565b611392565b005b6103fa61147a565b60405161040791906126eb565b60405180910390f35b61042a6004803603810190610425919061286a565b61148f565b604051610439939291906128d3565b60405180910390f35b61045c60048036038101906104579190612815565b6114d0565b604051610469919061271c565b60405180910390f35b61047a6114e5565b6040516104879190612a09565b60405180910390f35b610498611509565b6040516104a591906127a2565b60405180910390f35b6104c860048036038101906104c39190612908565b61152d565b005b6104d26119de565b6040516104df919061271c565b60405180910390f35b6104f06119e4565b005b61050c60048036038101906105079190612895565b611a19565b60405161051991906126eb565b60405180910390f35b61052a611a7c565b604051610537919061271c565b60405180910390f35b610548611a88565b60405161055591906127a2565b60405180910390f35b61057860048036038101906105739190612908565b611a8e565b005b610594600480360381019061058f9190612a22565b611bea565b6040516105a1919061271c565b60405180910390f35b6105b2611c19565b6040516105bf919061271c565b60405180910390f35b6105e260048036038101906105dd919061286a565b611c1f565b6040516105f59796959493929190612a81565b60405180910390f35b61061860048036038101906106139190612815565b611c97565b005b610634600480360381019061062f919061286a565b611cef565b005b610650600480360381019061064b9190612895565b612154565b005b61065a612176565b60405161066791906127a2565b60405180910390f35b5f61067a8261219a565b9050919050565b60045481565b5f600354905090565b5f805f8381526020019081526020015f20600101549050919050565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c217756106d681612213565b6107007f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0883610b33565b5050565b61070c612227565b6007805490508110610753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074a90612b48565b60405180910390fd5b5f6007828154811061076857610767612b66565b5b905f5260205f20906007020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610806576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fd90612bdd565b60405180910390fd5b806003015f9054906101000a900460ff1615610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e90612c45565b60405180910390fd5b5f60068260040154815481106108705761086f612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff161515151581525050905062015180815f01516108c89190612c90565b82600201546108d79190612cd1565b421015610919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091090612d4e565b60405180910390fd5b6001826003015f6101000a81548160ff021916908315150217905550816001015460085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546109859190612d6c565b92505081905550816001015460035f8282546109a19190612d6c565b92505081905550816005015460055f8282546109bd9190612d6c565b92505081905550816005015460045f8282546109d99190612d6c565b925050819055507f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4973ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3384600501548560010154610a319190612cd1565b6040518363ffffffff1660e01b8152600401610a4e929190612d9f565b6020604051808303815f875af1158015610a6a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8e9190612dda565b610acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac490612e4f565b60405180910390fd5b823373ffffffffffffffffffffffffffffffffffffffff167f75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a2184600101548560050154604051610b1e929190612e6d565b60405180910390a35050610b3061226d565b50565b610b3c82610690565b610b4581612213565b610b4f8383612276565b50505050565b5f6007805490508210610b9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9490612b48565b60405180910390fd5b5f60078381548110610bb257610bb1612b66565b5b905f5260205f2090600702019050806003015f9054906101000a900460ff1615610bdf575f915050610c59565b5f6006826004015481548110610bf857610bf7612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff1615151515815250509050610c5482600101548360060154835f0151611bea565b925050505b919050565b610c6661235f565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cca576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd48282612366565b505050565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775610d0381612213565b610d0b61244f565b50565b5f805f6006805490508410610d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4f90612ede565b60405180910390fd5b5f60068581548110610d6d57610d6c612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff1615151515815250509050805f015181602001518260400151935093509350509193909250565b5f600680549050905090565b610de3612227565b6007805490508110610e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2190612b48565b60405180910390fd5b5f60078281548110610e3f57610e3e612b66565b5b905f5260205f20906007020190503373ffffffffffffffffffffffffffffffffffffffff16815f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610edd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed490612bdd565b60405180910390fd5b806003015f9054906101000a900460ff1615610f2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2590612c45565b60405180910390fd5b5f6006826004015481548110610f4757610f46612b66565b5b905f5260205f2090600302016040518060600160405290815f820154815260200160018201548152602001600282015f9054906101000a900460ff161515151581525050905062015180815f0151610f9f9190612c90565b8260020154610fae9190612cd1565b4210610fef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe690612f92565b60405180910390fd5b6001826003015f6101000a81548160ff021916908315150217905550816001015460085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461105b9190612d6c565b92505081905550816001015460035f8282546110779190612d6c565b92505081905550816005015460055f8282546110939190612d6c565b925050819055507f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4973ffffffffffffffffffffffffffffffffffffffff1663a9059cbb3384600101546040518363ffffffff1660e01b81526004016110f9929190612d9f565b6020604051808303815f875af1158015611115573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111399190612dda565b611178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116f90612e4f565b60405180910390fd5b823373ffffffffffffffffffffffffffffffffffffffff167fb47853100b79d8afa66237bdb4f7f09d96628ee23aa8aac8a8c21a901c67ddb284600101546040516111c3919061271c565b60405180910390a350506111d561226d565b50565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0861120281612213565b5f8311611244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123b90612ffa565b60405180910390fd5b5f8211611286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127d90613062565b60405180910390fd5b61753082106112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c1906130f0565b60405180910390fd5b600660405180606001604052808581526020018481526020015f1515815250908060018154018082558091505060019003905f5260205f2090600302015f909190919091505f820151815f0155602082015181600101556040820151816002015f6101000a81548160ff021916908315150217905550505060016006805490506113549190612d6c565b7fe2e3574bef51c6ccb1bcd12648f35cb9fc5c2da079ae8a65e363966027e1efb28484604051611385929190612e6d565b60405180910390a2505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086113bc81612213565b6006805490508310611403576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113fa90612ede565b60405180910390fd5b816006848154811061141857611417612b66565b5b905f5260205f2090600302016002015f6101000a81548160ff021916908315150217905550827f22a0356e34b00dae2cc4132c94f9e15b57e9754225508cf6f9710eb5dba2bfc48360405161146d91906126eb565b60405180910390a2505050565b5f60025f9054906101000a900460ff16905090565b6006818154811061149e575f80fd5b905f5260205f2090600302015f91509050805f015490806001015490806002015f9054906101000a900460ff16905083565b6008602052805f5260405f205f915090505481565b7f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4981565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b611535612227565b61153d6124b0565b5f821161157f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157690613158565b60405180910390fd5b60068054905081106115c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bd90612ede565b60405180910390fd5b600681815481106115da576115d9612b66565b5b905f5260205f2090600302016002015f9054906101000a900460ff16611635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161162c906131c0565b60405180910390fd5b5f6006828154811061164a57611649612b66565b5b905f5260205f20906003020190505f61166b848360010154845f0154611bea565b90505f81116116af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a690613228565b60405180910390fd5b600454816005546116c09190612cd1565b1115611701576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f890613290565b60405180910390fd5b7f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4973ffffffffffffffffffffffffffffffffffffffff166323b872dd3330876040518463ffffffff1660e01b815260040161175e939291906132ae565b6020604051808303815f875af115801561177a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061179e9190612dda565b6117dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d490612e4f565b60405180910390fd5b8060055f8282546117ee9190612cd1565b925050819055508360035f8282546118069190612cd1565b9250508190555060076040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018681526020014281526020015f151581526020018581526020018381526020018460010154815250908060018154018082558091505060019003905f5260205f2090600702015f909190919091505f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201556060820151816003015f6101000a81548160ff0219169083151502179055506080820151816004015560a0820151816005015560c0820151816006015550508360085f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546119679190612cd1565b9250508190555060016007805490506119809190612d6c565b3373ffffffffffffffffffffffffffffffffffffffff167fb4caaf29adda3eefee3ad552a8e85058589bf834c7466cae4ee58787f70589ed86866040516119c8929190612e6d565b60405180910390a350506119da61226d565b5050565b60035481565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775611a0e81612213565b611a166124f1565b50565b5f805f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f600780549050905090565b5f801b81565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611ab881612213565b6006805490508310611aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af690612ede565b60405180910390fd5b5f8211611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890613062565b60405180910390fd5b6175308210611b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7c906130f0565b60405180910390fd5b8160068481548110611b9a57611b99612b66565b5b905f5260205f20906003020160010181905550827f55fb5e89ca36baf16337ac3eb669da37c6528c33dba1f16d350226b20e0800e783604051611bdd919061271c565b60405180910390a2505050565b5f6237b1d0828486611bfc9190612c90565b611c069190612c90565b611c109190613310565b90509392505050565b60055481565b60078181548110611c2e575f80fd5b905f5260205f2090600702015f91509050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015490806002015490806003015f9054906101000a900460ff16908060040154908060050154908060060154905087565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775611cc181612213565b611ceb7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0883612154565b5050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611d1981612213565b600554821015611d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d55906133b0565b60405180910390fd5b5f7f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4973ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611db891906133ce565b602060405180830381865afa158015611dd3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611df791906133fb565b90505f60035482611e089190612d6c565b9050600454841115611f07575f60045485611e239190612d6c565b90507f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4973ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b8152600401611e82939291906132ae565b6020604051808303815f875af1158015611e9e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ec29190612dda565b611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890612e4f565b60405180910390fd5b506120f9565b600454841015612002575f84600454611f209190612d6c565b90507f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4973ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401611f7d929190612d9f565b6020604051808303815f875af1158015611f99573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fbd9190612dda565b611ffc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff390612e4f565b60405180910390fd5b506120f8565b5f600454826120119190612d6c565b90505f8111156120f6577f000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d4973ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401612076929190612d9f565b6020604051808303815f875af1158015612092573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120b69190612dda565b6120f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ec90612e4f565b60405180910390fd5b5b505b5b836004819055503373ffffffffffffffffffffffffffffffffffffffff167f0333f461325c5d525713dc8a37127163b51366ee35acf64f22cc0472f343c75a85604051612146919061271c565b60405180910390a250505050565b61215d82610690565b61216681612213565b6121708383612366565b50505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061220c575061220b82612553565b5b9050919050565b6122248161221f61235f565b6125bc565b50565b600260015403612263576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b60018081905550565b5f6122818383611a19565b6123555760015f808581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506122f261235f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050612359565b5f90505b92915050565b5f33905090565b5f6123718383611a19565b15612445575f805f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506123e261235f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050612449565b5f90505b92915050565b61245761260d565b5f60025f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61249961235f565b6040516124a691906133ce565b60405180910390a1565b6124b861147a565b156124ef576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6124f96124b0565b600160025f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861253c61235f565b60405161254991906133ce565b60405180910390a1565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6125c68282611a19565b6126095780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401612600929190613426565b60405180910390fd5b5050565b61261561147a565b61264b576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61268581612651565b811461268f575f80fd5b50565b5f813590506126a08161267c565b92915050565b5f602082840312156126bb576126ba61264d565b5b5f6126c884828501612692565b91505092915050565b5f8115159050919050565b6126e5816126d1565b82525050565b5f6020820190506126fe5f8301846126dc565b92915050565b5f819050919050565b61271681612704565b82525050565b5f60208201905061272f5f83018461270d565b92915050565b5f819050919050565b61274781612735565b8114612751575f80fd5b50565b5f813590506127628161273e565b92915050565b5f6020828403121561277d5761277c61264d565b5b5f61278a84828501612754565b91505092915050565b61279c81612735565b82525050565b5f6020820190506127b55f830184612793565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6127e4826127bb565b9050919050565b6127f4816127da565b81146127fe575f80fd5b50565b5f8135905061280f816127eb565b92915050565b5f6020828403121561282a5761282961264d565b5b5f61283784828501612801565b91505092915050565b61284981612704565b8114612853575f80fd5b50565b5f8135905061286481612840565b92915050565b5f6020828403121561287f5761287e61264d565b5b5f61288c84828501612856565b91505092915050565b5f80604083850312156128ab576128aa61264d565b5b5f6128b885828601612754565b92505060206128c985828601612801565b9150509250929050565b5f6060820190506128e65f83018661270d565b6128f3602083018561270d565b61290060408301846126dc565b949350505050565b5f806040838503121561291e5761291d61264d565b5b5f61292b85828601612856565b925050602061293c85828601612856565b9150509250929050565b61294f816126d1565b8114612959575f80fd5b50565b5f8135905061296a81612946565b92915050565b5f80604083850312156129865761298561264d565b5b5f61299385828601612856565b92505060206129a48582860161295c565b9150509250929050565b5f819050919050565b5f6129d16129cc6129c7846127bb565b6129ae565b6127bb565b9050919050565b5f6129e2826129b7565b9050919050565b5f6129f3826129d8565b9050919050565b612a03816129e9565b82525050565b5f602082019050612a1c5f8301846129fa565b92915050565b5f805f60608486031215612a3957612a3861264d565b5b5f612a4686828701612856565b9350506020612a5786828701612856565b9250506040612a6886828701612856565b9150509250925092565b612a7b816127da565b82525050565b5f60e082019050612a945f83018a612a72565b612aa1602083018961270d565b612aae604083018861270d565b612abb60608301876126dc565b612ac8608083018661270d565b612ad560a083018561270d565b612ae260c083018461270d565b98975050505050505050565b5f82825260208201905092915050565b7f496e76616c6964206465706f73697420696e64657800000000000000000000005f82015250565b5f612b32601583612aee565b9150612b3d82612afe565b602082019050919050565b5f6020820190508181035f830152612b5f81612b26565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e6f74206465706f736974206f776e65720000000000000000000000000000005f82015250565b5f612bc7601183612aee565b9150612bd282612b93565b602082019050919050565b5f6020820190508181035f830152612bf481612bbb565b9050919050565b7f416c72656164792077697468647261776e0000000000000000000000000000005f82015250565b5f612c2f601183612aee565b9150612c3a82612bfb565b602082019050919050565b5f6020820190508181035f830152612c5c81612c23565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612c9a82612704565b9150612ca583612704565b9250828202612cb381612704565b91508282048414831517612cca57612cc9612c63565b5b5092915050565b5f612cdb82612704565b9150612ce683612704565b9250828201905080821115612cfe57612cfd612c63565b5b92915050565b7f4c6f636b20706572696f64206e6f7420656e64656400000000000000000000005f82015250565b5f612d38601583612aee565b9150612d4382612d04565b602082019050919050565b5f6020820190508181035f830152612d6581612d2c565b9050919050565b5f612d7682612704565b9150612d8183612704565b9250828203905081811115612d9957612d98612c63565b5b92915050565b5f604082019050612db25f830185612a72565b612dbf602083018461270d565b9392505050565b5f81519050612dd481612946565b92915050565b5f60208284031215612def57612dee61264d565b5b5f612dfc84828501612dc6565b91505092915050565b7f5472616e73666572206661696c656400000000000000000000000000000000005f82015250565b5f612e39600f83612aee565b9150612e4482612e05565b602082019050919050565b5f6020820190508181035f830152612e6681612e2d565b9050919050565b5f604082019050612e805f83018561270d565b612e8d602083018461270d565b9392505050565b7f496e76616c696420626c6f636b20696e646578000000000000000000000000005f82015250565b5f612ec8601383612aee565b9150612ed382612e94565b602082019050919050565b5f6020820190508181035f830152612ef581612ebc565b9050919050565b7f4e6f206e6565642c2073696d706c7920776974686472617720696e636c7564695f8201527f6e6720796f75722072657761726473207573696e67207769746864726177286460208201527f65706f736974496e646578290000000000000000000000000000000000000000604082015250565b5f612f7c604c83612aee565b9150612f8782612efc565b606082019050919050565b5f6020820190508181035f830152612fa981612f70565b9050919050565b7f44617973206d7573742062652067726561746572207468616e203000000000005f82015250565b5f612fe4601b83612aee565b9150612fef82612fb0565b602082019050919050565b5f6020820190508181035f83015261301181612fd8565b9050919050565b7f415059206d7573742062652067726561746572207468616e20300000000000005f82015250565b5f61304c601a83612aee565b915061305782613018565b602082019050919050565b5f6020820190508181035f83015261307981613040565b9050919050565b7f415059206d757374206265206772656174657220736d616c6c6572207468616e5f8201527f2033303030300000000000000000000000000000000000000000000000000000602082015250565b5f6130da602683612aee565b91506130e582613080565b604082019050919050565b5f6020820190508181035f830152613107816130ce565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e20300000005f82015250565b5f613142601d83612aee565b915061314d8261310e565b602082019050919050565b5f6020820190508181035f83015261316f81613136565b9050919050565b7f52657761726420626c6f636b206e6f7420656e61626c656400000000000000005f82015250565b5f6131aa601883612aee565b91506131b582613176565b602082019050919050565b5f6020820190508181035f8301526131d78161319e565b9050919050565b7f5374616b696e6720616d6f756e7420746f6f206c6974746c65000000000000005f82015250565b5f613212601983612aee565b915061321d826131de565b602082019050919050565b5f6020820190508181035f83015261323f81613206565b9050919050565b7f496e73756666696369656e7420726577617264206361706163697479000000005f82015250565b5f61327a601c83612aee565b915061328582613246565b602082019050919050565b5f6020820190508181035f8301526132a78161326e565b9050919050565b5f6060820190506132c15f830186612a72565b6132ce6020830185612a72565b6132db604083018461270d565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61331a82612704565b915061332583612704565b925082613335576133346132e3565b5b828204905092915050565b7f43616e6e6f74207365742062656c6f77207265736572766564207265776172645f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f61339a602183612aee565b91506133a582613340565b604082019050919050565b5f6020820190508181035f8301526133c78161338e565b9050919050565b5f6020820190506133e15f830184612a72565b92915050565b5f815190506133f581612840565b92915050565b5f602082840312156134105761340f61264d565b5b5f61341d848285016133e7565b91505092915050565b5f6040820190506134395f830185612a72565b6134466020830184612793565b939250505056fea26469706673582212205fd66e7375c1bb146a704b265cfebf3186e605caac08069ab2ece658cde9bb6964736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d49
-----Decoded View---------------
Arg [0] : _stakingToken (address): 0xCF078DA6e85389de507ceeDE0E3d217e457B9d49
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000cf078da6e85389de507ceede0e3d217e457b9d49
Deployed Bytecode Sourcemap
44642:16173:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60628:184;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45173:36;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50091:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34523:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50376:126;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55112:1203;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34955:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59447:535;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36092:251;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60350:78;;;:::i;:::-;;58469:351;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;59160:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56524:1086;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51176:522;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52661:326;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43273:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46394:33;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;46590:50;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45057:36;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44772:60;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53335:1549;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44960:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60156:74;;;:::i;:::-;;33539:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58935:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32851:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51973:447;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57959:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45286:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46493:25;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;50694:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;48410:1556;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35386:140;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44839:64;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60628:184;60744:4;60768:36;60792:11;60768:23;:36::i;:::-;60761:43;;60628:184;;;:::o;45173:36::-;;;;:::o;50091:93::-;50138:7;50165:11;;50158:18;;50091:93;:::o;34523:122::-;34588:7;34615:6;:12;34622:4;34615:12;;;;;;;;;;;:22;;;34608:29;;34523:122;;;:::o;50376:126::-;44809:23;33135:16;33146:4;33135:10;:16::i;:::-;50461:33:::1;44878:25;50485:8;50461:9;:33::i;:::-;50376:126:::0;;:::o;55112:1203::-;40458:21;:19;:21::i;:::-;55210:8:::1;:15;;;;55194:13;:31;55186:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;55262:23;55288:8;55297:13;55288:23;;;;;;;;:::i;:::-;;;;;;;;;;;;55262:49;;55346:10;55330:26;;:7;:12;;;;;;;;;;;;:26;;;55322:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;55398:7;:12;;;;;;;;;;;;55397:13;55389:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;55445:30;55478:12;55491:7;:24;;;55478:38;;;;;;;;:::i;:::-;;;;;;;;;;;;55445:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;55627:6;55601:11;:23;;;:32;;;;:::i;:::-;55585:7;:12;;;:49;;;;:::i;:::-;55549:15;:85;;55527:156;;;;;;;;;;;;:::i;:::-;;;;;;;;;55711:4;55696:7;:12;;;:19;;;;;;;;;;;;;;;;;;55757:7;:20;;;55726:15;:27;55742:10;55726:27;;;;;;;;;;;;;;;;:51;;;;;;;:::i;:::-;;;;;;;;55803:7;:20;;;55788:11;;:35;;;;;;;:::i;:::-;;;;;;;;55853:7;:23;;;55834:15;;:42;;;;;;;:::i;:::-;;;;;;;;55912:7;:23;;;55887:21;;:48;;;;;;;:::i;:::-;;;;;;;;55970:12;:21;;;56010:10;56062:7;:23;;;56039:7;:20;;;:46;;;;:::i;:::-;55970:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55948:195;;;;;;;;;;;;:::i;:::-;;;;;;;;;56210:13;56185:10;56161:146;;;56238:7;:20;;;56273:7;:23;;;56161:146;;;;;;;:::i;:::-;;;;;;;;55175:1140;;40502:20:::0;:18;:20::i;:::-;55112:1203;:::o;34955:138::-;35029:18;35042:4;35029:12;:18::i;:::-;33135:16;33146:4;33135:10;:16::i;:::-;35060:25:::1;35071:4;35077:7;35060:10;:25::i;:::-;;34955:138:::0;;;:::o;59447:535::-;59536:7;59580:8;:15;;;;59564:13;:31;59556:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;59632:23;59658:8;59667:13;59658:23;;;;;;;;:::i;:::-;;;;;;;;;;;;59632:49;;59696:7;:12;;;;;;;;;;;;59692:26;;;59717:1;59710:8;;;;;59692:26;59731:30;59764:12;59777:7;:24;;;59764:38;;;;;;;;:::i;:::-;;;;;;;;;;;;59731:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59833:141;59867:7;:20;;;59906:7;:11;;;59936;:23;;;59833:15;:141::i;:::-;59813:161;;;;59447:535;;;;:::o;36092:251::-;36208:12;:10;:12::i;:::-;36186:34;;:18;:34;;;36182:104;;36244:30;;;;;;;;;;;;;;36182:104;36298:37;36310:4;36316:18;36298:11;:37::i;:::-;;36092:251;;:::o;60350:78::-;44809:23;33135:16;33146:4;33135:10;:16::i;:::-;60410:10:::1;:8;:10::i;:::-;60350:78:::0;:::o;58469:351::-;58548:19;58569:11;58582:12;58624;:19;;;;58615:6;:28;58607:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;58678:30;58711:12;58724:6;58711:20;;;;;;;;:::i;:::-;;;;;;;;;;;;58678:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58750:11;:23;;;58775:11;:15;;;58792:11;:19;;;58742:70;;;;;;;58469:351;;;;;:::o;59160:108::-;59214:7;59241:12;:19;;;;59234:26;;59160:108;:::o;56524:1086::-;40458:21;:19;:21::i;:::-;56631:8:::1;:15;;;;56615:13;:31;56607:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;56683:23;56709:8;56718:13;56709:23;;;;;;;;:::i;:::-;;;;;;;;;;;;56683:49;;56767:10;56751:26;;:7;:12;;;;;;;;;;;;:26;;;56743:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;56819:7;:12;;;;;;;;;;;;56818:13;56810:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;56866:30;56899:12;56912:7;:24;;;56899:38;;;;;;;;:::i;:::-;;;;;;;;;;;;56866:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;57030:6;57004:11;:23;;;:32;;;;:::i;:::-;56988:7;:12;;;:49;;;;:::i;:::-;56970:15;:67;56948:193;;;;;;;;;;;;:::i;:::-;;;;;;;;;57169:4;57154:7;:12;;;:19;;;;;;;;;;;;;;;;;;57215:7;:20;;;57184:15;:27;57200:10;57184:27;;;;;;;;;;;;;;;;:51;;;;;;;:::i;:::-;;;;;;;;57261:7;:20;;;57246:11;;:35;;;;;;;:::i;:::-;;;;;;;;57311:7;:23;;;57292:15;;:42;;;;;;;:::i;:::-;;;;;;;;57369:12;:21;;;57391:10;57403:7;:20;;;57369:55;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57347:120;;;;;;;;;;;;:::i;:::-;;;;;;;;;57543:13;57518:10;57485:117;;;57571:7;:20;;;57485:117;;;;;;:::i;:::-;;;;;;;;56596:1014;;40502:20:::0;:18;:20::i;:::-;56524:1086;:::o;51176:522::-;44878:25;33135:16;33146:4;33135:10;:16::i;:::-;51327:1:::1;51312:12;:16;51304:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;51386:1;51379:4;:8;51371:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;51444:5;51437:4;:12;51429:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;51503:12;51535:67;;;;;;;;51561:12;51535:67;;;;51580:4;51535:67;;;;51595:5;51535:67;;;;::::0;51503:110:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51668:1;51646:12;:19;;;;:23;;;;:::i;:::-;51629:61;51671:12;51685:4;51629:61;;;;;;;:::i;:::-;;;;;;;;51176:522:::0;;;:::o;52661:326::-;44878:25;33135:16;33146:4;33135:10;:16::i;:::-;52812:12:::1;:19;;;;52798:11;:33;52790:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;52902:8;52866:12;52879:11;52866:25;;;;;;;;:::i;:::-;;;;;;;;;;;;:33;;;:44;;;;;;;;;;;;;;;;;;52957:11;52926:53;52970:8;52926:53;;;;;;:::i;:::-;;;;;;;;52661:326:::0;;;:::o;43273:86::-;43320:4;43344:7;;;;;;;;;;;43337:14;;43273:86;:::o;46394:33::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;46590:50::-;;;;;;;;;;;;;;;;;:::o;45057:36::-;;;:::o;44772:60::-;44809:23;44772:60;:::o;53335:1549::-;40458:21;:19;:21::i;:::-;42878:19:::1;:17;:19::i;:::-;53478:1:::2;53468:7;:11;53460:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;53546:12;:19;;;;53532:11;:33;53524:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;53608:12;53621:11;53608:25;;;;;;;;:::i;:::-;;;;;;;;;;;;:33;;;;;;;;;;;;53600:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;53683:31;53717:12;53730:11;53717:25;;;;;;;;:::i;:::-;;;;;;;;;;;;53683:59;;53755:23;53781:116;53811:7;53833:11;:15;;;53863:11;:23;;;53781:15;:116::i;:::-;53755:142;;53988:1;53970:15;:19;53962:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;54091:21;;54072:15;54054;;:33;;;;:::i;:::-;:58;;54032:136;;;;;;;;;;;;:::i;:::-;;;;;;;;;54203:12;:25;;;54229:10;54249:4;54256:7;54203:61;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54181:126;;;;;;;;;;;;:::i;:::-;;;;;;;;;54339:15;54320;;:34;;;;;;;:::i;:::-;;;;;;;;54380:7;54365:11;;:22;;;;;;;:::i;:::-;;;;;;;;54400:8;54428:307;;;;;;;;54461:10;54428:307;;;;;;54504:7;54428:307;;;;54536:15;54428:307;;;;54576:5;54428:307;;;;;;54618:11;54428:307;;;;54665:15;54428:307;;;;54704:11;:15;;;54428:307;;::::0;54400:346:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54790:7;54759:15;:27;54775:10;54759:27;;;;;;;;;;;;;;;;:38;;;;;;;:::i;:::-;;;;;;;;54852:1;54834:8;:15;;;;:19;;;;:::i;:::-;54822:10;54815:61;;;54855:7;54864:11;54815:61;;;;;;;:::i;:::-;;;;;;;;53449:1435;;40502:20:::0;:18;:20::i;:::-;53335:1549;;:::o;44960:26::-;;;;:::o;60156:74::-;44809:23;33135:16;33146:4;33135:10;:16::i;:::-;60214:8:::1;:6;:8::i;:::-;60156:74:::0;:::o;33539:138::-;33616:4;33640:6;:12;33647:4;33640:12;;;;;;;;;;;:20;;:29;33661:7;33640:29;;;;;;;;;;;;;;;;;;;;;;;;;33633:36;;33539:138;;;;:::o;58935:100::-;58985:7;59012:8;:15;;;;59005:22;;58935:100;:::o;32851:49::-;32896:4;32851:49;;;:::o;51973:447::-;44878:25;33135:16;33146:4;33135:10;:16::i;:::-;52125:12:::1;:19;;;;52111:11;:33;52103:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;52197:1;52187:7;:11;52179:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;52258:5;52248:7;:15;52240:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;52349:7;52317:12;52330:11;52317:25;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;:39;;;;52391:11;52372:40;52404:7;52372:40;;;;;;:::i;:::-;;;;;;;;51973:447:::0;;;:::o;57959:224::-;58085:7;58140:11;58130:5;58123:4;58113:7;:14;;;;:::i;:::-;:22;;;;:::i;:::-;58112:40;;;;:::i;:::-;58105:47;;57959:224;;;;;:::o;45286:30::-;;;;:::o;46493:25::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;50694:128::-;44809:23;33135:16;33146:4;33135:10;:16::i;:::-;50780:34:::1;44878:25;50805:8;50780:10;:34::i;:::-;50694:128:::0;;:::o;48410:1556::-;44878:25;33135:16;33146:4;33135:10;:16::i;:::-;48549:15:::1;;48536:9;:28;;48514:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;48638:22;48663:12;:22;;;48694:4;48663:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48638:62;;48711:31;48762:11;;48745:14;:28;;;;:::i;:::-;48711:62;;48802:21;;48790:9;:33;48786:1071;;;48910:25;48950:21;;48938:9;:33;;;;:::i;:::-;48910:61;;49012:12;:25;;;49060:10;49101:4;49129:17;49012:153;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48986:230;;;;;;;;;;;;:::i;:::-;;;;;;;;;48825:403;48786:1071;;;49250:21;;49238:9;:33;49234:623;;;49288:18;49333:9;49309:21;;:33;;;;:::i;:::-;49288:54;;49383:12;:21;;;49405:10;49417;49383:45;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49357:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;49273:218;49234:623;;;49557:18;49621:21;;49578:23;:64;;;;:::i;:::-;49557:85;;49674:1;49661:10;:14;49657:189;;;49726:12;:21;;;49748:10;49760;49726:45;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49696:134;;;;;;;;;;;;:::i;:::-;;;;;;;;;49657:189;49497:360;49234:623;48786:1071;49893:9;49869:21;:33;;;;49936:10;49918:40;;;49948:9;49918:40;;;;;;:::i;:::-;;;;;;;;48503:1463;;48410:1556:::0;;:::o;35386:140::-;35461:18;35474:4;35461:12;:18::i;:::-;33135:16;33146:4;33135:10;:16::i;:::-;35492:26:::1;35504:4;35510:7;35492:11;:26::i;:::-;;35386:140:::0;;;:::o;44839:64::-;44878:25;44839:64;:::o;33243:204::-;33328:4;33367:32;33352:47;;;:11;:47;;;;:87;;;;33403:36;33427:11;33403:23;:36::i;:::-;33352:87;33345:94;;33243:204;;;:::o;33892:105::-;33959:30;33970:4;33976:12;:10;:12::i;:::-;33959:10;:30::i;:::-;33892:105;:::o;40538:315::-;39836:1;40667:7;;:18;40663:88;;40709:30;;;;;;;;;;;;;;40663:88;39836:1;40828:7;:17;;;;40538:315::o;40861:212::-;39793:1;41044:7;:21;;;;40861:212::o;36969:324::-;37046:4;37068:22;37076:4;37082:7;37068;:22::i;:::-;37063:223;;37139:4;37107:6;:12;37114:4;37107:12;;;;;;;;;;;:20;;:29;37128:7;37107:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;37190:12;:10;:12::i;:::-;37163:40;;37181:7;37163:40;;37175:4;37163:40;;;;;;;;;;37225:4;37218:11;;;;37063:223;37269:5;37262:12;;36969:324;;;;;:::o;29476:98::-;29529:7;29556:10;29549:17;;29476:98;:::o;37537:325::-;37615:4;37636:22;37644:4;37650:7;37636;:22::i;:::-;37632:223;;;37707:5;37675:6;:12;37682:4;37675:12;;;;;;;;;;;:20;;:29;37696:7;37675:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;37759:12;:10;:12::i;:::-;37732:40;;37750:7;37732:40;;37744:4;37732:40;;;;;;;;;;37794:4;37787:11;;;;37632:223;37838:5;37831:12;;37537:325;;;;;:::o;44174:120::-;43137:16;:14;:16::i;:::-;44243:5:::1;44233:7;;:15;;;;;;;;;;;;;;;;;;44264:22;44273:12;:10;:12::i;:::-;44264:22;;;;;;:::i;:::-;;;;;;;;44174:120::o:0;43432:132::-;43498:8;:6;:8::i;:::-;43494:63;;;43530:15;;;;;;;;;;;;;;43494:63;43432:132::o;43915:118::-;42878:19;:17;:19::i;:::-;43985:4:::1;43975:7;;:14;;;;;;;;;;;;;;;;;;44005:20;44012:12;:10;:12::i;:::-;44005:20;;;;;;:::i;:::-;;;;;;;;43915:118::o:0;30579:148::-;30655:4;30694:25;30679:40;;;:11;:40;;;;30672:47;;30579:148;;;:::o;34133:201::-;34222:22;34230:4;34236:7;34222;:22::i;:::-;34217:110;;34301:7;34310:4;34268:47;;;;;;;;;;;;:::i;:::-;;;;;;;;34217:110;34133:201;;:::o;43641:130::-;43705:8;:6;:8::i;:::-;43700:64;;43737:15;;;;;;;;;;;;;;43700:64;43641:130::o;88:117:1:-;197:1;194;187:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:77::-;1990:7;2019:5;2008:16;;1953:77;;;:::o;2036:122::-;2109:24;2127:5;2109:24;:::i;:::-;2102:5;2099:35;2089:63;;2148:1;2145;2138:12;2089:63;2036:122;:::o;2164:139::-;2210:5;2248:6;2235:20;2226:29;;2264:33;2291:5;2264:33;:::i;:::-;2164:139;;;;:::o;2309:329::-;2368:6;2417:2;2405:9;2396:7;2392:23;2388:32;2385:119;;;2423:79;;:::i;:::-;2385:119;2543:1;2568:53;2613:7;2604:6;2593:9;2589:22;2568:53;:::i;:::-;2558:63;;2514:117;2309:329;;;;:::o;2644:118::-;2731:24;2749:5;2731:24;:::i;:::-;2726:3;2719:37;2644:118;;:::o;2768:222::-;2861:4;2899:2;2888:9;2884:18;2876:26;;2912:71;2980:1;2969:9;2965:17;2956:6;2912:71;:::i;:::-;2768:222;;;;:::o;2996:126::-;3033:7;3073:42;3066:5;3062:54;3051:65;;2996:126;;;:::o;3128:96::-;3165:7;3194:24;3212:5;3194:24;:::i;:::-;3183:35;;3128:96;;;:::o;3230:122::-;3303:24;3321:5;3303:24;:::i;:::-;3296:5;3293:35;3283:63;;3342:1;3339;3332:12;3283:63;3230:122;:::o;3358:139::-;3404:5;3442:6;3429:20;3420:29;;3458:33;3485:5;3458:33;:::i;:::-;3358:139;;;;:::o;3503:329::-;3562:6;3611:2;3599:9;3590:7;3586:23;3582:32;3579:119;;;3617:79;;:::i;:::-;3579:119;3737:1;3762:53;3807:7;3798:6;3787:9;3783:22;3762:53;:::i;:::-;3752:63;;3708:117;3503:329;;;;:::o;3838:122::-;3911:24;3929:5;3911:24;:::i;:::-;3904:5;3901:35;3891:63;;3950:1;3947;3940:12;3891:63;3838:122;:::o;3966:139::-;4012:5;4050:6;4037:20;4028:29;;4066:33;4093:5;4066:33;:::i;:::-;3966:139;;;;:::o;4111:329::-;4170:6;4219:2;4207:9;4198:7;4194:23;4190:32;4187:119;;;4225:79;;:::i;:::-;4187:119;4345:1;4370:53;4415:7;4406:6;4395:9;4391:22;4370:53;:::i;:::-;4360:63;;4316:117;4111:329;;;;:::o;4446:474::-;4514:6;4522;4571:2;4559:9;4550:7;4546:23;4542:32;4539:119;;;4577:79;;:::i;:::-;4539:119;4697:1;4722:53;4767:7;4758:6;4747:9;4743:22;4722:53;:::i;:::-;4712:63;;4668:117;4824:2;4850:53;4895:7;4886:6;4875:9;4871:22;4850:53;:::i;:::-;4840:63;;4795:118;4446:474;;;;;:::o;4926:430::-;5069:4;5107:2;5096:9;5092:18;5084:26;;5120:71;5188:1;5177:9;5173:17;5164:6;5120:71;:::i;:::-;5201:72;5269:2;5258:9;5254:18;5245:6;5201:72;:::i;:::-;5283:66;5345:2;5334:9;5330:18;5321:6;5283:66;:::i;:::-;4926:430;;;;;;:::o;5362:474::-;5430:6;5438;5487:2;5475:9;5466:7;5462:23;5458:32;5455:119;;;5493:79;;:::i;:::-;5455:119;5613:1;5638:53;5683:7;5674:6;5663:9;5659:22;5638:53;:::i;:::-;5628:63;;5584:117;5740:2;5766:53;5811:7;5802:6;5791:9;5787:22;5766:53;:::i;:::-;5756:63;;5711:118;5362:474;;;;;:::o;5842:116::-;5912:21;5927:5;5912:21;:::i;:::-;5905:5;5902:32;5892:60;;5948:1;5945;5938:12;5892:60;5842:116;:::o;5964:133::-;6007:5;6045:6;6032:20;6023:29;;6061:30;6085:5;6061:30;:::i;:::-;5964:133;;;;:::o;6103:468::-;6168:6;6176;6225:2;6213:9;6204:7;6200:23;6196:32;6193:119;;;6231:79;;:::i;:::-;6193:119;6351:1;6376:53;6421:7;6412:6;6401:9;6397:22;6376:53;:::i;:::-;6366:63;;6322:117;6478:2;6504:50;6546:7;6537:6;6526:9;6522:22;6504:50;:::i;:::-;6494:60;;6449:115;6103:468;;;;;:::o;6577:60::-;6605:3;6626:5;6619:12;;6577:60;;;:::o;6643:142::-;6693:9;6726:53;6744:34;6753:24;6771:5;6753:24;:::i;:::-;6744:34;:::i;:::-;6726:53;:::i;:::-;6713:66;;6643:142;;;:::o;6791:126::-;6841:9;6874:37;6905:5;6874:37;:::i;:::-;6861:50;;6791:126;;;:::o;6923:139::-;6986:9;7019:37;7050:5;7019:37;:::i;:::-;7006:50;;6923:139;;;:::o;7068:157::-;7168:50;7212:5;7168:50;:::i;:::-;7163:3;7156:63;7068:157;;:::o;7231:248::-;7337:4;7375:2;7364:9;7360:18;7352:26;;7388:84;7469:1;7458:9;7454:17;7445:6;7388:84;:::i;:::-;7231:248;;;;:::o;7485:619::-;7562:6;7570;7578;7627:2;7615:9;7606:7;7602:23;7598:32;7595:119;;;7633:79;;:::i;:::-;7595:119;7753:1;7778:53;7823:7;7814:6;7803:9;7799:22;7778:53;:::i;:::-;7768:63;;7724:117;7880:2;7906:53;7951:7;7942:6;7931:9;7927:22;7906:53;:::i;:::-;7896:63;;7851:118;8008:2;8034:53;8079:7;8070:6;8059:9;8055:22;8034:53;:::i;:::-;8024:63;;7979:118;7485:619;;;;;:::o;8110:118::-;8197:24;8215:5;8197:24;:::i;:::-;8192:3;8185:37;8110:118;;:::o;8234:874::-;8489:4;8527:3;8516:9;8512:19;8504:27;;8541:71;8609:1;8598:9;8594:17;8585:6;8541:71;:::i;:::-;8622:72;8690:2;8679:9;8675:18;8666:6;8622:72;:::i;:::-;8704;8772:2;8761:9;8757:18;8748:6;8704:72;:::i;:::-;8786:66;8848:2;8837:9;8833:18;8824:6;8786:66;:::i;:::-;8862:73;8930:3;8919:9;8915:19;8906:6;8862:73;:::i;:::-;8945;9013:3;9002:9;8998:19;8989:6;8945:73;:::i;:::-;9028;9096:3;9085:9;9081:19;9072:6;9028:73;:::i;:::-;8234:874;;;;;;;;;;:::o;9114:169::-;9198:11;9232:6;9227:3;9220:19;9272:4;9267:3;9263:14;9248:29;;9114:169;;;;:::o;9289:171::-;9429:23;9425:1;9417:6;9413:14;9406:47;9289:171;:::o;9466:366::-;9608:3;9629:67;9693:2;9688:3;9629:67;:::i;:::-;9622:74;;9705:93;9794:3;9705:93;:::i;:::-;9823:2;9818:3;9814:12;9807:19;;9466:366;;;:::o;9838:419::-;10004:4;10042:2;10031:9;10027:18;10019:26;;10091:9;10085:4;10081:20;10077:1;10066:9;10062:17;10055:47;10119:131;10245:4;10119:131;:::i;:::-;10111:139;;9838:419;;;:::o;10263:180::-;10311:77;10308:1;10301:88;10408:4;10405:1;10398:15;10432:4;10429:1;10422:15;10449:167;10589:19;10585:1;10577:6;10573:14;10566:43;10449:167;:::o;10622:366::-;10764:3;10785:67;10849:2;10844:3;10785:67;:::i;:::-;10778:74;;10861:93;10950:3;10861:93;:::i;:::-;10979:2;10974:3;10970:12;10963:19;;10622:366;;;:::o;10994:419::-;11160:4;11198:2;11187:9;11183:18;11175:26;;11247:9;11241:4;11237:20;11233:1;11222:9;11218:17;11211:47;11275:131;11401:4;11275:131;:::i;:::-;11267:139;;10994:419;;;:::o;11419:167::-;11559:19;11555:1;11547:6;11543:14;11536:43;11419:167;:::o;11592:366::-;11734:3;11755:67;11819:2;11814:3;11755:67;:::i;:::-;11748:74;;11831:93;11920:3;11831:93;:::i;:::-;11949:2;11944:3;11940:12;11933:19;;11592:366;;;:::o;11964:419::-;12130:4;12168:2;12157:9;12153:18;12145:26;;12217:9;12211:4;12207:20;12203:1;12192:9;12188:17;12181:47;12245:131;12371:4;12245:131;:::i;:::-;12237:139;;11964:419;;;:::o;12389:180::-;12437:77;12434:1;12427:88;12534:4;12531:1;12524:15;12558:4;12555:1;12548:15;12575:410;12615:7;12638:20;12656:1;12638:20;:::i;:::-;12633:25;;12672:20;12690:1;12672:20;:::i;:::-;12667:25;;12727:1;12724;12720:9;12749:30;12767:11;12749:30;:::i;:::-;12738:41;;12928:1;12919:7;12915:15;12912:1;12909:22;12889:1;12882:9;12862:83;12839:139;;12958:18;;:::i;:::-;12839:139;12623:362;12575:410;;;;:::o;12991:191::-;13031:3;13050:20;13068:1;13050:20;:::i;:::-;13045:25;;13084:20;13102:1;13084:20;:::i;:::-;13079:25;;13127:1;13124;13120:9;13113:16;;13148:3;13145:1;13142:10;13139:36;;;13155:18;;:::i;:::-;13139:36;12991:191;;;;:::o;13188:171::-;13328:23;13324:1;13316:6;13312:14;13305:47;13188:171;:::o;13365:366::-;13507:3;13528:67;13592:2;13587:3;13528:67;:::i;:::-;13521:74;;13604:93;13693:3;13604:93;:::i;:::-;13722:2;13717:3;13713:12;13706:19;;13365:366;;;:::o;13737:419::-;13903:4;13941:2;13930:9;13926:18;13918:26;;13990:9;13984:4;13980:20;13976:1;13965:9;13961:17;13954:47;14018:131;14144:4;14018:131;:::i;:::-;14010:139;;13737:419;;;:::o;14162:194::-;14202:4;14222:20;14240:1;14222:20;:::i;:::-;14217:25;;14256:20;14274:1;14256:20;:::i;:::-;14251:25;;14300:1;14297;14293:9;14285:17;;14324:1;14318:4;14315:11;14312:37;;;14329:18;;:::i;:::-;14312:37;14162:194;;;;:::o;14362:332::-;14483:4;14521:2;14510:9;14506:18;14498:26;;14534:71;14602:1;14591:9;14587:17;14578:6;14534:71;:::i;:::-;14615:72;14683:2;14672:9;14668:18;14659:6;14615:72;:::i;:::-;14362:332;;;;;:::o;14700:137::-;14754:5;14785:6;14779:13;14770:22;;14801:30;14825:5;14801:30;:::i;:::-;14700:137;;;;:::o;14843:345::-;14910:6;14959:2;14947:9;14938:7;14934:23;14930:32;14927:119;;;14965:79;;:::i;:::-;14927:119;15085:1;15110:61;15163:7;15154:6;15143:9;15139:22;15110:61;:::i;:::-;15100:71;;15056:125;14843:345;;;;:::o;15194:165::-;15334:17;15330:1;15322:6;15318:14;15311:41;15194:165;:::o;15365:366::-;15507:3;15528:67;15592:2;15587:3;15528:67;:::i;:::-;15521:74;;15604:93;15693:3;15604:93;:::i;:::-;15722:2;15717:3;15713:12;15706:19;;15365:366;;;:::o;15737:419::-;15903:4;15941:2;15930:9;15926:18;15918:26;;15990:9;15984:4;15980:20;15976:1;15965:9;15961:17;15954:47;16018:131;16144:4;16018:131;:::i;:::-;16010:139;;15737:419;;;:::o;16162:332::-;16283:4;16321:2;16310:9;16306:18;16298:26;;16334:71;16402:1;16391:9;16387:17;16378:6;16334:71;:::i;:::-;16415:72;16483:2;16472:9;16468:18;16459:6;16415:72;:::i;:::-;16162:332;;;;;:::o;16500:169::-;16640:21;16636:1;16628:6;16624:14;16617:45;16500:169;:::o;16675:366::-;16817:3;16838:67;16902:2;16897:3;16838:67;:::i;:::-;16831:74;;16914:93;17003:3;16914:93;:::i;:::-;17032:2;17027:3;17023:12;17016:19;;16675:366;;;:::o;17047:419::-;17213:4;17251:2;17240:9;17236:18;17228:26;;17300:9;17294:4;17290:20;17286:1;17275:9;17271:17;17264:47;17328:131;17454:4;17328:131;:::i;:::-;17320:139;;17047:419;;;:::o;17472:300::-;17612:34;17608:1;17600:6;17596:14;17589:58;17681:34;17676:2;17668:6;17664:15;17657:59;17750:14;17745:2;17737:6;17733:15;17726:39;17472:300;:::o;17778:366::-;17920:3;17941:67;18005:2;18000:3;17941:67;:::i;:::-;17934:74;;18017:93;18106:3;18017:93;:::i;:::-;18135:2;18130:3;18126:12;18119:19;;17778:366;;;:::o;18150:419::-;18316:4;18354:2;18343:9;18339:18;18331:26;;18403:9;18397:4;18393:20;18389:1;18378:9;18374:17;18367:47;18431:131;18557:4;18431:131;:::i;:::-;18423:139;;18150:419;;;:::o;18575:177::-;18715:29;18711:1;18703:6;18699:14;18692:53;18575:177;:::o;18758:366::-;18900:3;18921:67;18985:2;18980:3;18921:67;:::i;:::-;18914:74;;18997:93;19086:3;18997:93;:::i;:::-;19115:2;19110:3;19106:12;19099:19;;18758:366;;;:::o;19130:419::-;19296:4;19334:2;19323:9;19319:18;19311:26;;19383:9;19377:4;19373:20;19369:1;19358:9;19354:17;19347:47;19411:131;19537:4;19411:131;:::i;:::-;19403:139;;19130:419;;;:::o;19555:176::-;19695:28;19691:1;19683:6;19679:14;19672:52;19555:176;:::o;19737:366::-;19879:3;19900:67;19964:2;19959:3;19900:67;:::i;:::-;19893:74;;19976:93;20065:3;19976:93;:::i;:::-;20094:2;20089:3;20085:12;20078:19;;19737:366;;;:::o;20109:419::-;20275:4;20313:2;20302:9;20298:18;20290:26;;20362:9;20356:4;20352:20;20348:1;20337:9;20333:17;20326:47;20390:131;20516:4;20390:131;:::i;:::-;20382:139;;20109:419;;;:::o;20534:225::-;20674:34;20670:1;20662:6;20658:14;20651:58;20743:8;20738:2;20730:6;20726:15;20719:33;20534:225;:::o;20765:366::-;20907:3;20928:67;20992:2;20987:3;20928:67;:::i;:::-;20921:74;;21004:93;21093:3;21004:93;:::i;:::-;21122:2;21117:3;21113:12;21106:19;;20765:366;;;:::o;21137:419::-;21303:4;21341:2;21330:9;21326:18;21318:26;;21390:9;21384:4;21380:20;21376:1;21365:9;21361:17;21354:47;21418:131;21544:4;21418:131;:::i;:::-;21410:139;;21137:419;;;:::o;21562:179::-;21702:31;21698:1;21690:6;21686:14;21679:55;21562:179;:::o;21747:366::-;21889:3;21910:67;21974:2;21969:3;21910:67;:::i;:::-;21903:74;;21986:93;22075:3;21986:93;:::i;:::-;22104:2;22099:3;22095:12;22088:19;;21747:366;;;:::o;22119:419::-;22285:4;22323:2;22312:9;22308:18;22300:26;;22372:9;22366:4;22362:20;22358:1;22347:9;22343:17;22336:47;22400:131;22526:4;22400:131;:::i;:::-;22392:139;;22119:419;;;:::o;22544:174::-;22684:26;22680:1;22672:6;22668:14;22661:50;22544:174;:::o;22724:366::-;22866:3;22887:67;22951:2;22946:3;22887:67;:::i;:::-;22880:74;;22963:93;23052:3;22963:93;:::i;:::-;23081:2;23076:3;23072:12;23065:19;;22724:366;;;:::o;23096:419::-;23262:4;23300:2;23289:9;23285:18;23277:26;;23349:9;23343:4;23339:20;23335:1;23324:9;23320:17;23313:47;23377:131;23503:4;23377:131;:::i;:::-;23369:139;;23096:419;;;:::o;23521:175::-;23661:27;23657:1;23649:6;23645:14;23638:51;23521:175;:::o;23702:366::-;23844:3;23865:67;23929:2;23924:3;23865:67;:::i;:::-;23858:74;;23941:93;24030:3;23941:93;:::i;:::-;24059:2;24054:3;24050:12;24043:19;;23702:366;;;:::o;24074:419::-;24240:4;24278:2;24267:9;24263:18;24255:26;;24327:9;24321:4;24317:20;24313:1;24302:9;24298:17;24291:47;24355:131;24481:4;24355:131;:::i;:::-;24347:139;;24074:419;;;:::o;24499:178::-;24639:30;24635:1;24627:6;24623:14;24616:54;24499:178;:::o;24683:366::-;24825:3;24846:67;24910:2;24905:3;24846:67;:::i;:::-;24839:74;;24922:93;25011:3;24922:93;:::i;:::-;25040:2;25035:3;25031:12;25024:19;;24683:366;;;:::o;25055:419::-;25221:4;25259:2;25248:9;25244:18;25236:26;;25308:9;25302:4;25298:20;25294:1;25283:9;25279:17;25272:47;25336:131;25462:4;25336:131;:::i;:::-;25328:139;;25055:419;;;:::o;25480:442::-;25629:4;25667:2;25656:9;25652:18;25644:26;;25680:71;25748:1;25737:9;25733:17;25724:6;25680:71;:::i;:::-;25761:72;25829:2;25818:9;25814:18;25805:6;25761:72;:::i;:::-;25843;25911:2;25900:9;25896:18;25887:6;25843:72;:::i;:::-;25480:442;;;;;;:::o;25928:180::-;25976:77;25973:1;25966:88;26073:4;26070:1;26063:15;26097:4;26094:1;26087:15;26114:185;26154:1;26171:20;26189:1;26171:20;:::i;:::-;26166:25;;26205:20;26223:1;26205:20;:::i;:::-;26200:25;;26244:1;26234:35;;26249:18;;:::i;:::-;26234:35;26291:1;26288;26284:9;26279:14;;26114:185;;;;:::o;26305:220::-;26445:34;26441:1;26433:6;26429:14;26422:58;26514:3;26509:2;26501:6;26497:15;26490:28;26305:220;:::o;26531:366::-;26673:3;26694:67;26758:2;26753:3;26694:67;:::i;:::-;26687:74;;26770:93;26859:3;26770:93;:::i;:::-;26888:2;26883:3;26879:12;26872:19;;26531:366;;;:::o;26903:419::-;27069:4;27107:2;27096:9;27092:18;27084:26;;27156:9;27150:4;27146:20;27142:1;27131:9;27127:17;27120:47;27184:131;27310:4;27184:131;:::i;:::-;27176:139;;26903:419;;;:::o;27328:222::-;27421:4;27459:2;27448:9;27444:18;27436:26;;27472:71;27540:1;27529:9;27525:17;27516:6;27472:71;:::i;:::-;27328:222;;;;:::o;27556:143::-;27613:5;27644:6;27638:13;27629:22;;27660:33;27687:5;27660:33;:::i;:::-;27556:143;;;;:::o;27705:351::-;27775:6;27824:2;27812:9;27803:7;27799:23;27795:32;27792:119;;;27830:79;;:::i;:::-;27792:119;27950:1;27975:64;28031:7;28022:6;28011:9;28007:22;27975:64;:::i;:::-;27965:74;;27921:128;27705:351;;;;:::o;28062:332::-;28183:4;28221:2;28210:9;28206:18;28198:26;;28234:71;28302:1;28291:9;28287:17;28278:6;28234:71;:::i;:::-;28315:72;28383:2;28372:9;28368:18;28359:6;28315:72;:::i;:::-;28062:332;;;;;:::o
Swarm Source
ipfs://5fd66e7375c1bb146a704b265cfebf3186e605caac08069ab2ece658cde9bb69
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.002853 | 13,984,145.3154 | $39,897.13 |
Loading...
Loading
Loading...
Loading
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.