Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
PROSPERA_v2
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "./PROSPERA.sol";
contract PROSPERA_v2 is PROSPERA {
/// @notice Initializes the upgraded contract
/// @dev This function is called during the upgrade process
function initializeV2() external reinitializer(2) {
_unpause(); // Unpause the contract after upgrade to allow transfers
}
/// @notice Records the final state of the ICO and performs necessary actions
/// @dev This function can only be called by the ICO contract
/// @param totalSold The total number of tokens sold in the ICO
function recordIcoCompletion(uint256 totalSold) external override {
if (msg.sender != icoContract) revert UnauthorizedCaller();
if (totalSold != getIcoSupply()) revert InvalidIcoCompletion();
if (icoCompleted) revert IcoAlreadyCompleted();
// Mark ICO as completed
icoCompleted = true;
// Update the total circulating supply
circulatingSupply += totalSold;
emit IcoCompleted(totalSold);
}
/// @notice Returns the ICO supply
/// @dev This function is added to access the ICO_SUPPLY constant
/// @return The total number of tokens allocated for the ICO
function getIcoSupply() public pure returns (uint256) {
return 153750000; // 15.375% of 1 billion (1e9 * 15375 / 100000)
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable
struct OwnableStorage {
address _owner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
assembly {
$.slot := OwnableStorageLocation
}
}
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
function __Ownable_init(address initialOwner) internal onlyInitializing {
__Ownable_init_unchained(initialOwner);
}
function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
OwnableStorage storage $ = _getOwnableStorage();
return $._owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
OwnableStorage storage $ = _getOwnableStorage();
address oldOwner = $._owner;
$._owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.20;
import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {Initializable} from "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address private immutable __self = address(this);
/**
* @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
* and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
* while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
* If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
* be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
* during an upgrade.
*/
string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
/**
* @dev The call is from an unauthorized context.
*/
error UUPSUnauthorizedCallContext();
/**
* @dev The storage `slot` is unsupported as a UUID.
*/
error UUPSUnsupportedProxiableUUID(bytes32 slot);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
_checkProxy();
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
_checkNotDelegated();
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual notDelegated returns (bytes32) {
return ERC1967Utils.IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data);
}
/**
* @dev Reverts if the execution is not performed via delegatecall or the execution
* context is not of a proxy with an ERC1967-compliant implementation pointing to self.
* See {_onlyProxy}.
*/
function _checkProxy() internal view virtual {
if (
address(this) == __self || // Must be called through delegatecall
ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
) {
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Reverts if the execution is performed via delegatecall.
* See {notDelegated}.
*/
function _checkNotDelegated() internal view virtual {
if (address(this) != __self) {
// Must not be called through delegatecall
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
*
* As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
* is expected to be the implementation slot in ERC1967.
*
* Emits an {IERC1967-Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
revert UUPSUnsupportedProxiableUUID(slot);
}
ERC1967Utils.upgradeToAndCall(newImplementation, data);
} catch {
// The implementation is not UUPS
revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol";
import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*/
abstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {
/// @custom:storage-location erc7201:openzeppelin.storage.ERC20
struct ERC20Storage {
mapping(address account => uint256) _balances;
mapping(address account => mapping(address spender => uint256)) _allowances;
uint256 _totalSupply;
string _name;
string _symbol;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;
function _getERC20Storage() private pure returns (ERC20Storage storage $) {
assembly {
$.slot := ERC20StorageLocation
}
}
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
ERC20Storage storage $ = _getERC20Storage();
$._name = name_;
$._symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
ERC20Storage storage $ = _getERC20Storage();
return $._name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
ERC20Storage storage $ = _getERC20Storage();
return $._symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
ERC20Storage storage $ = _getERC20Storage();
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
$._totalSupply += value;
} else {
uint256 fromBalance = $._balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
$._balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
$._totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
$._balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
* ```
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
ERC20Storage storage $ = _getERC20Storage();
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
$._allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)
pragma solidity ^0.8.20;
import {ERC20Upgradeable} from "../ERC20Upgradeable.sol";
import {ContextUpgradeable} from "../../../utils/ContextUpgradeable.sol";
import {Initializable} from "../../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/
abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {
function __ERC20Burnable_init() internal onlyInitializing {
}
function __ERC20Burnable_init_unchained() internal onlyInitializing {
}
/**
* @dev Destroys a `value` amount of tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 value) public virtual {
_burn(_msgSender(), value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, deducting from
* the caller's allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `value`.
*/
function burnFrom(address account, uint256 value) public virtual {
_spendAllowance(account, _msgSender(), value);
_burn(account, value);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Pausable.sol)
pragma solidity ^0.8.20;
import {ERC20Upgradeable} from "../ERC20Upgradeable.sol";
import {PausableUpgradeable} from "../../../utils/PausableUpgradeable.sol";
import {Initializable} from "../../../proxy/utils/Initializable.sol";
/**
* @dev ERC20 token with pausable token transfers, minting and burning.
*
* Useful for scenarios such as preventing trades until the end of an evaluation
* period, or having an emergency switch for freezing all token transfers in the
* event of a large bug.
*
* IMPORTANT: This contract does not include public pause and unpause functions. In
* addition to inheriting this contract, you must define both functions, invoking the
* {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate
* access control, e.g. using {AccessControl} or {Ownable}. Not doing so will
* make the contract pause mechanism of the contract unreachable, and thus unusable.
*/
abstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {
function __ERC20Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
function __ERC20Pausable_init_unchained() internal onlyInitializing {
}
/**
* @dev See {ERC20-_update}.
*
* Requirements:
*
* - the contract must not be paused.
*/
function _update(address from, address to, uint256 value) internal virtual override whenNotPaused {
super._update(from, to, value);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Pausable
struct PausableStorage {
bool _paused;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Pausable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;
function _getPausableStorage() private pure returns (PausableStorage storage $) {
assembly {
$.slot := PausableStorageLocation
}
}
/**
* @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.
*/
function __Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
function __Pausable_init_unchained() internal onlyInitializing {
PausableStorage storage $ = _getPausableStorage();
$._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) {
PausableStorage storage $ = _getPausableStorage();
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 {
PausableStorage storage $ = _getPausableStorage();
$._paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
PausableStorage storage $ = _getPausableStorage();
$._paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
/// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
struct ReentrancyGuardStorage {
uint256 _status;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
assembly {
$.slot := ReentrancyGuardStorageLocation
}
}
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
$._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 {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// 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 {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// 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) {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
return $._status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822Proxiable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.20;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {UpgradeableBeacon} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
pragma solidity ^0.8.20;
import {IBeacon} from "../beacon/IBeacon.sol";
import {Address} from "../../utils/Address.sol";
import {StorageSlot} from "../../utils/StorageSlot.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*/
library ERC1967Utils {
// We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
// This will be fixed in Solidity 0.8.21. At that point we should remove these events.
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev The `implementation` of the proxy is invalid.
*/
error ERC1967InvalidImplementation(address implementation);
/**
* @dev The `admin` of the proxy is invalid.
*/
error ERC1967InvalidAdmin(address admin);
/**
* @dev The `beacon` of the proxy is invalid.
*/
error ERC1967InvalidBeacon(address beacon);
/**
* @dev An upgrade function sees `msg.value > 0` that may be lost.
*/
error ERC1967NonPayable();
/**
* @dev Returns the current implementation address.
*/
function getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(newImplementation);
}
StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Performs implementation upgrade with additional setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
if (data.length > 0) {
Address.functionDelegateCall(newImplementation, data);
} else {
_checkNonPayable();
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
if (newAdmin == address(0)) {
revert ERC1967InvalidAdmin(address(0));
}
StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {IERC1967-AdminChanged} event.
*/
function changeAdmin(address newAdmin) internal {
emit AdminChanged(getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
if (newBeacon.code.length == 0) {
revert ERC1967InvalidBeacon(newBeacon);
}
StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
address beaconImplementation = IBeacon(newBeacon).implementation();
if (beaconImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(beaconImplementation);
}
}
/**
* @dev Change the beacon and trigger a setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-BeaconUpgraded} event.
*
* CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
* it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
* efficiency.
*/
function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
} else {
_checkNonPayable();
}
}
/**
* @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
* if an upgrade doesn't perform an initialization call.
*/
function _checkNonPayable() private {
if (msg.value > 0) {
revert ERC1967NonPayable();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @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 AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @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
* {FailedInnerCall} 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 AddressInsufficientBalance(address(this));
}
(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 {FailedInnerCall}) 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 {FailedInnerCall} 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 {FailedInnerCall}.
*/
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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {ERC20BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import {ERC20PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {StorageSlot} from "@openzeppelin/contracts/utils/StorageSlot.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
/// @title Vesting Contract Interface
/// @notice Interface for the vesting contract used by PROSPERA
/// @custom:security-contact [email protected]
interface IVestingContract {
/// @notice Checks if a transfer involves vested tokens
/// @param account Address to check for vested tokens
/// @return isVested True if the transfer involves vested tokens, false otherwise
function isVestedTokenTransfer(address account) external view returns (bool isVested);
/// @notice Adds an account to the vesting schedule
/// @param account The address to be added to the vesting schedule
/// @param amount The amount of tokens to be vested
/// @param vestingType The type of vesting schedule (0 for marketing team, 1 for PROSPERA team)
/// @return success True if the address was successfully added to the vesting schedule
function addToVesting(address account, uint256 amount, uint8 vestingType) external returns (bool success);
/// @notice Releases vested tokens for a given account
/// @param account The address for which to release tokens
/// @return amount The amount of tokens released
function releaseVestedTokens(address account) external returns (uint256 amount);
}
/// @title PROSPERA Token Contract
/// @author Prospera Development Team
/// @notice This contract implements the PROSPERA token with various functionalities
/// @custom:security-contact [email protected]
contract PROSPERA is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, ERC20PausableUpgradeable, OwnableUpgradeable, UUPSUpgradeable, ReentrancyGuardUpgradeable {
using Address for address payable;
/// @notice Total supply of tokens
uint256 private constant TOTAL_SUPPLY = 1e9; // 1 billion tokens
/// @notice Tokens allocated for staking rewards
uint256 private constant STAKING_SUPPLY = TOTAL_SUPPLY * 10000 / 100000; // 10%
/// @notice Tokens allocated for liquidity
uint256 private constant LIQUIDITY_SUPPLY = TOTAL_SUPPLY * 20000 / 100000; // 20%
/// @notice Tokens allocated for farming
uint256 private constant FARMING_SUPPLY = TOTAL_SUPPLY * 10000 / 100000; // 10%
/// @notice Tokens allocated for listing on exchanges
uint256 private constant LISTING_SUPPLY = TOTAL_SUPPLY * 12000 / 100000; // 12%
/// @notice Tokens allocated for reserves
uint256 private constant RESERVE_SUPPLY = TOTAL_SUPPLY * 5025 / 100000; // 5.025%
/// @notice Tokens allocated for marketing
uint256 private constant MARKETING_SUPPLY = TOTAL_SUPPLY * 5000 / 100000; // 5%
/// @notice Tokens allocated for team wallet
uint256 private constant TEAM_SUPPLY = TOTAL_SUPPLY * 11000 / 100000; // 11%
/// @notice Tokens allocated for dev wallet
uint256 private constant DEV_SUPPLY = TOTAL_SUPPLY * 11600 / 100000; // 11.6%
/// @notice Tokens allocated for the ICO
uint256 private constant ICO_SUPPLY = TOTAL_SUPPLY * 15375 / 100000; // 15.375%
/// @notice Indicates whether the ICO has been completed
/// @dev This is set to true when the recordIcoCompletion function is called
/// @return Returns true if the ICO is completed, false otherwise
bool public icoCompleted;
/// @notice The total number of tokens in circulation
/// @dev This value is updated when tokens are minted, burned, or when the ICO is completed
/// @return Returns the current number of tokens in circulation
uint256 public circulatingSupply;
/// @notice Wallet address for tax collection
address public taxWallet;
/// @notice Wallet address for ICO funds
address public icoWallet;
/// @notice Wallet address for staking funds
address public stakingWallet;
/// @notice Address of the staking contract
address public stakingContract;
/// @notice Address of the vesting contract
address public vestingContract;
/// @notice Address of the ICO contract
address public icoContract;
/// @notice Address of the math contract
address public mathContract;
/// @notice Mapping of blacklisted addresses
mapping(address user => bool isBlacklisted) private _blacklist;
/// @notice Mapping of whitelisted addresses
mapping(address user => bool isWhitelisted) private _whitelist;
// Storage slots
/// @dev Storage slot for staking wallet
bytes32 private constant STAKING_WALLET_SLOT = bytes32(uint256(keccak256("stakingWalletSlot")) - 1);
/// @dev Storage slot for liquidity wallet
bytes32 private constant LIQUIDITY_WALLET_SLOT = bytes32(uint256(keccak256("liquidityWalletSlot")) - 1);
/// @dev Storage slot for farming wallet
bytes32 private constant FARMING_WALLET_SLOT = bytes32(uint256(keccak256("farmingWalletSlot")) - 1);
/// @dev Storage slot for listing wallet
bytes32 private constant LISTING_WALLET_SLOT = bytes32(uint256(keccak256("listingWalletSlot")) - 1);
/// @dev Storage slot for reserve wallet
bytes32 private constant RESERVE_WALLET_SLOT = bytes32(uint256(keccak256("reserveWalletSlot")) - 1);
/// @dev Storage slot for marketing wallet
bytes32 private constant MARKETING_WALLET_SLOT = bytes32(uint256(keccak256("marketingWalletSlot")) - 1);
/// @dev Storage slot for team wallet
bytes32 private constant TEAM_WALLET_SLOT = bytes32(uint256(keccak256("teamWalletSlot")) - 1);
/// @dev Storage slot for dev wallet
bytes32 private constant DEV_WALLET_SLOT = bytes32(uint256(keccak256("devWalletSlot")) - 1);
// Events
/// @notice Emitted when an address is added to or removed from the blacklist
/// @param user The address that was updated
/// @param value The new blacklist status (true if blacklisted, false if removed from blacklist)
event BlacklistUpdated(address indexed user, bool value);
/// @notice Emitted when the contract is initialized
/// @param deployer The address of the contract deployer
event Initialized(address indexed deployer);
/// @notice Emitted when a contract state is updated
/// @param variable The name of the variable that was updated
/// @param account The address associated with the update (if applicable)
/// @param value The new value of the variable
event StateUpdated(string variable, address indexed account, bool value);
/// @notice Emitted when a wallet address is set
/// @param walletType The type of wallet being set
/// @param walletAddress The address of the wallet
event WalletAddressSet(string indexed walletType, address indexed walletAddress);
/// @notice Emitted when an address is added to the whitelist
/// @param user The address that was added to the whitelist
event AddedToWhitelist(address indexed user);
/// @notice Emitted when an address is removed from the whitelist
/// @param user The address that was removed from the whitelist
event RemovedFromWhitelist(address indexed user);
/// @notice Emitted when ETH is withdrawn from the contract
/// @param recipient The address receiving the withdrawn ETH
/// @param amount The amount of ETH withdrawn
event EthWithdrawn(address indexed recipient, uint256 amount);
/// @notice Emitted when the ICO is successfully completed
/// @param totalSold The total number of tokens sold during the ICO
event IcoCompleted(uint256 indexed totalSold);
/// @notice Emitted when tokens are transferred
/// @param from The address sending the tokens
/// @param to The address receiving the tokens
/// @param value The amount of tokens transferred
event TokensTransferred(address indexed from, address indexed to, uint256 value);
/// @notice Override the decimals function to return 0
function decimals() public view virtual override returns (uint8) {
return 0;
}
// Errors
/// @notice Error thrown when an operation involves a blacklisted address
/// @param account The address that is blacklisted
error BlacklistedAddress(address account);
/// @notice Error thrown when attempting to blacklist the zero address
error BlacklistZeroAddress();
/// @notice Error thrown when attempting to remove the zero address from the blacklist
error RemoveFromBlacklistZeroAddress();
/// @notice Error thrown when an operation requires more balance than available
error InsufficientBalance();
/// @notice Error thrown when attempting to withdraw ETH from a contract with no ETH balance
error NoEthToWithdraw();
/// @notice Error thrown when the fallback function receives data with a non-empty ETH transfer
error FallbackFunctionOnlyAcceptsETH();
/// @notice Error thrown when an invalid address is provided for an operation
error InvalidAddress();
/// @notice Error thrown when attempting to transfer vested tokens
error VestedTokensCannotBeTransferred();
/// @notice Error thrown when an invalid contract address is provided
/// @param contractType The type of contract (e.g., "staking", "ICO", "vesting")
error InvalidContractAddress(string contractType);
/// @notice Error thrown when a function is called by an unauthorized address
error UnauthorizedCaller();
/// @notice Error thrown when the ICO completion is recorded incorrectly
error InvalidIcoCompletion();
/// @notice Error thrown when an operation is attempted after the ICO has completed
error IcoAlreadyCompleted();
/// @notice Error thrown when the contract balance changes unexpectedly after a transfer
error UnexpectedBalanceChange();
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/// @notice Initializes the contract with the specified parameters
/// @dev This function sets up the initial state of the contract, including setting up wallets and minting the total supply
/// @param params The initialization parameters
struct WalletParams {
address deployerWallet;
address taxWallet;
address stakingWallet;
address icoWallet;
address liquidityWallet;
address farmingWallet;
address listingWallet;
address reserveWallet;
address marketingWallet;
address teamWallet;
address devWallet;
}
struct ContractParams {
address vestingContract;
address icoContract;
}
/// @notice Initializes the contract with the specified parameters
/// @dev This function sets up the initial state of the contract, including setting up wallets and minting the total supply
/// @param walletParams The wallet initialization parameters
/// @param contractParams The contract initialization parameters
function initialize(WalletParams calldata walletParams, ContractParams calldata contractParams) external initializer {
// Base contract initializations
__ERC20_init("PROSPERA", "PROS");
__ERC20Burnable_init();
__ERC20Pausable_init();
__Ownable_init(walletParams.deployerWallet);
__UUPSUpgradeable_init();
__ReentrancyGuard_init();
// Initialize wallets and contracts
_initializeWallets(walletParams);
_initializeContracts(contractParams);
// Mint and distribute initial token supply (no need to multiply by 10**18)
_mint(walletParams.stakingWallet, STAKING_SUPPLY);
_mint(StorageSlot.getAddressSlot(LIQUIDITY_WALLET_SLOT).value, LIQUIDITY_SUPPLY);
_mint(StorageSlot.getAddressSlot(FARMING_WALLET_SLOT).value, FARMING_SUPPLY);
_mint(StorageSlot.getAddressSlot(LISTING_WALLET_SLOT).value, LISTING_SUPPLY);
_mint(StorageSlot.getAddressSlot(RESERVE_WALLET_SLOT).value, RESERVE_SUPPLY);
_mint(StorageSlot.getAddressSlot(MARKETING_WALLET_SLOT).value, MARKETING_SUPPLY);
_mint(StorageSlot.getAddressSlot(TEAM_WALLET_SLOT).value, TEAM_SUPPLY);
_mint(StorageSlot.getAddressSlot(DEV_WALLET_SLOT).value, DEV_SUPPLY);
_mint(contractParams.icoContract, ICO_SUPPLY);
emit Initialized(walletParams.deployerWallet);
}
/// @notice Initializes wallet addresses
/// @param params The wallet initialization parameters
function _initializeWallets(WalletParams memory params) private {
taxWallet = params.taxWallet;
stakingWallet = params.stakingWallet;
icoWallet = params.icoWallet;
StorageSlot.getAddressSlot(STAKING_WALLET_SLOT).value = params.stakingWallet;
StorageSlot.getAddressSlot(LIQUIDITY_WALLET_SLOT).value = params.liquidityWallet;
StorageSlot.getAddressSlot(FARMING_WALLET_SLOT).value = params.farmingWallet;
StorageSlot.getAddressSlot(LISTING_WALLET_SLOT).value = params.listingWallet;
StorageSlot.getAddressSlot(RESERVE_WALLET_SLOT).value = params.reserveWallet;
StorageSlot.getAddressSlot(MARKETING_WALLET_SLOT).value = params.marketingWallet;
StorageSlot.getAddressSlot(TEAM_WALLET_SLOT).value = params.teamWallet;
StorageSlot.getAddressSlot(DEV_WALLET_SLOT).value = params.devWallet;
emit WalletAddressSet("Tax Wallet", taxWallet);
emit WalletAddressSet("Staking Wallet", stakingWallet);
emit WalletAddressSet("ICO Wallet", icoWallet);
emit WalletAddressSet("Liquidity Wallet", params.liquidityWallet);
emit WalletAddressSet("Farming Wallet", params.farmingWallet);
emit WalletAddressSet("Listing Wallet", params.listingWallet);
emit WalletAddressSet("Reserve Wallet", params.reserveWallet);
emit WalletAddressSet("Marketing Wallet", params.marketingWallet);
emit WalletAddressSet("Team Wallet", params.teamWallet);
emit WalletAddressSet("Dev Wallet", params.devWallet);
}
/// @notice Initializes contract addresses
/// @param params The contract initialization parameters
function _initializeContracts(ContractParams memory params) private {
vestingContract = params.vestingContract;
icoContract = params.icoContract;
emit WalletAddressSet("Vesting Contract", vestingContract);
emit WalletAddressSet("Vesting Contract", vestingContract);
emit WalletAddressSet("ICO Contract", icoContract);
}
/// @notice Authorizes an upgrade to a new implementation
/// @dev This function is left empty but is required by the UUPSUpgradeable contract
/// @param newImplementation Address of the new implementation
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
/// @notice Sets the address of the staking contract
/// @dev This function can only be called by the owner of the contract
/// @param _stakingContract The address of the new staking contract
function setStakingContract(address _stakingContract) external onlyOwner {
if (_stakingContract == address(0)) revert InvalidContractAddress("staking");
stakingContract = _stakingContract;
emit WalletAddressSet("Staking Contract", stakingContract);
}
/// @notice Sets the address of the math contract
/// @dev This function can only be called by the owner of the contract
/// @param _mathContract The address of the new math contract
function setMathContract(address _mathContract) external onlyOwner {
if (_mathContract == address(0)) revert InvalidContractAddress("math");
mathContract = _mathContract;
emit WalletAddressSet("Math Contract", mathContract);
}
/// @notice Pauses all token transfers
function pause() external onlyOwner {
_pause();
emit StateUpdated("paused", address(0), true);
}
/// @notice Unpauses all token transfers
function unpause() external onlyOwner {
_unpause();
emit StateUpdated("paused", address(0), false);
}
/// @notice Adds an address to the blacklist
/// @param account The address to be blacklisted
function addToBlacklist(address account) external onlyOwner {
if (account == address(0)) revert BlacklistZeroAddress();
_blacklist[account] = true;
emit BlacklistUpdated(account, true);
emit StateUpdated("blacklist", account, true);
}
/// @notice Removes an address from the blacklist
/// @param account The address to be removed from the blacklist
function removeFromBlacklist(address account) external onlyOwner {
if (account == address(0)) revert RemoveFromBlacklistZeroAddress();
_blacklist[account] = false;
emit BlacklistUpdated(account, false);
emit StateUpdated("blacklist", account, false);
}
/// @notice Adds an address to the whitelist
/// @param account The address to be added
function addToWhitelist(address account) external onlyOwner {
if (account == address(0)) revert InvalidAddress();
_whitelist[account] = true;
emit AddedToWhitelist(account);
emit StateUpdated("whitelist", account, true);
}
/// @notice Removes an address from the whitelist
/// @param account The address to be removed
function removeFromWhitelist(address account) external onlyOwner {
if (account == address(0)) revert InvalidAddress();
_whitelist[account] = false;
emit RemovedFromWhitelist(account);
emit StateUpdated("whitelist", account, false);
}
/// @notice Records the final state of the ICO and performs necessary actions
/// @dev This function can only be called by the ICO contract
/// @param totalSold The total number of tokens sold in the ICO
function recordIcoCompletion(uint256 totalSold) external virtual {
if (msg.sender != icoContract) revert UnauthorizedCaller();
if (totalSold != ICO_SUPPLY) revert InvalidIcoCompletion();
if (icoCompleted) revert IcoAlreadyCompleted();
// Mark ICO as completed
icoCompleted = true;
// Update the total circulating supply
circulatingSupply += totalSold;
// Enable token transfers for all holders
_unpause();
emit IcoCompleted(totalSold);
}
/// @notice Checks if an address is whitelisted
/// @param account The address to check
/// @return isWhitelisted True if the address is whitelisted, false otherwise
function _isWhitelisted(address account) internal view returns (bool isWhitelisted) {
return _whitelist[account];
}
/// @notice Withdraws all ETH from the contract to the owner's address
/// @dev This function can only be called by the contract owner and is protected against reentrancy attacks
/// @custom:security nonReentrant
/// @custom:requires The contract must have a non-zero ETH balance
/// @custom:emits EthWithdrawn event upon successful withdrawal
/// @custom:throws NoEthToWithdraw if the contract's ETH balance is zero
/// @custom:throws Any error that _safeTransferETH might throw (e.g., InsufficientBalance, UnexpectedBalanceChange)
function withdrawETH() external onlyOwner nonReentrant {
address payable ownerPayable = payable(owner());
uint256 balance = address(this).balance;
if (balance == 0) revert NoEthToWithdraw();
_safeTransferETH(ownerPayable, balance);
emit EthWithdrawn(ownerPayable, balance);
}
/// @notice Fallback function to receive ETH
receive() external payable {}
/// @notice Fallback function to handle unexpected calls
fallback() external payable {
if (msg.data.length != 0) revert FallbackFunctionOnlyAcceptsETH();
}
/// @notice Safely transfers ETH to an address
/// @dev Uses OpenZeppelin's Address.sendValue for safer ETH transfers
/// @param recipientAddress The address to receive the ETH
/// @param amount The amount of ETH to transfer
function _safeTransferETH(address recipientAddress, uint256 amount) private nonReentrant {
if (address(this).balance < amount) revert InsufficientBalance();
uint256 previousBalance = address(this).balance;
// Use OpenZeppelin's sendValue function
payable(recipientAddress).sendValue(amount);
uint256 expectedMinBalance = previousBalance - amount;
uint256 tolerance = 1 wei; // Small tolerance to account for potential gas refunds
if (address(this).balance < expectedMinBalance || address(this).balance > expectedMinBalance + tolerance) {
revert UnexpectedBalanceChange();
}
}
/// @notice Updates the internal state during transfers
/// @param from The address sending the tokens
/// @param to The address receiving the tokens
/// @param value The amount of tokens being transferred
function _update(address from, address to, uint256 value) internal override(ERC20Upgradeable, ERC20PausableUpgradeable) {
if (_blacklist[from]) revert BlacklistedAddress(from);
if (_blacklist[to]) revert BlacklistedAddress(to);
if (vestingContract != address(0)) {
bool isVested = IVestingContract(vestingContract).isVestedTokenTransfer(from);
if (isVested) revert VestedTokensCannotBeTransferred();
}
super._update(from, to, value);
emit TokensTransferred(from, to, value);
}
/// @notice Adds an account to the vesting schedule
/// @dev This function can only be called by the contract owner
/// @param account The address to be added to the vesting schedule
/// @param amount The amount of tokens to be vested
/// @param vestingType The type of vesting schedule (0 for marketing team, 1 for PROSPERA team)
/// @return success True if the account was successfully added to the vesting schedule
function addAccountToVesting(address account, uint256 amount, uint8 vestingType) external onlyOwner returns (bool success) {
if (vestingContract == address(0)) revert InvalidContractAddress("vesting");
success = IVestingContract(vestingContract).addToVesting(account, amount, vestingType);
require(success, "Failed to add account to vesting");
return success;
}
/// @notice Releases vested tokens for a given account
/// @param account The address for which to release tokens
/// @return amount The amount of tokens released
function releaseVestedTokensForAccount(address account) external returns (uint256 amount) {
if (vestingContract == address(0)) revert InvalidContractAddress("vesting");
amount = IVestingContract(vestingContract).releaseVestedTokens(account);
_transfer(address(this), account, amount);
return amount;
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"BlacklistZeroAddress","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"BlacklistedAddress","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FallbackFunctionOnlyAcceptsETH","type":"error"},{"inputs":[],"name":"IcoAlreadyCompleted","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"string","name":"contractType","type":"string"}],"name":"InvalidContractAddress","type":"error"},{"inputs":[],"name":"InvalidIcoCompletion","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NoEthToWithdraw","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"RemoveFromBlacklistZeroAddress","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"inputs":[],"name":"UnauthorizedCaller","type":"error"},{"inputs":[],"name":"UnexpectedBalanceChange","type":"error"},{"inputs":[],"name":"VestedTokensCannotBeTransferred","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"AddedToWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"BlacklistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EthWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"totalSold","type":"uint256"}],"name":"IcoCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"deployer","type":"address"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"RemovedFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"variable","type":"string"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"StateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TokensTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"walletType","type":"string"},{"indexed":true,"internalType":"address","name":"walletAddress","type":"address"}],"name":"WalletAddressSet","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"vestingType","type":"uint8"}],"name":"addAccountToVesting","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getIcoSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"icoCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"icoContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"icoWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"deployerWallet","type":"address"},{"internalType":"address","name":"taxWallet","type":"address"},{"internalType":"address","name":"stakingWallet","type":"address"},{"internalType":"address","name":"icoWallet","type":"address"},{"internalType":"address","name":"liquidityWallet","type":"address"},{"internalType":"address","name":"farmingWallet","type":"address"},{"internalType":"address","name":"listingWallet","type":"address"},{"internalType":"address","name":"reserveWallet","type":"address"},{"internalType":"address","name":"marketingWallet","type":"address"},{"internalType":"address","name":"teamWallet","type":"address"},{"internalType":"address","name":"devWallet","type":"address"}],"internalType":"struct PROSPERA.WalletParams","name":"walletParams","type":"tuple"},{"components":[{"internalType":"address","name":"vestingContract","type":"address"},{"internalType":"address","name":"icoContract","type":"address"}],"internalType":"struct PROSPERA.ContractParams","name":"contractParams","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializeV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mathContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"totalSold","type":"uint256"}],"name":"recordIcoCompletion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releaseVestedTokensForAccount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mathContract","type":"address"}],"name":"setMathContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingContract","type":"address"}],"name":"setStakingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"vestingContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60a08060405234620000d157306080527ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a009081549060ff8260401c16620000c257506001600160401b036002600160401b0319828216016200007c575b6040516138419081620000d78239608051818181610ddc0152610ec20152f35b6001600160401b031990911681179091556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a13880806200005c565b63f92ee8a960e01b8152600490fd5b600080fdfe608080604052600436101561002a575b50361561002857604051633025323f60e11b8152600490fd5b005b60003560e01c90816306ee6ad814612d3e5750806306fdde0314612c9b578063095ea7b314612be8578063153d55e414612af557806318160ddd14612aca578063204e8b1714612aa75780632228791414612a7e57806323b872dd14612a465780632dc0562d14612a1d578063313ce56714612a015780633f0ca101146129d85780633f4ba83a1461293c5780633f87c8701461115057806342966c681461113357806344337ea1146110715780634f1ef28614610e4657806352d1902d14610dc9578063537df3b614610d0a57806357b5310614610c555780635c975abb14610c255780635cd8a76b14610b2d5780635e6f604514610b0457806370a0823114610abd578063715018a614610a5357806379cc679014610a235780638456cb59146109845780638ab1d681146108dd5780638da5cb5b146108a75780639358928b1461088957806395d89b41146107af5780639dd373b914610707578063a48d9e70146106e8578063a9059cbb146106b7578063ad3cb1cc14610675578063c66e40951461064c578063d7fa9f6b1461056a578063dd62ed3e14610521578063e086e5ec146103bc578063e43252d714610300578063ee99205c146102d7578063f2fde38b146102ae5763f82c544e14610205573861000f565b346102a95760203660031901126102a95761021e612dab565b610226612e31565b6001600160a01b0316801561027d57600880546001600160a01b031916821790557fcdd4f932fda9f1b4dafa35df19764b5e690e4dd5c6567503b9d0ef0c505ab02460008051602061372c833981519152600080a3005b6064604051630e21b92360e41b81526020600482015260046024820152630dac2e8d60e31b6044820152fd5b600080fd5b346102a95760203660031901126102a9576100286102ca612dab565b6102d2612e31565b612e6a565b346102a95760003660031901126102a9576005546040516001600160a01b039091168152602090f35b346102a95760203660031901126102a957610319612dab565b610321612e31565b6001600160a01b031680156103aa5780600052600a6020526040600020600160ff1982541617905560008051602061368c8339815191526080604051837fa850ae9193f515cbae8d35e8925bd2be26627fc91bce650b8652ed254e9cab03600080a26040815260096040820152681dda1a5d195b1a5cdd60ba1b606082015260016020820152a2005b60405163e6c4247b60e01b8152600490fd5b346102a95760003660031901126102a9576103d5612e31565b6103dd613461565b60008051602061370c833981519152546001600160a01b031647801561050f57610405613461565b8047106104fd57478147106104e557600080808085875af1610425613370565b50156104d3578181039081116104bd578047109081156104a8575b506104965760207f8455ae6be5d92f1df1c3c1484388e247a36c7e60d72055ae216dbc258f257d4b91604051908152a260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055005b60405163ad70993360e01b8152600490fd5b905047600182018092116104bd571183610440565b634e487b7160e01b600052601160045260246000fd5b604051630a12f52160e11b8152600490fd5b60405163cd78605960e01b8152306004820152602490fd5b604051631e9acf1760e31b8152600490fd5b6040516361cc654560e01b8152600490fd5b346102a95760403660031901126102a95761053a612dab565b61054b610545612dc1565b91612f18565b9060018060a01b03166000526020526020604060002054604051908152f35b346102a9576020806003193601126102a957610584612dab565b6006546001600160a01b039081169190821561061c5760009260248592604051958693849263ce699a4160e01b8452871660048401525af1918215610610576000926105df575b50816105d79130612f51565b604051908152f35b9091508281813d8311610609575b6105f78183612df3565b810103126102a95751906105d76105cb565b503d6105ed565b6040513d6000823e3d90fd5b604051630e21b92360e41b815260206004820152600760248201526676657374696e6760c81b6044820152606490fd5b346102a95760003660031901126102a9576007546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a9576106b360405161069581612dd7565b60058152640352e302e360dc1b602082015260405191829182612d62565b0390f35b346102a95760403660031901126102a9576106dd6106d3612dab565b6024359033612f51565b602060405160018152f35b346102a95760003660031901126102a957602060405163092a09f08152f35b346102a95760203660031901126102a957610720612dab565b610728612e31565b6001600160a01b0316801561077f57600580546001600160a01b031916821790557f28df65e3e787da752d78d981344a2b93809a4a4e1466ab7303e44c1e894c984e60008051602061372c833981519152600080a3005b604051630e21b92360e41b81526020600482015260076024820152667374616b696e6760c81b6044820152606490fd5b346102a95760003660031901126102a95760405160006000805160206136ec83398151915280546107df81612ede565b8085529160019180831690811561085f5750600114610815575b6106b38561080981870382612df3565b60405191829182612d62565b600090815292506000805160206137cc8339815191525b828410610847575050508101602001610809826106b36107f9565b8054602085870181019190915290930192810161082c565b8695506106b39693506020925061080994915060ff191682840152151560051b82010192936107f9565b346102a95760003660031901126102a9576020600154604051908152f35b346102a95760003660031901126102a95760008051602061370c833981519152546040516001600160a01b039091168152602090f35b346102a95760203660031901126102a9576108f6612dab565b6108fe612e31565b6001600160a01b031680156103aa5780600052600a602052604060002060ff19815416905560008051602061368c8339815191526080604051837fcdd2e9b91a56913d370075169cefa1602ba36be5301664f752192bb1709df757600080a26040815260096040820152681dda1a5d195b1a5cdd60ba1b606082015260006020820152a2005b346102a95760003660031901126102a95761099d612e31565b6109a5613436565b6000805160206137ac833981519152600160ff198254161790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1600060008051602061368c83398151915260806040516040815260066040820152651c185d5cd95960d21b606082015260016020820152a2005b346102a95760403660031901126102a957610028610a3f612dab565b60243590610a4e823383613103565b6131d9565b346102a95760003660031901126102a957610a6c612e31565b60008051602061370c83398151915280546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346102a95760203660031901126102a9576001600160a01b03610ade612dab565b166000526000805160206136cc8339815191526020526020604060002054604051908152f35b346102a95760003660031901126102a9576006546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a9576000805160206137ec833981519152805460ff8160401c168015610c10575b610bfe576000805160206137ac8339815191529081549160ff831615610bec5760029260ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a168ffffffffffffffffff19161790557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160028152a1005b604051638dfc202b60e01b8152600490fd5b60405163f92ee8a960e01b8152600490fd5b50600267ffffffffffffffff82161015610b5d565b346102a95760003660031901126102a957602060ff6000805160206137ac83398151915254166040519015158152f35b346102a95760203660031901126102a957600754600435906001600160a01b03163303610cf85763092a09f08103610ce65760005460ff8116610cd45760019060ff1916176000556001548181018091116104bd576001557f7e5a75ee59a3d939dac1be7f2c09b14ca3829223668d6beee2cd8c61ada33341600080a2005b604051637863d09b60e11b8152600490fd5b60405163baa35d1360e01b8152600490fd5b604051635c427cd960e01b8152600490fd5b346102a95760203660031901126102a957610d23612dab565b610d2b612e31565b6001600160a01b03168015610db757806000526009602052604060002060ff198154169055807f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac602060405160008152a260008051602061368c8339815191526080604051604081526009604082015268189b1858dadb1a5cdd60ba1b606082015260006020820152a2005b6040516302d9462160e11b8152600490fd5b346102a95760003660031901126102a9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003610e345760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b60405163703e46dd60e11b8152600490fd5b60403660031901126102a957610e5a612dab565b602490813567ffffffffffffffff81116102a957366023820112156102a957806004013591610e8883612e15565b610e956040519182612df3565b83815260209384820193368783830101116102a95781600092888893018737830101526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116308114908115611043575b50610e3457610efb612e31565b6040516352d1902d60e01b8152908316948082600481895afa918291600093611013575b5050610f3d57604051634c9c8ce360e01b8152600481018690528690fd5b8490867f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91828103610ffe5750843b15610fe8575080546001600160a01b03191682179055604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2815115610fce575060006100289381925190845af4610fc8613370565b916133a0565b9250505034610fd957005b63b398979f60e01b8152600490fd5b604051634c9c8ce360e01b815260048101849052fd5b60405190632a87526960e21b82526004820152fd5b9080929350813d831161103c575b61102b8183612df3565b810103126102a95751908780610f1f565b503d611021565b9050817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416141587610eee565b346102a95760203660031901126102a95761108a612dab565b611092612e31565b6001600160a01b03168015611121578060005260096020526040600020600160ff19825416179055807f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac602060405160018152a260008051602061368c8339815191526080604051604081526009604082015268189b1858dadb1a5cdd60ba1b606082015260016020820152a2005b60405163ceff43a960e01b8152600490fd5b346102a95760203660031901126102a957610028600435336131d9565b346102a95736600319016101a081126102a957610160136102a9576040366101631901126102a9576000805160206137ec8339815191525467ffffffffffffffff81168015908161292c575b6001149081612922575b159081612919575b50610bfe57600167ffffffffffffffff198216176000805160206137ec8339815191525560ff8160401c16156128ec575b604051906111ec82612dd7565b600882526750524f535045524160c01b60208301526040519061120e82612dd7565b600482526350524f5360e01b6020830152611227613407565b61122f613407565b825167ffffffffffffffff81116126b8576112586000805160206136ac83398151915254612ede565b601f8111612876575b506020601f82116001146127e857819293946000926127dd575b50508160011b916000199060031b1c1916176000805160206136ac833981519152555b815167ffffffffffffffff81116126b8576112c76000805160206136ec83398151915254612ede565b601f8111612763575b50602092601f82116001146126d957928192936000926126ce575b50508160011b916000199060031b1c1916176000805160206136ec833981519152555b611316613407565b61131e613407565b611326613407565b6000805160206137ac833981519152805460ff191690556113586113486133f1565b611350613407565b6102d2613407565b611360613407565b611368613407565b611370613407565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051610160810181811067ffffffffffffffff8211176126b8576040526113ba612dab565b81526113c4612dc1565b602082018190526044356001600160a01b03811690036102a9576044356040830152606435916001600160a01b03831683036102a957606081018390526084356001600160a01b03811681036102a9576080820181905260a4356001600160a01b03811690036102a95760a43560a083015260c4356001600160a01b03811690036102a95760c43560c083015260e435926001600160a01b03841684036102a95760e08301849052610104356001600160a01b03811690036102a95761010435610100840152610124356001600160a01b03811690036102a95761012435610120840152610144356001600160a01b03811690036102a957610144356101408401819052600280546001600160a01b03199081166001600160a01b0394851690811790925560048054821660443586169081179091556003805483168a87161790557f0c672d9dba74bebc168b103cf20eed62c1c5a30334e98296bf7d8ce1a5c1ea488054831690911790557f2aba2a91d77d103a85ba138e578966efc0fc31cbe14b7d7f404c10f4d9dcb9c880548216958516959095179094557f9b44a32a4ca7acffc1c70ef670b75f2f45ec2da1c467d617fe4e715a3b1a40818054851660a43585161790557f11fcaf5cfc3792b195f40db144bdc3b799b7ce582005b5824306d60336df42e18054851660c43585161790557f7b4fc011b6134f11ff666f9344f27840e3914471199406e7c283930e9718f71e80548516968416969096179095557f14dedacc455a0c0133c4baee2cf0f7ebcb6a6b327942df5289cac6a3b2980a01805484166101043584161790557f0f78416ba663791d813952b6ec605b3f25cd669082eb6212c8a1c5dfd31a2e78805484166101243584161790557f6b560155c24616b409cdfbb28a97a5d7aed4e1200d488f46207598f8f3bb998280549093169116179055604080516915185e0815d85b1b195d60b21b9052516911195d8815d85b1b195d60b21b926d14dd185ada5b99c815d85b1b195d60921b91907f2abd966a4424e65c222adebb0152a50b1af9a5eddc76e958b14c2281b60a43c260008051602061372c833981519152600080a352604051691250d3c815d85b1b195d60b21b906044356001600160a01b03167f9e58e2eac2c8e36accd1095bb9d2fe32412ce4704bf829b0ebb8b3610e2df20160008051602061372c833981519152600080a352604051926001600160a01b03167f31384fb8734df3c866f8a032e71c2794f58f31c926da33ff07f3bc99ae7a344360008051602061372c833981519152600080a360808101516f131a5c5d5a591a5d1e4815d85b1b195d60821b909352604051926001600160a01b03167f8c4b085b8571f2b28000e0c43f80bb3401681ad53fdb85d7a9349ef9b158b43060008051602061372c833981519152600080a360a08101516d11985c9b5a5b99c815d85b1b195d60921b909352604051926001600160a01b03167f37f12d4caeee3b372ab38acc5076c4f0db20dac6f8d56935611af0711adbdded60008051602061372c833981519152600080a360c08101516d131a5cdd1a5b99c815d85b1b195d60921b909352604051926001600160a01b03167f8d17dcb2491eceb42e9f410a808d5cd175c2709a6a27dcee7cb7d2a431d0b60c60008051602061372c833981519152600080a360e08101516d14995cd95c9d994815d85b1b195d60921b909352604051926001600160a01b03167f6e87f62b2c72d4ae7c556b16722dc277e6b720dcc47c54ffe66bcd60edd2c91460008051602061372c833981519152600080a36101008101516f13585c9ad95d1a5b99c815d85b1b195d60821b909352604051926001600160a01b03167f196ba63ecbc71da617f3fb326bbb7f71d30cafa2c30da919b4ff46802cdd814d60008051602061372c833981519152600080a36101208101516a1519585b4815d85b1b195d60aa1b909352604051926001600160a01b03167f90a24532a62237f4aee10052c7364ce0c2a3e9ad6693cad0c707563441386d5a60008051602061372c833981519152600080a361014001519152604051906001600160a01b03167f8f3dfe72c2152ef1f255b3cc84b8ff937e9147d0a1e8ad522910ab84d987678260008051602061372c833981519152600080a380604081011067ffffffffffffffff6040830111176126b85760408181019052610164356001600160a01b03811681036102a957808252610184356001600160a01b03811690036102a95761018435602092909201829052600680546001600160a01b038381166001600160a01b0319928316811790935560078054919095169116179092556040516f15995cdd1a5b99c810dbdb9d1c9858dd60821b908190526b1250d3c810dbdb9d1c9858dd60a21b927f788736aa4d8b33659c066e5e6eeeae6908f3a4c9759ea891608e9e6f29ff4f2191908260008051602061372c833981519152600080a3604080519190915251916001600160a01b03169060008051602061372c833981519152600080a352610184356001600160a01b03167fca2579a3c7458570c1f17089ea81eb3be417a37ad09b2ed314f7c182206f9d4260008051602061372c833981519152600080a36044356001600160a01b03161561247757611b4b6044356134bb565b7f2aba2a91d77d103a85ba138e578966efc0fc31cbe14b7d7f404c10f4d9dcb9c8546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612660575b50611bcd613436565b60008051602061374c83398151915254630bebc200810181116104bd57630bebc2000160008051602061374c83398151915255806000526000805160206136cc8339815191526020526040600020630bebc200815401905580600060008051602061378c8339815191526020604051630bebc2008152a3600060008051602061376c8339815191526020604051630bebc2008152a37f9b44a32a4ca7acffc1c70ef670b75f2f45ec2da1c467d617fe4e715a3b1a4081546001600160a01b0316801561247757611c9c906134bb565b7f11fcaf5cfc3792b195f40db144bdc3b799b7ce582005b5824306d60336df42e1546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612608575b50611d1e613436565b60008051602061374c833981519152546307270e00810181116104bd576307270e000160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206307270e00815401905580600060008051602061378c83398151915260206040516307270e008152a3600060008051602061376c83398151915260206040516307270e008152a37f7b4fc011b6134f11ff666f9344f27840e3914471199406e7c283930e9718f71e546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b0316806125b0575b50611e35613436565b60008051602061374c833981519152546302fec110810181116104bd576302fec1100160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206302fec110815401905580600060008051602061378c83398151915260206040516302fec1108152a3600060008051602061376c83398151915260206040516302fec1108152a37f14dedacc455a0c0133c4baee2cf0f7ebcb6a6b327942df5289cac6a3b2980a01546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612558575b50611f4c613436565b60008051602061374c833981519152546302faf080810181116104bd576302faf0800160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206302faf080815401905580600060008051602061378c83398151915260206040516302faf0808152a3600060008051602061376c83398151915260206040516302faf0808152a37f0f78416ba663791d813952b6ec605b3f25cd669082eb6212c8a1c5dfd31a2e78546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612500575b50612063613436565b60008051602061374c8339815191525463068e7780810181116104bd5763068e77800160008051602061374c83398151915255806000526000805160206136cc833981519152602052604060002063068e7780815401905580600060008051602061378c833981519152602060405163068e77808152a3600060008051602061376c833981519152602060405163068e77808152a37f6b560155c24616b409cdfbb28a97a5d7aed4e1200d488f46207598f8f3bb9982546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612490575b5061217a613436565b60008051602061374c833981519152546306ea0500810181116104bd576306ea05000160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206306ea0500815401905580600060008051602061378c83398151915260206040516306ea05008152a3600060008051602061376c83398151915260206040516306ea05008152a3610184356001600160a01b0316156124775760008052600960205260008051602061364c8339815191525460ff1661245e57610184356001600160a01b031660009081526009602052604090205460ff1661243a576006546001600160a01b0316806123c0575b5061227f613436565b60008051602061374c8339815191525463092a09f0908181018091116104bd5760008051602061374c83398151915255610184356001600160a01b031660008181526000805160206136cc833981519152602090815260408083208054860190555184815260008051602061378c8339815191529190a3604051908152610184356001600160a01b03169060009060008051602061376c83398151915290602090a360ff6001600160a01b036123336133f1565b1691604051927f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6600080a260401c161561236957005b60207fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29168ff0000000000000000196000805160206137ec83398151915254166000805160206137ec8339815191525560018152a1005b602060249160405192838092631673485560e01b8252600060048301525afa9081156106105760009161240b575b506123f95781612276565b604051631aaf894760e31b8152600490fd5b61242d915060203d602011612433575b6124258183612df3565b8101906134a3565b826123ee565b503d61241b565b60405163d33f19e760e01b8152610184356001600160a01b03166004820152602490fd5b60405163d33f19e760e01b815260006004820152602490fd5b60405163ec442f0560e01b815260006004820152602490fd5b602060249160405192838092631673485560e01b8252600060048301525afa908115610610576000916124c9575b506123f95782612171565b6124e2915060203d602011612433576124258183612df3565b836124be565b6024906040519063d33f19e760e01b82526004820152fd5b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612539575b506123f9578261205a565b612552915060203d602011612433576124258183612df3565b8361252e565b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612591575b506123f95782611f43565b6125aa915060203d602011612433576124258183612df3565b83612586565b602060249160405192838092631673485560e01b8252600060048301525afa908115610610576000916125e9575b506123f95782611e2c565b612602915060203d602011612433576124258183612df3565b836125de565b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612641575b506123f95782611d15565b61265a915060203d602011612433576124258183612df3565b83612636565b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612699575b506123f95782611bc4565b6126b2915060203d602011612433576124258183612df3565b8361268e565b634e487b7160e01b600052604160045260246000fd5b0151905083806112eb565b601f198216936000805160206136ec8339815191526000526000805160206137cc8339815191529160005b86811061274b5750836001959610612732575b505050811b016000805160206136ec8339815191525561130e565b015160001960f88460031b161c19169055838080612717565b91926020600181928685015181550194019201612704565b6000805160206136ec833981519152600052601f820160051c6000805160206137cc8339815191520190602083106127c7575b601f0160051c6000805160206137cc83398151915201905b8181106127bb57506112d0565b600081556001016127ae565b6000805160206137cc8339815191529150612796565b01519050848061127b565b6000805160206136ac83398151915260005260008051602061366c8339815191529060005b601f198416811061285e5750600193949583601f19811610612845575b505050811b016000805160206136ac8339815191525561129e565b015160001960f88460031b161c1916905584808061282a565b9091602060018192858a01518155019301910161280d565b6000805160206136ac833981519152600052601f820160051c60008051602061366c83398151915201602083106128d7575b601f820160051c60008051602061366c8339815191520181106128cb5750611261565b600081556001016128a8565b5060008051602061366c8339815191526128a8565b68ffffffffffffffffff19811668010000000000000001176000805160206137ec833981519152556111df565b905015826111ae565b303b1591506111a6565b604083901c60ff1615915061119c565b346102a95760003660031901126102a957612955612e31565b6000805160206137ac833981519152805460ff811615610bec5760ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1600060008051602061368c83398151915260806040516040815260066040820152651c185d5cd95960d21b6060820152836020820152a2005b346102a95760003660031901126102a9576008546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a957602060405160008152f35b346102a95760003660031901126102a9576002546040516001600160a01b039091168152602090f35b346102a95760603660031901126102a9576106dd612a62612dab565b612a6a612dc1565b60443591612a79833383613103565b612f51565b346102a95760003660031901126102a9576003546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a957602060ff600054166040519015158152f35b346102a95760003660031901126102a957602060008051602061374c83398151915254604051908152f35b346102a95760603660031901126102a957612b0e612dab565b6044359060ff82168092036102a957612b25612e31565b6006546001600160a01b039290831690811561061c5760009360405193630feabe0160e11b8552166004840152602435602484015260448301528160648160209586945af190811561061057600091612bcb575b5015612b885760405160018152f35b6064906040519062461bcd60e51b825280600483015260248201527f4661696c656420746f20616464206163636f756e7420746f2076657374696e676044820152fd5b612be29150823d8411612433576124258183612df3565b82612b79565b346102a95760403660031901126102a957612c01612dab565b602435903315612c82576001600160a01b0316908115612c6957612c2433612f18565b82600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b346102a95760003660031901126102a95760405160006000805160206136ac8339815191528054612ccb81612ede565b8085529160019180831690811561085f5750600114612cf4576106b38561080981870382612df3565b6000908152925060008051602061366c8339815191525b828410612d26575050508101602001610809826106b36107f9565b80546020858701810191909152909301928101612d0b565b346102a95760003660031901126102a9576004546001600160a01b03168152602090f35b6020808252825181830181905290939260005b828110612d9757505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501612d75565b600435906001600160a01b03821682036102a957565b602435906001600160a01b03821682036102a957565b6040810190811067ffffffffffffffff8211176126b857604052565b90601f8019910116810190811067ffffffffffffffff8211176126b857604052565b67ffffffffffffffff81116126b857601f01601f191660200190565b60008051602061370c833981519152546001600160a01b03163303612e5257565b60405163118cdaa760e01b8152336004820152602490fd5b6001600160a01b03908116908115612ec55760008051602061370c83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b604051631e4fbdf760e01b815260006004820152602490fd5b90600182811c92168015612f0e575b6020831014612ef857565b634e487b7160e01b600052602260045260246000fd5b91607f1691612eed565b6001600160a01b031660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020526040902090565b9291906001600160a01b038085169182156130ea578116928315612477576000918383526020926009845260409160ff83832054166130d2578682526009855260ff83832054166130ba5760065416848161304d575b5050612fb1613436565b8481526000805160206136cc8339815191528085528282205498848a1061301d5750908386979899849360008051602061376c8339815191529884528752038282205587815220828154019055858560008051602061378c833981519152858451868152a351908152a3565b835163391434e360e21b81526001600160a01b03919091166004820152602481018a905260448101859052606490fd5b602491845192838092631673485560e01b82528a60048301525afa9081156130b0578291613093575b50613082573884612fa7565b8151631aaf894760e31b8152600490fd5b6130aa9150853d8711612433576124258183612df3565b38613076565b83513d84823e3d90fd5b825163d33f19e760e01b815260048101889052602490fd5b825163d33f19e760e01b815260048101879052602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b919061310e83612f18565b9260018060a01b039081831691600095838752602052604086205493600019850361313d575b50505050505050565b8585106131a8575081161561318f57811561317657906131606040949392612f18565b9085526020520391205538808080808080613134565b604051634a1406b160e11b815260048101869052602490fd5b60405163e602df0560e01b815260048101869052602490fd5b604051637dc7a0d960e11b81526001600160a01b039190911660048201526024810185905260448101869052606490fd5b91906001600160a01b038084169081156130ea576000928284526020916009835260409060ff8287205416613358578580526009845260ff8287205416613340576006541683816132d4575b505061322f613436565b8385526000805160206136cc83398151915280845281862054978389106132a4575085969783918660008051602061376c8339815191529798528552038187205560008051602061374c833981519152828154039055858560008051602061378c833981519152858451868152a351908152a3565b825163391434e360e21b81526001600160a01b039190911660048201526024810189905260448101849052606490fd5b602491835192838092631673485560e01b82528960048301525afa908115613336578691613319575b50613309573883613225565b51631aaf894760e31b8152600490fd5b6133309150843d8611612433576124258183612df3565b386132fd565b82513d88823e3d90fd5b815163d33f19e760e01b815260048101879052602490fd5b815163d33f19e760e01b815260048101869052602490fd5b3d1561339b573d9061338182612e15565b9161338f6040519384612df3565b82523d6000602084013e565b606090565b906133b557508051156104d357805190602001fd5b815115806133e8575b6133c6575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156133be565b6004356001600160a01b03811681036102a95790565b60ff6000805160206137ec8339815191525460401c161561342457565b604051631afcd79f60e31b8152600490fd5b60ff6000805160206137ac833981519152541661344f57565b60405163d93c066560e01b8152600490fd5b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0060028154146134915760029055565b604051633ee5aeb560e01b8152600490fd5b908160209103126102a9575180151581036102a95790565b906000918280526020926009845260409360ff8583205416613633576001600160a01b03928316808352600982528583205490939060ff1661361b576006541681816135ae575b505061350c613436565b60008051602061374c8339815191528054956305f5e1009182880180981161359a5760008051602061376c83398151915294959697815586156000146135775780546305f5e0ff190190555b858560008051602061378c833981519152858451868152a351908152a3565b508585526000805160206136cc8339815191528352808520828154019055613558565b634e487b7160e01b85526011600452602485fd5b602491875192838092631673485560e01b82528760048301525afa9081156136115783916135f4575b506135e3573881613502565b8451631aaf894760e31b8152600490fd5b61360b9150823d8411612433576124258183612df3565b386135d7565b86513d85823e3d90fd5b855163d33f19e760e01b815260048101859052602490fd5b845163d33f19e760e01b815260048101839052602490fdfeec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b2ae08a8e29253f69ac5d979a101956ab8f8d9d7ded63fa7a83b16fc47648eab05b0b376f56fbaee6462a33ce7d274d6494bd3d6300c1623ef695e55b7635fad852c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0352c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace049016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993009909e508f055ea78c4ff7e02dd4f38b686e5527bd8c0d5cedc9bb8c0b233d44052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace021b89874203ff7f0bba87c969ada3f32fda22ed38a6706d35199d21280c7811b1ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330046a2803e59a4de4e7a4c574b1243f25977ac4c77d5a1a4a609b5394cebb4a2aaf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a2646970667358221220ecbe9218afd4eb3ec82c55a242ebbc1c62c6a40f3b705cdd3447e061b6646efd64736f6c63430008140033
Deployed Bytecode
0x608080604052600436101561002a575b50361561002857604051633025323f60e11b8152600490fd5b005b60003560e01c90816306ee6ad814612d3e5750806306fdde0314612c9b578063095ea7b314612be8578063153d55e414612af557806318160ddd14612aca578063204e8b1714612aa75780632228791414612a7e57806323b872dd14612a465780632dc0562d14612a1d578063313ce56714612a015780633f0ca101146129d85780633f4ba83a1461293c5780633f87c8701461115057806342966c681461113357806344337ea1146110715780634f1ef28614610e4657806352d1902d14610dc9578063537df3b614610d0a57806357b5310614610c555780635c975abb14610c255780635cd8a76b14610b2d5780635e6f604514610b0457806370a0823114610abd578063715018a614610a5357806379cc679014610a235780638456cb59146109845780638ab1d681146108dd5780638da5cb5b146108a75780639358928b1461088957806395d89b41146107af5780639dd373b914610707578063a48d9e70146106e8578063a9059cbb146106b7578063ad3cb1cc14610675578063c66e40951461064c578063d7fa9f6b1461056a578063dd62ed3e14610521578063e086e5ec146103bc578063e43252d714610300578063ee99205c146102d7578063f2fde38b146102ae5763f82c544e14610205573861000f565b346102a95760203660031901126102a95761021e612dab565b610226612e31565b6001600160a01b0316801561027d57600880546001600160a01b031916821790557fcdd4f932fda9f1b4dafa35df19764b5e690e4dd5c6567503b9d0ef0c505ab02460008051602061372c833981519152600080a3005b6064604051630e21b92360e41b81526020600482015260046024820152630dac2e8d60e31b6044820152fd5b600080fd5b346102a95760203660031901126102a9576100286102ca612dab565b6102d2612e31565b612e6a565b346102a95760003660031901126102a9576005546040516001600160a01b039091168152602090f35b346102a95760203660031901126102a957610319612dab565b610321612e31565b6001600160a01b031680156103aa5780600052600a6020526040600020600160ff1982541617905560008051602061368c8339815191526080604051837fa850ae9193f515cbae8d35e8925bd2be26627fc91bce650b8652ed254e9cab03600080a26040815260096040820152681dda1a5d195b1a5cdd60ba1b606082015260016020820152a2005b60405163e6c4247b60e01b8152600490fd5b346102a95760003660031901126102a9576103d5612e31565b6103dd613461565b60008051602061370c833981519152546001600160a01b031647801561050f57610405613461565b8047106104fd57478147106104e557600080808085875af1610425613370565b50156104d3578181039081116104bd578047109081156104a8575b506104965760207f8455ae6be5d92f1df1c3c1484388e247a36c7e60d72055ae216dbc258f257d4b91604051908152a260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055005b60405163ad70993360e01b8152600490fd5b905047600182018092116104bd571183610440565b634e487b7160e01b600052601160045260246000fd5b604051630a12f52160e11b8152600490fd5b60405163cd78605960e01b8152306004820152602490fd5b604051631e9acf1760e31b8152600490fd5b6040516361cc654560e01b8152600490fd5b346102a95760403660031901126102a95761053a612dab565b61054b610545612dc1565b91612f18565b9060018060a01b03166000526020526020604060002054604051908152f35b346102a9576020806003193601126102a957610584612dab565b6006546001600160a01b039081169190821561061c5760009260248592604051958693849263ce699a4160e01b8452871660048401525af1918215610610576000926105df575b50816105d79130612f51565b604051908152f35b9091508281813d8311610609575b6105f78183612df3565b810103126102a95751906105d76105cb565b503d6105ed565b6040513d6000823e3d90fd5b604051630e21b92360e41b815260206004820152600760248201526676657374696e6760c81b6044820152606490fd5b346102a95760003660031901126102a9576007546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a9576106b360405161069581612dd7565b60058152640352e302e360dc1b602082015260405191829182612d62565b0390f35b346102a95760403660031901126102a9576106dd6106d3612dab565b6024359033612f51565b602060405160018152f35b346102a95760003660031901126102a957602060405163092a09f08152f35b346102a95760203660031901126102a957610720612dab565b610728612e31565b6001600160a01b0316801561077f57600580546001600160a01b031916821790557f28df65e3e787da752d78d981344a2b93809a4a4e1466ab7303e44c1e894c984e60008051602061372c833981519152600080a3005b604051630e21b92360e41b81526020600482015260076024820152667374616b696e6760c81b6044820152606490fd5b346102a95760003660031901126102a95760405160006000805160206136ec83398151915280546107df81612ede565b8085529160019180831690811561085f5750600114610815575b6106b38561080981870382612df3565b60405191829182612d62565b600090815292506000805160206137cc8339815191525b828410610847575050508101602001610809826106b36107f9565b8054602085870181019190915290930192810161082c565b8695506106b39693506020925061080994915060ff191682840152151560051b82010192936107f9565b346102a95760003660031901126102a9576020600154604051908152f35b346102a95760003660031901126102a95760008051602061370c833981519152546040516001600160a01b039091168152602090f35b346102a95760203660031901126102a9576108f6612dab565b6108fe612e31565b6001600160a01b031680156103aa5780600052600a602052604060002060ff19815416905560008051602061368c8339815191526080604051837fcdd2e9b91a56913d370075169cefa1602ba36be5301664f752192bb1709df757600080a26040815260096040820152681dda1a5d195b1a5cdd60ba1b606082015260006020820152a2005b346102a95760003660031901126102a95761099d612e31565b6109a5613436565b6000805160206137ac833981519152600160ff198254161790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1600060008051602061368c83398151915260806040516040815260066040820152651c185d5cd95960d21b606082015260016020820152a2005b346102a95760403660031901126102a957610028610a3f612dab565b60243590610a4e823383613103565b6131d9565b346102a95760003660031901126102a957610a6c612e31565b60008051602061370c83398151915280546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346102a95760203660031901126102a9576001600160a01b03610ade612dab565b166000526000805160206136cc8339815191526020526020604060002054604051908152f35b346102a95760003660031901126102a9576006546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a9576000805160206137ec833981519152805460ff8160401c168015610c10575b610bfe576000805160206137ac8339815191529081549160ff831615610bec5760029260ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a168ffffffffffffffffff19161790557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160028152a1005b604051638dfc202b60e01b8152600490fd5b60405163f92ee8a960e01b8152600490fd5b50600267ffffffffffffffff82161015610b5d565b346102a95760003660031901126102a957602060ff6000805160206137ac83398151915254166040519015158152f35b346102a95760203660031901126102a957600754600435906001600160a01b03163303610cf85763092a09f08103610ce65760005460ff8116610cd45760019060ff1916176000556001548181018091116104bd576001557f7e5a75ee59a3d939dac1be7f2c09b14ca3829223668d6beee2cd8c61ada33341600080a2005b604051637863d09b60e11b8152600490fd5b60405163baa35d1360e01b8152600490fd5b604051635c427cd960e01b8152600490fd5b346102a95760203660031901126102a957610d23612dab565b610d2b612e31565b6001600160a01b03168015610db757806000526009602052604060002060ff198154169055807f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac602060405160008152a260008051602061368c8339815191526080604051604081526009604082015268189b1858dadb1a5cdd60ba1b606082015260006020820152a2005b6040516302d9462160e11b8152600490fd5b346102a95760003660031901126102a9577f000000000000000000000000062c8c1a23fc256efe3d5fd3b38b0016fa65d6b66001600160a01b03163003610e345760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b60405163703e46dd60e11b8152600490fd5b60403660031901126102a957610e5a612dab565b602490813567ffffffffffffffff81116102a957366023820112156102a957806004013591610e8883612e15565b610e956040519182612df3565b83815260209384820193368783830101116102a95781600092888893018737830101526001600160a01b037f000000000000000000000000062c8c1a23fc256efe3d5fd3b38b0016fa65d6b68116308114908115611043575b50610e3457610efb612e31565b6040516352d1902d60e01b8152908316948082600481895afa918291600093611013575b5050610f3d57604051634c9c8ce360e01b8152600481018690528690fd5b8490867f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91828103610ffe5750843b15610fe8575080546001600160a01b03191682179055604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2815115610fce575060006100289381925190845af4610fc8613370565b916133a0565b9250505034610fd957005b63b398979f60e01b8152600490fd5b604051634c9c8ce360e01b815260048101849052fd5b60405190632a87526960e21b82526004820152fd5b9080929350813d831161103c575b61102b8183612df3565b810103126102a95751908780610f1f565b503d611021565b9050817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416141587610eee565b346102a95760203660031901126102a95761108a612dab565b611092612e31565b6001600160a01b03168015611121578060005260096020526040600020600160ff19825416179055807f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac602060405160018152a260008051602061368c8339815191526080604051604081526009604082015268189b1858dadb1a5cdd60ba1b606082015260016020820152a2005b60405163ceff43a960e01b8152600490fd5b346102a95760203660031901126102a957610028600435336131d9565b346102a95736600319016101a081126102a957610160136102a9576040366101631901126102a9576000805160206137ec8339815191525467ffffffffffffffff81168015908161292c575b6001149081612922575b159081612919575b50610bfe57600167ffffffffffffffff198216176000805160206137ec8339815191525560ff8160401c16156128ec575b604051906111ec82612dd7565b600882526750524f535045524160c01b60208301526040519061120e82612dd7565b600482526350524f5360e01b6020830152611227613407565b61122f613407565b825167ffffffffffffffff81116126b8576112586000805160206136ac83398151915254612ede565b601f8111612876575b506020601f82116001146127e857819293946000926127dd575b50508160011b916000199060031b1c1916176000805160206136ac833981519152555b815167ffffffffffffffff81116126b8576112c76000805160206136ec83398151915254612ede565b601f8111612763575b50602092601f82116001146126d957928192936000926126ce575b50508160011b916000199060031b1c1916176000805160206136ec833981519152555b611316613407565b61131e613407565b611326613407565b6000805160206137ac833981519152805460ff191690556113586113486133f1565b611350613407565b6102d2613407565b611360613407565b611368613407565b611370613407565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055604051610160810181811067ffffffffffffffff8211176126b8576040526113ba612dab565b81526113c4612dc1565b602082018190526044356001600160a01b03811690036102a9576044356040830152606435916001600160a01b03831683036102a957606081018390526084356001600160a01b03811681036102a9576080820181905260a4356001600160a01b03811690036102a95760a43560a083015260c4356001600160a01b03811690036102a95760c43560c083015260e435926001600160a01b03841684036102a95760e08301849052610104356001600160a01b03811690036102a95761010435610100840152610124356001600160a01b03811690036102a95761012435610120840152610144356001600160a01b03811690036102a957610144356101408401819052600280546001600160a01b03199081166001600160a01b0394851690811790925560048054821660443586169081179091556003805483168a87161790557f0c672d9dba74bebc168b103cf20eed62c1c5a30334e98296bf7d8ce1a5c1ea488054831690911790557f2aba2a91d77d103a85ba138e578966efc0fc31cbe14b7d7f404c10f4d9dcb9c880548216958516959095179094557f9b44a32a4ca7acffc1c70ef670b75f2f45ec2da1c467d617fe4e715a3b1a40818054851660a43585161790557f11fcaf5cfc3792b195f40db144bdc3b799b7ce582005b5824306d60336df42e18054851660c43585161790557f7b4fc011b6134f11ff666f9344f27840e3914471199406e7c283930e9718f71e80548516968416969096179095557f14dedacc455a0c0133c4baee2cf0f7ebcb6a6b327942df5289cac6a3b2980a01805484166101043584161790557f0f78416ba663791d813952b6ec605b3f25cd669082eb6212c8a1c5dfd31a2e78805484166101243584161790557f6b560155c24616b409cdfbb28a97a5d7aed4e1200d488f46207598f8f3bb998280549093169116179055604080516915185e0815d85b1b195d60b21b9052516911195d8815d85b1b195d60b21b926d14dd185ada5b99c815d85b1b195d60921b91907f2abd966a4424e65c222adebb0152a50b1af9a5eddc76e958b14c2281b60a43c260008051602061372c833981519152600080a352604051691250d3c815d85b1b195d60b21b906044356001600160a01b03167f9e58e2eac2c8e36accd1095bb9d2fe32412ce4704bf829b0ebb8b3610e2df20160008051602061372c833981519152600080a352604051926001600160a01b03167f31384fb8734df3c866f8a032e71c2794f58f31c926da33ff07f3bc99ae7a344360008051602061372c833981519152600080a360808101516f131a5c5d5a591a5d1e4815d85b1b195d60821b909352604051926001600160a01b03167f8c4b085b8571f2b28000e0c43f80bb3401681ad53fdb85d7a9349ef9b158b43060008051602061372c833981519152600080a360a08101516d11985c9b5a5b99c815d85b1b195d60921b909352604051926001600160a01b03167f37f12d4caeee3b372ab38acc5076c4f0db20dac6f8d56935611af0711adbdded60008051602061372c833981519152600080a360c08101516d131a5cdd1a5b99c815d85b1b195d60921b909352604051926001600160a01b03167f8d17dcb2491eceb42e9f410a808d5cd175c2709a6a27dcee7cb7d2a431d0b60c60008051602061372c833981519152600080a360e08101516d14995cd95c9d994815d85b1b195d60921b909352604051926001600160a01b03167f6e87f62b2c72d4ae7c556b16722dc277e6b720dcc47c54ffe66bcd60edd2c91460008051602061372c833981519152600080a36101008101516f13585c9ad95d1a5b99c815d85b1b195d60821b909352604051926001600160a01b03167f196ba63ecbc71da617f3fb326bbb7f71d30cafa2c30da919b4ff46802cdd814d60008051602061372c833981519152600080a36101208101516a1519585b4815d85b1b195d60aa1b909352604051926001600160a01b03167f90a24532a62237f4aee10052c7364ce0c2a3e9ad6693cad0c707563441386d5a60008051602061372c833981519152600080a361014001519152604051906001600160a01b03167f8f3dfe72c2152ef1f255b3cc84b8ff937e9147d0a1e8ad522910ab84d987678260008051602061372c833981519152600080a380604081011067ffffffffffffffff6040830111176126b85760408181019052610164356001600160a01b03811681036102a957808252610184356001600160a01b03811690036102a95761018435602092909201829052600680546001600160a01b038381166001600160a01b0319928316811790935560078054919095169116179092556040516f15995cdd1a5b99c810dbdb9d1c9858dd60821b908190526b1250d3c810dbdb9d1c9858dd60a21b927f788736aa4d8b33659c066e5e6eeeae6908f3a4c9759ea891608e9e6f29ff4f2191908260008051602061372c833981519152600080a3604080519190915251916001600160a01b03169060008051602061372c833981519152600080a352610184356001600160a01b03167fca2579a3c7458570c1f17089ea81eb3be417a37ad09b2ed314f7c182206f9d4260008051602061372c833981519152600080a36044356001600160a01b03161561247757611b4b6044356134bb565b7f2aba2a91d77d103a85ba138e578966efc0fc31cbe14b7d7f404c10f4d9dcb9c8546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612660575b50611bcd613436565b60008051602061374c83398151915254630bebc200810181116104bd57630bebc2000160008051602061374c83398151915255806000526000805160206136cc8339815191526020526040600020630bebc200815401905580600060008051602061378c8339815191526020604051630bebc2008152a3600060008051602061376c8339815191526020604051630bebc2008152a37f9b44a32a4ca7acffc1c70ef670b75f2f45ec2da1c467d617fe4e715a3b1a4081546001600160a01b0316801561247757611c9c906134bb565b7f11fcaf5cfc3792b195f40db144bdc3b799b7ce582005b5824306d60336df42e1546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612608575b50611d1e613436565b60008051602061374c833981519152546307270e00810181116104bd576307270e000160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206307270e00815401905580600060008051602061378c83398151915260206040516307270e008152a3600060008051602061376c83398151915260206040516307270e008152a37f7b4fc011b6134f11ff666f9344f27840e3914471199406e7c283930e9718f71e546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b0316806125b0575b50611e35613436565b60008051602061374c833981519152546302fec110810181116104bd576302fec1100160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206302fec110815401905580600060008051602061378c83398151915260206040516302fec1108152a3600060008051602061376c83398151915260206040516302fec1108152a37f14dedacc455a0c0133c4baee2cf0f7ebcb6a6b327942df5289cac6a3b2980a01546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612558575b50611f4c613436565b60008051602061374c833981519152546302faf080810181116104bd576302faf0800160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206302faf080815401905580600060008051602061378c83398151915260206040516302faf0808152a3600060008051602061376c83398151915260206040516302faf0808152a37f0f78416ba663791d813952b6ec605b3f25cd669082eb6212c8a1c5dfd31a2e78546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612500575b50612063613436565b60008051602061374c8339815191525463068e7780810181116104bd5763068e77800160008051602061374c83398151915255806000526000805160206136cc833981519152602052604060002063068e7780815401905580600060008051602061378c833981519152602060405163068e77808152a3600060008051602061376c833981519152602060405163068e77808152a37f6b560155c24616b409cdfbb28a97a5d7aed4e1200d488f46207598f8f3bb9982546001600160a01b031680156124775760008052600960205260008051602061364c8339815191525460ff1661245e5780600052600960205260ff604060002054166124e8576006546001600160a01b031680612490575b5061217a613436565b60008051602061374c833981519152546306ea0500810181116104bd576306ea05000160008051602061374c83398151915255806000526000805160206136cc83398151915260205260406000206306ea0500815401905580600060008051602061378c83398151915260206040516306ea05008152a3600060008051602061376c83398151915260206040516306ea05008152a3610184356001600160a01b0316156124775760008052600960205260008051602061364c8339815191525460ff1661245e57610184356001600160a01b031660009081526009602052604090205460ff1661243a576006546001600160a01b0316806123c0575b5061227f613436565b60008051602061374c8339815191525463092a09f0908181018091116104bd5760008051602061374c83398151915255610184356001600160a01b031660008181526000805160206136cc833981519152602090815260408083208054860190555184815260008051602061378c8339815191529190a3604051908152610184356001600160a01b03169060009060008051602061376c83398151915290602090a360ff6001600160a01b036123336133f1565b1691604051927f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6600080a260401c161561236957005b60207fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29168ff0000000000000000196000805160206137ec83398151915254166000805160206137ec8339815191525560018152a1005b602060249160405192838092631673485560e01b8252600060048301525afa9081156106105760009161240b575b506123f95781612276565b604051631aaf894760e31b8152600490fd5b61242d915060203d602011612433575b6124258183612df3565b8101906134a3565b826123ee565b503d61241b565b60405163d33f19e760e01b8152610184356001600160a01b03166004820152602490fd5b60405163d33f19e760e01b815260006004820152602490fd5b60405163ec442f0560e01b815260006004820152602490fd5b602060249160405192838092631673485560e01b8252600060048301525afa908115610610576000916124c9575b506123f95782612171565b6124e2915060203d602011612433576124258183612df3565b836124be565b6024906040519063d33f19e760e01b82526004820152fd5b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612539575b506123f9578261205a565b612552915060203d602011612433576124258183612df3565b8361252e565b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612591575b506123f95782611f43565b6125aa915060203d602011612433576124258183612df3565b83612586565b602060249160405192838092631673485560e01b8252600060048301525afa908115610610576000916125e9575b506123f95782611e2c565b612602915060203d602011612433576124258183612df3565b836125de565b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612641575b506123f95782611d15565b61265a915060203d602011612433576124258183612df3565b83612636565b602060249160405192838092631673485560e01b8252600060048301525afa90811561061057600091612699575b506123f95782611bc4565b6126b2915060203d602011612433576124258183612df3565b8361268e565b634e487b7160e01b600052604160045260246000fd5b0151905083806112eb565b601f198216936000805160206136ec8339815191526000526000805160206137cc8339815191529160005b86811061274b5750836001959610612732575b505050811b016000805160206136ec8339815191525561130e565b015160001960f88460031b161c19169055838080612717565b91926020600181928685015181550194019201612704565b6000805160206136ec833981519152600052601f820160051c6000805160206137cc8339815191520190602083106127c7575b601f0160051c6000805160206137cc83398151915201905b8181106127bb57506112d0565b600081556001016127ae565b6000805160206137cc8339815191529150612796565b01519050848061127b565b6000805160206136ac83398151915260005260008051602061366c8339815191529060005b601f198416811061285e5750600193949583601f19811610612845575b505050811b016000805160206136ac8339815191525561129e565b015160001960f88460031b161c1916905584808061282a565b9091602060018192858a01518155019301910161280d565b6000805160206136ac833981519152600052601f820160051c60008051602061366c83398151915201602083106128d7575b601f820160051c60008051602061366c8339815191520181106128cb5750611261565b600081556001016128a8565b5060008051602061366c8339815191526128a8565b68ffffffffffffffffff19811668010000000000000001176000805160206137ec833981519152556111df565b905015826111ae565b303b1591506111a6565b604083901c60ff1615915061119c565b346102a95760003660031901126102a957612955612e31565b6000805160206137ac833981519152805460ff811615610bec5760ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1600060008051602061368c83398151915260806040516040815260066040820152651c185d5cd95960d21b6060820152836020820152a2005b346102a95760003660031901126102a9576008546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a957602060405160008152f35b346102a95760003660031901126102a9576002546040516001600160a01b039091168152602090f35b346102a95760603660031901126102a9576106dd612a62612dab565b612a6a612dc1565b60443591612a79833383613103565b612f51565b346102a95760003660031901126102a9576003546040516001600160a01b039091168152602090f35b346102a95760003660031901126102a957602060ff600054166040519015158152f35b346102a95760003660031901126102a957602060008051602061374c83398151915254604051908152f35b346102a95760603660031901126102a957612b0e612dab565b6044359060ff82168092036102a957612b25612e31565b6006546001600160a01b039290831690811561061c5760009360405193630feabe0160e11b8552166004840152602435602484015260448301528160648160209586945af190811561061057600091612bcb575b5015612b885760405160018152f35b6064906040519062461bcd60e51b825280600483015260248201527f4661696c656420746f20616464206163636f756e7420746f2076657374696e676044820152fd5b612be29150823d8411612433576124258183612df3565b82612b79565b346102a95760403660031901126102a957612c01612dab565b602435903315612c82576001600160a01b0316908115612c6957612c2433612f18565b82600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b604051634a1406b160e11b815260006004820152602490fd5b60405163e602df0560e01b815260006004820152602490fd5b346102a95760003660031901126102a95760405160006000805160206136ac8339815191528054612ccb81612ede565b8085529160019180831690811561085f5750600114612cf4576106b38561080981870382612df3565b6000908152925060008051602061366c8339815191525b828410612d26575050508101602001610809826106b36107f9565b80546020858701810191909152909301928101612d0b565b346102a95760003660031901126102a9576004546001600160a01b03168152602090f35b6020808252825181830181905290939260005b828110612d9757505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501612d75565b600435906001600160a01b03821682036102a957565b602435906001600160a01b03821682036102a957565b6040810190811067ffffffffffffffff8211176126b857604052565b90601f8019910116810190811067ffffffffffffffff8211176126b857604052565b67ffffffffffffffff81116126b857601f01601f191660200190565b60008051602061370c833981519152546001600160a01b03163303612e5257565b60405163118cdaa760e01b8152336004820152602490fd5b6001600160a01b03908116908115612ec55760008051602061370c83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b604051631e4fbdf760e01b815260006004820152602490fd5b90600182811c92168015612f0e575b6020831014612ef857565b634e487b7160e01b600052602260045260246000fd5b91607f1691612eed565b6001600160a01b031660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020526040902090565b9291906001600160a01b038085169182156130ea578116928315612477576000918383526020926009845260409160ff83832054166130d2578682526009855260ff83832054166130ba5760065416848161304d575b5050612fb1613436565b8481526000805160206136cc8339815191528085528282205498848a1061301d5750908386979899849360008051602061376c8339815191529884528752038282205587815220828154019055858560008051602061378c833981519152858451868152a351908152a3565b835163391434e360e21b81526001600160a01b03919091166004820152602481018a905260448101859052606490fd5b602491845192838092631673485560e01b82528a60048301525afa9081156130b0578291613093575b50613082573884612fa7565b8151631aaf894760e31b8152600490fd5b6130aa9150853d8711612433576124258183612df3565b38613076565b83513d84823e3d90fd5b825163d33f19e760e01b815260048101889052602490fd5b825163d33f19e760e01b815260048101879052602490fd5b604051634b637e8f60e11b815260006004820152602490fd5b919061310e83612f18565b9260018060a01b039081831691600095838752602052604086205493600019850361313d575b50505050505050565b8585106131a8575081161561318f57811561317657906131606040949392612f18565b9085526020520391205538808080808080613134565b604051634a1406b160e11b815260048101869052602490fd5b60405163e602df0560e01b815260048101869052602490fd5b604051637dc7a0d960e11b81526001600160a01b039190911660048201526024810185905260448101869052606490fd5b91906001600160a01b038084169081156130ea576000928284526020916009835260409060ff8287205416613358578580526009845260ff8287205416613340576006541683816132d4575b505061322f613436565b8385526000805160206136cc83398151915280845281862054978389106132a4575085969783918660008051602061376c8339815191529798528552038187205560008051602061374c833981519152828154039055858560008051602061378c833981519152858451868152a351908152a3565b825163391434e360e21b81526001600160a01b039190911660048201526024810189905260448101849052606490fd5b602491835192838092631673485560e01b82528960048301525afa908115613336578691613319575b50613309573883613225565b51631aaf894760e31b8152600490fd5b6133309150843d8611612433576124258183612df3565b386132fd565b82513d88823e3d90fd5b815163d33f19e760e01b815260048101879052602490fd5b815163d33f19e760e01b815260048101869052602490fd5b3d1561339b573d9061338182612e15565b9161338f6040519384612df3565b82523d6000602084013e565b606090565b906133b557508051156104d357805190602001fd5b815115806133e8575b6133c6575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b156133be565b6004356001600160a01b03811681036102a95790565b60ff6000805160206137ec8339815191525460401c161561342457565b604051631afcd79f60e31b8152600490fd5b60ff6000805160206137ac833981519152541661344f57565b60405163d93c066560e01b8152600490fd5b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0060028154146134915760029055565b604051633ee5aeb560e01b8152600490fd5b908160209103126102a9575180151581036102a95790565b906000918280526020926009845260409360ff8583205416613633576001600160a01b03928316808352600982528583205490939060ff1661361b576006541681816135ae575b505061350c613436565b60008051602061374c8339815191528054956305f5e1009182880180981161359a5760008051602061376c83398151915294959697815586156000146135775780546305f5e0ff190190555b858560008051602061378c833981519152858451868152a351908152a3565b508585526000805160206136cc8339815191528352808520828154019055613558565b634e487b7160e01b85526011600452602485fd5b602491875192838092631673485560e01b82528760048301525afa9081156136115783916135f4575b506135e3573881613502565b8451631aaf894760e31b8152600490fd5b61360b9150823d8411612433576124258183612df3565b386135d7565b86513d85823e3d90fd5b855163d33f19e760e01b815260048101859052602490fd5b845163d33f19e760e01b815260048101839052602490fdfeec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b2ae08a8e29253f69ac5d979a101956ab8f8d9d7ded63fa7a83b16fc47648eab05b0b376f56fbaee6462a33ce7d274d6494bd3d6300c1623ef695e55b7635fad852c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0352c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace049016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993009909e508f055ea78c4ff7e02dd4f38b686e5527bd8c0d5cedc9bb8c0b233d44052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace021b89874203ff7f0bba87c969ada3f32fda22ed38a6706d35199d21280c7811b1ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f0330046a2803e59a4de4e7a4c574b1243f25977ac4c77d5a1a4a609b5394cebb4a2aaf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a2646970667358221220ecbe9218afd4eb3ec82c55a242ebbc1c62c6a40f3b705cdd3447e061b6646efd64736f6c63430008140033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.