S Price: $0.551718 (-2.01%)

Token

SpinnerVerifiedToken (SpinnerVerifiedToken)

Overview

Max Total Supply

0.0000000001 SpinnerVerifiedToken

Holders

1

Total Transfers

-

Market

Price

$0.00 @ 0.000000 S

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
SpinnerVerifiedToken

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
No with 200 runs

Other Settings:
paris EvmVersion
File 1 of 10 : SpinnerFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {TickMath} from "@uniswap/v3-core/contracts/libraries/TickMath.sol";

import {INonfungiblePositionManager, IUniswapV3Factory, ILockerFactory, ExactInputSingleParams, ISwapRouter, ILocker} from "./interface.sol";
import {Bytes32AddressLib} from "./Bytes32AddressLib.sol";

///@dev SpinnerVerifiedToken is a verified ERC20 token, make sure it's safe to use
/// and not a scam token
contract SpinnerVerifiedToken is ERC20 {
    constructor(
        string memory name_,
        string memory symbol_,
        uint256 maxSupply_
    ) ERC20(name_, symbol_) {
        _mint(msg.sender, maxSupply_);
    }

    function burn(uint256 amount) external {
        _burn(msg.sender, amount);
    }
}


///@dev SpinnerFactory is a factory contract to create verified tokens
/// The factory will be triggered automatically by AI to create verified tokens
/// The liquidity NFT will be locked in a locker contract
contract SpinnerFactory is Ownable {
    using TickMath for int24;
    using Bytes32AddressLib for bytes32;
    uint64 public defaultLockingPeriod = 3 * 365 days;

    address public taxCollector;
    address public deadAddress = 0x000000000000000000000000000000000000dEaD;
    uint8 public taxRate = 25;
    uint8 public lpFeesCut = 50;
    uint8 public protocolCut = 30;
    ILockerFactory public liquidityLocker;
    mapping(address => uint256) public nonce;

    address public weth;
    IUniswapV3Factory public uniswapV3Factory;
    INonfungiblePositionManager public positionManager;

    address public swapRouter;

    event TokenCreated(
        address tokenAddress,
        uint256 lpNftId,
        address deployer,
        string name,
        string symbol,
        uint256 supply,
        uint256 _supply
    );

    event LockerCreated(
        address tokenAddress,
        uint256 lpNftId,
        address lockerAddress
    );

    constructor(
        address taxCollector_,
        address weth_,
        address locker_,
        address uniswapV3Factory_,
        address positionManager_,
        uint64 defaultLockingPeriod_,
        address swapRouter_
    ) Ownable(msg.sender) {
        taxCollector = taxCollector_;
        weth = weth_;
        uniswapV3Factory = IUniswapV3Factory(uniswapV3Factory_);
        positionManager = INonfungiblePositionManager(positionManager_);
        swapRouter = swapRouter_;
        liquidityLocker = ILockerFactory(locker_);
        defaultLockingPeriod = defaultLockingPeriod_;
    }

    function createToken(
        string calldata _name,
        string calldata _symbol,
        uint256 _supply,
        int24 _initialTick,
        uint24 _fee,
        bytes32 _salt
    ) external payable returns (SpinnerVerifiedToken token, uint256 tokenId) {
        int24 tickSpacing = uniswapV3Factory.feeAmountTickSpacing(_fee);

        require(
            tickSpacing != 0 && _initialTick % tickSpacing == 0,
            "SpinnerError: Invalid tick"
        );

        token = new SpinnerVerifiedToken{
            salt: keccak256(abi.encode(msg.sender, _salt))
        }(_name, _symbol, _supply);

        require(address(token) < weth, "SpinnerError: Invalid salt");

        uint160 sqrtPriceX96 = _initialTick.getSqrtRatioAtTick();
        address pool = uniswapV3Factory.createPool(address(token), weth, _fee);
        IUniswapV3Factory(pool).initialize(sqrtPriceX96);

        INonfungiblePositionManager.MintParams
            memory params = INonfungiblePositionManager.MintParams(
                address(token),
                weth,
                _fee,
                _initialTick,
                maxUsableTick(tickSpacing),
                _supply,
                0,
                0,
                0,
                address(this),
                block.timestamp
            );

        token.approve(address(positionManager), _supply);
        (tokenId, , , ) = positionManager.mint(params);

        address lockerAddress = liquidityLocker.deploy(
            address(positionManager),
            msg.sender,
            defaultLockingPeriod,
            tokenId,
            lpFeesCut
        );

        positionManager.safeTransferFrom(address(this), lockerAddress, tokenId);

        ILocker(lockerAddress).initializer(tokenId);

        uint256 protocolFees = (msg.value * protocolCut) / 1000;
        uint256 remainingFundsToBuyTokens = msg.value - protocolFees;

        if (msg.value > 0) {
            ExactInputSingleParams memory swapParams = ExactInputSingleParams({
                tokenIn: weth,
                tokenOut: address(token),
                fee: _fee,
                recipient: msg.sender,
                amountIn: remainingFundsToBuyTokens,
                amountOutMinimum: 0,
                sqrtPriceLimitX96: 0
            });

            ISwapRouter(swapRouter).exactInputSingle{
                value: remainingFundsToBuyTokens
            }(swapParams);
        }

        (bool success, ) = payable(taxCollector).call{value: protocolFees}("");

        if (!success) {
            revert("SpinnerError: Failed to send protocol fees");
        }
        nonce[msg.sender]++;

        emit TokenCreated(
            address(token),
            tokenId,
            msg.sender,
            _name,
            _symbol,
            _supply,
            _supply
        );

        emit LockerCreated(address(token), tokenId, lockerAddress);
    }

    function initialSwapTokens(address token, uint24 _fee) public payable {
        ExactInputSingleParams memory swapParams = ExactInputSingleParams({
            tokenIn: weth,
            tokenOut: address(token),
            fee: _fee,
            recipient: msg.sender,
            amountIn: msg.value,
            amountOutMinimum: 0,
            sqrtPriceLimitX96: 0
        });
        ISwapRouter(swapRouter).exactInputSingle{value: msg.value}(swapParams);
    }

    function updateLiquidityLocker(address newLocker) external onlyOwner {
        liquidityLocker = ILockerFactory(newLocker);
    }

    function updateDefaultLockingPeriod(uint64 newPeriod) external onlyOwner {
        defaultLockingPeriod = newPeriod;
    }

    function predictToken(
        address deployer,
        string calldata name,
        string calldata symbol,
        uint256 supply,
        bytes32 salt
    ) public view returns (address) {
        bytes32 create2Salt = keccak256(abi.encode(deployer, salt));
        return
            keccak256(
                abi.encodePacked(
                    bytes1(0xFF),
                    address(this),
                    create2Salt,
                    keccak256(
                        abi.encodePacked(
                            type(SpinnerVerifiedToken).creationCode,
                            abi.encode(name, symbol, supply)
                        )
                    )
                )
            ).fromLast20Bytes();
    }

    function generateSalt(
        address deployer,
        string calldata name,
        string calldata symbol,
        uint256 supply
    ) external view returns (bytes32 salt, address token) {
        uint256 deployerNonce = nonce[deployer];
        for (uint256 i; ; i++) {
            salt = keccak256(abi.encode(deployerNonce, i));
            token = predictToken(deployer, name, symbol, supply, salt);
            if (token < weth && token.code.length == 0) {
                break;
            }
        }
    }

    function updateTaxCollector(address newCollector) external onlyOwner {
        taxCollector = newCollector;
    }

    function updateProtocolFees(uint8 newFee) external onlyOwner {
        lpFeesCut = newFee;
    }

    function updateTaxRate(uint8 newRate) external onlyOwner {
        taxRate = newRate;
    }
}

function maxUsableTick(int24 tickSpacing) pure returns (int24) {
    unchecked {
        return (TickMath.MAX_TICK / tickSpacing) * tickSpacing;
    }
}

File 2 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.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 Ownable is Context {
    address private _owner;

    /**
     * @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.
     */
    constructor(address initialOwner) {
        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) {
        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 {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 10 : draft-IERC6093.sol
// 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);
}

File 4 of 10 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.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 ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        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) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        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) {
        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 {
        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 {
        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);
            }
        }
    }
}

File 5 of 10 : IERC20Metadata.sol
// 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);
}

File 6 of 10 : IERC20.sol
// 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);
}

File 7 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 8 of 10 : TickMath.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title Math library for computing sqrt prices from ticks and vice versa
/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports
/// prices between 2**-128 and 2**128
library TickMath {
    /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128
    int24 internal constant MIN_TICK = -887272;
    /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128
    int24 internal constant MAX_TICK = -MIN_TICK;

    /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)
    uint160 internal constant MIN_SQRT_RATIO = 4295128739;
    /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)
    uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;

    /// @notice Calculates sqrt(1.0001^tick) * 2^96
    /// @dev Throws if |tick| > max tick
    /// @param tick The input tick for the above formula
    /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)
    /// at the given tick
    function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
        uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
        require(absTick <= uint256(int(MAX_TICK)), 'T');

        uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;
        if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
        if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
        if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
        if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
        if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
        if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
        if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
        if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
        if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
        if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
        if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
        if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
        if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
        if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
        if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
        if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
        if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
        if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
        if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;

        if (tick > 0) ratio = type(uint256).max / ratio;

        // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.
        // we then downcast because we know the result always fits within 160 bits due to our tick input constraint
        // we round up in the division so getTickAtSqrtRatio of the output price is always consistent
        sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
    }

    /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio
    /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may
    /// ever return.
    /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96
    /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio
    function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {
        // second inequality must be < because the price can never reach the price at the max tick
        require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R');
        uint256 ratio = uint256(sqrtPriceX96) << 32;

        uint256 r = ratio;
        uint256 msb = 0;

        assembly {
            let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(5, gt(r, 0xFFFFFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(4, gt(r, 0xFFFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(3, gt(r, 0xFF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(2, gt(r, 0xF))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := shl(1, gt(r, 0x3))
            msb := or(msb, f)
            r := shr(f, r)
        }
        assembly {
            let f := gt(r, 0x1)
            msb := or(msb, f)
        }

        if (msb >= 128) r = ratio >> (msb - 127);
        else r = ratio << (127 - msb);

        int256 log_2 = (int256(msb) - 128) << 64;

        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(63, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(62, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(61, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(60, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(59, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(58, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(57, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(56, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(55, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(54, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(53, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(52, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(51, f))
            r := shr(f, r)
        }
        assembly {
            r := shr(127, mul(r, r))
            let f := shr(128, r)
            log_2 := or(log_2, shl(50, f))
        }

        int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number

        int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);
        int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);

        tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;
    }
}

File 9 of 10 : Bytes32AddressLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Library for converting between addresses and bytes32 values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Bytes32AddressLib.sol)
library Bytes32AddressLib {
    function fromLast20Bytes(
        bytes32 bytesValue
    ) internal pure returns (address) {
        return address(uint160(uint256(bytesValue)));
    }

    function fillLast12Bytes(
        address addressValue
    ) internal pure returns (bytes32) {
        return bytes32(bytes20(addressValue));
    }
}

File 10 of 10 : interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

interface ILocker {
    function initializer(uint256 tokenId) external;
}

interface ILockerFactory {
    function deploy(
        address token,
        address beneficiary,
        uint64 durationSeconds,
        uint256 tokenId,
        uint256 fees
    ) external payable returns (address);
}

interface INonfungiblePositionManager {
    struct MintParams {
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }

    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    function mint(
        MintParams calldata params
    )
        external
        payable
        returns (
            uint256 tokenId,
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

    function createAndInitializePoolIfNecessary(
        address token0,
        address token1,
        uint24 fee,
        uint160 sqrtPriceX96
    ) external payable returns (address pool);

    function collect(
        CollectParams calldata params
    ) external payable returns (uint256 amount0, uint256 amount1);

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;
}

interface IUniswapV3Factory {
    function initialize(uint160 sqrtPriceX96) external;

    function createPool(
        address tokenA,
        address tokenB,
        uint24 fee
    ) external returns (address pool);

    function feeAmountTickSpacing(uint24 fee) external view returns (int24);
}

// interface ILockerFactory {
//     function deploy(
//         address token,
//         address beneficiary,
//         uint64 durationSeconds,
//         uint256 tokenId,
//         uint256 fees
//     ) external payable returns (address);
// }

// interface ILocker {
//     function initializer(uint256 tokenId) external;
// }

struct ExactInputSingleParams {
    address tokenIn;
    address tokenOut;
    uint24 fee;
    address recipient;
    uint256 amountIn;
    uint256 amountOutMinimum;
    uint160 sqrtPriceLimitX96;
}

interface ISwapRouter {
    function exactInputSingle(
        ExactInputSingleParams calldata params
    ) external payable returns (uint256 amountOut);
}

Settings
{
  "viaIR": true,
  "evmVersion": "paris",
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"maxSupply_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"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"},{"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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"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":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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"}]

6080604052346100305761001a6100146101de565b91610201565b610022610035565b610e1f61082c8239610e1f90f35b61003b565b60405190565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b9061006a90610040565b810190811060018060401b0382111761008257604052565b61004a565b9061009a610093610035565b9283610060565b565b600080fd5b600080fd5b600080fd5b600080fd5b60018060401b0381116100cc576100c8602091610040565b0190565b61004a565b60005b8381106100e5575050906000910152565b8060209183015181850152016100d4565b9092919261010b610106826100b0565b610087565b9381855260208501908284011161012757610125926100d1565b565b6100ab565b9080601f8301121561014a57816020610147935191016100f6565b90565b6100a6565b90565b61015b8161014f565b0361016257565b600080fd5b9050519061017482610152565b565b90916060828403126101d957600082015160018060401b0381116101d457836101a091840161012c565b9260208301519060018060401b0382116101cf576101c3816101cc93860161012c565b93604001610167565b90565b6100a1565b6100a1565b61009c565b6101fc61164b803803806101f181610087565b928339810190610176565b909192565b610215929161020f91610475565b336104f2565b565b5190565b634e487b7160e01b600052602260045260246000fd5b9060016002830492168015610251575b602083101461024c57565b61021b565b91607f1691610241565b600052602060002090565b601f602091010490565b1b90565b9190600861029091029161028a60001984610270565b92610270565b9181191691161790565b90565b6102b16102ac6102b69261014f565b61029a565b61014f565b90565b90565b91906102d26102cd6102da9361029d565b6102b9565b908354610274565b9055565b600090565b6102f5916102ef6102de565b916102bc565b565b5b818110610303575050565b8061031160006001936102e3565b016102f8565b9190601f8111610327575b505050565b6103336103589361025b565b90602061033f84610266565b83019310610360575b61035190610266565b01906102f7565b388080610322565b915061035181929050610348565b1c90565b90610383906000199060080261036e565b191690565b8161039291610372565b906002021790565b906103a481610217565b9060018060401b038211610464576103c6826103c08554610231565b85610317565b602090601f83116001146103fb579180916103ea936000926103ef575b5050610388565b90555b565b909150015138806103e3565b601f1983169161040a8561025b565b9260005b81811061044c57509160029391856001969410610432575b505050020190556103ed565b610442910151601f841690610372565b9055388080610426565b9193602060018192878701518155019501920161040e565b61004a565b906104739161039a565b565b9061048461048b926003610469565b6004610469565b565b90565b60018060a01b031690565b6104af6104aa6104b49261048d565b61029a565b610490565b90565b6104c09061049b565b90565b6104cc90610490565b90565b6104d8906104c3565b9052565b91906104f0906000602085019401906104cf565b565b8061050e61050861050360006104b7565b6104c3565b916104c3565b1461052b576105299161052160006104b7565b9190916106b4565b565b61055061053860006104b7565b600091829163ec442f0560e01b8352600483016104dc565b0390fd5b61056861056361056d92610490565b61029a565b610490565b90565b61057990610554565b90565b61058590610570565b90565b906105929061057c565b600052602052604060002090565b60001c90565b90565b6105b56105ba916105a0565b6105a6565b90565b6105c790546105a9565b90565b6105d39061014f565b9052565b60409061060161060894969593966105f7606084019860008501906104cf565b60208301906105ca565b01906105ca565b565b90610615910361014f565b90565b60001b90565b9061062b60001991610618565b9181191691161790565b9061064a6106456106519261029d565b6102b9565b825461061e565b9055565b634e487b7160e01b600052601160045260246000fd5b61067a6106809193929361014f565b9261014f565b820180921161068b57565b610655565b9061069b910161014f565b90565b91906106b2906000602085019401906105ca565b565b919091806106d36106cd6106c860006104b7565b6104c3565b916104c3565b146000146107b8576106f86106f1836106ec60026105bd565b61066b565b6002610635565b5b8261071561070f61070a60006104b7565b6104c3565b916104c3565b1460001461078b5761073a6107338361072e60026105bd565b61060a565b6002610635565b5b91909161078661077461076e7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9361057c565b9361057c565b9361077d610035565b9182918261069e565b0390a3565b6107b3826107ad61079e60008790610588565b916107a8836105bd565b610690565b90610635565b61073b565b6107cc6107c760008390610588565b6105bd565b806107df6107d98561014f565b9161014f565b10610808576107f261080391849061060a565b6107fe60008490610588565b610635565b6106f9565b90610827909192600093849363391434e360e21b8552600485016105d7565b0390fdfe60806040526004361015610013575b61052e565b61001e6000356100bd565b806306fdde03146100b8578063095ea7b3146100b357806318160ddd146100ae57806323b872dd146100a9578063313ce567146100a457806342966c681461009f57806370a082311461009a57806395d89b4114610095578063a9059cbb146100905763dd62ed3e0361000e576104f8565b610494565b61045f565b61042a565b6103d8565b61037e565b61031f565b6102af565b610256565b610169565b60e01c90565b60405190565b600080fd5b600080fd5b60009103126100de57565b6100ce565b5190565b60209181520190565b60005b838110610104575050906000910152565b8060209183015181850152016100f3565b601f801991011690565b61013e61014760209361014c93610135816100e3565b938480936100e7565b958691016100f0565b610115565b0190565b610166916020820191600081840391015261011f565b90565b34610199576101793660046100d3565b610195610184610695565b61018c6100c3565b91829182610150565b0390f35b6100c9565b60018060a01b031690565b6101b29061019e565b90565b6101be816101a9565b036101c557565b600080fd5b905035906101d7826101b5565b565b90565b6101e5816101d9565b036101ec57565b600080fd5b905035906101fe826101dc565b565b9190604083820312610229578061021d61022692600086016101ca565b936020016101f1565b90565b6100ce565b151590565b61023c9061022e565b9052565b919061025490600060208501940190610233565b565b346102875761028361027261026c366004610200565b906106b0565b61027a6100c3565b91829182610240565b0390f35b6100c9565b610295906101d9565b9052565b91906102ad9060006020850194019061028c565b565b346102df576102bf3660046100d3565b6102db6102ca610701565b6102d26100c3565b91829182610299565b0390f35b6100c9565b909160608284031261031a5761031761030084600085016101ca565b9361030e81602086016101ca565b936040016101f1565b90565b6100ce565b346103505761034c61033b6103353660046102e4565b91610717565b6103436100c3565b91829182610240565b0390f35b6100c9565b60ff1690565b61036490610355565b9052565b919061037c9060006020850194019061035b565b565b346103ae5761038e3660046100d3565b6103aa61039961076d565b6103a16100c3565b91829182610368565b0390f35b6100c9565b906020828203126103cd576103ca916000016101f1565b90565b6100ce565b60000190565b34610406576103f06103eb3660046103b3565b610783565b6103f86100c3565b80610402816103d2565b0390f35b6100c9565b9060208282031261042557610422916000016101ca565b90565b6100ce565b3461045a5761045661044561044036600461040b565b6107db565b61044d6100c3565b91829182610299565b0390f35b6100c9565b3461048f5761046f3660046100d3565b61048b61047a6107fa565b6104826100c3565b91829182610150565b0390f35b6100c9565b346104c5576104c16104b06104aa366004610200565b90610810565b6104b86100c3565b91829182610240565b0390f35b6100c9565b91906040838203126104f357806104e76104f092600086016101ca565b936020016101ca565b90565b6100ce565b346105295761052561051461050e3660046104ca565b9061084a565b61051c6100c3565b91829182610299565b0390f35b6100c9565b600080fd5b606090565b634e487b7160e01b600052602260045260246000fd5b906001600283049216801561056e575b602083101461056957565b610538565b91607f169161055e565b60209181520190565b600052602060002090565b90600092918054906105a76105a08361054e565b8094610578565b9160018116908160001461060057506001146105c3575b505050565b6105d09192939450610581565b916000925b8184106105e857505001903880806105be565b600181602092959395548486015201910192906105d5565b92949550505060ff19168252151560200201903880806105be565b906106259161058c565b90565b634e487b7160e01b600052604160045260246000fd5b9061064890610115565b810190811067ffffffffffffffff82111761066257604052565b610628565b90610687610680926106776100c3565b9384809261061b565b038361063e565b565b61069290610667565b90565b61069d610533565b506106a86003610689565b90565b600090565b6106cd916106bc6106ab565b506106c5610877565b919091610884565b600190565b600090565b60001c90565b90565b6106ec6106f1916106d7565b6106dd565b90565b6106fe90546106e0565b90565b6107096106d2565b5061071460026106f4565b90565b91610741926107246106ab565b50610739610730610877565b829084916108e2565b9190916109b2565b600190565b600090565b90565b90565b61076561076061076a9261074b565b61074e565b610355565b90565b610775610746565b506107806012610751565b90565b61078d9033610a55565b565b6107a361079e6107a89261019e565b61074e565b61019e565b90565b6107b49061078f565b90565b6107c0906107ab565b90565b906107cd906107b7565b600052602052604060002090565b6107f26107f7916107ea6106d2565b5060006107c3565b6106f4565b90565b610802610533565b5061080d6004610689565b90565b61082d9161081c6106ab565b50610825610877565b9190916109b2565b600190565b9061083c906107b7565b600052602052604060002090565b61086f9161086561086a9261085d6106d2565b506001610832565b6107c3565b6106f4565b90565b600090565b61087f610872565b503390565b916108929291600192610b14565b565b61089d906101a9565b9052565b6040906108cb6108d294969593966108c160608401986000850190610894565b602083019061028c565b019061028c565b565b906108df91036101d9565b90565b9291926108f081839061084a565b90816109066109006000196101d9565b916101d9565b03610913575b5050509050565b81610926610920876101d9565b916101d9565b1061094d57610944939461093b9193926108d4565b90600092610b14565b8038808061090c565b5061096d849291926000938493637dc7a0d960e11b8552600485016108a1565b0390fd5b90565b61098861098361098d92610971565b61074e565b61019e565b90565b61099990610974565b90565b91906109b090600060208501940190610894565b565b91826109cf6109c96109c46000610990565b6101a9565b916101a9565b14610a2c57816109f06109ea6109e56000610990565b6101a9565b916101a9565b14610a0357610a0192919091610c72565b565b610a28610a106000610990565b600091829163ec442f0560e01b83526004830161099c565b0390fd5b610a51610a396000610990565b6000918291634b637e8f60e11b83526004830161099c565b0390fd5b9081610a72610a6c610a676000610990565b6101a9565b916101a9565b14610a8f57610a8d9190610a866000610990565b9091610c72565b565b610ab4610a9c6000610990565b6000918291634b637e8f60e11b83526004830161099c565b0390fd5b60001b90565b90610acb60001991610ab8565b9181191691161790565b610ae9610ae4610aee926101d9565b61074e565b6101d9565b90565b90565b90610b09610b04610b1092610ad5565b610af1565b8254610abe565b9055565b909281610b32610b2c610b276000610990565b6101a9565b916101a9565b14610c005783610b53610b4d610b486000610990565b6101a9565b916101a9565b14610bd757610b7783610b72610b6b60018690610832565b87906107c3565b610af4565b610b81575b505050565b919091610bcc610bba610bb47f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925936107b7565b936107b7565b93610bc36100c3565b91829182610299565b0390a3388080610b7c565b610bfc610be46000610990565b6000918291634a1406b160e11b83526004830161099c565b0390fd5b610c25610c0d6000610990565b600091829163e602df0560e01b83526004830161099c565b0390fd5b634e487b7160e01b600052601160045260246000fd5b610c4e610c54919392936101d9565b926101d9565b8201809211610c5f57565b610c29565b90610c6f91016101d9565b90565b91909180610c91610c8b610c866000610990565b6101a9565b916101a9565b14600014610d7657610cb6610caf83610caa60026106f4565b610c3f565b6002610af4565b5b82610cd3610ccd610cc86000610990565b6101a9565b916101a9565b14600014610d4957610cf8610cf183610cec60026106f4565b6108d4565b6002610af4565b5b919091610d44610d32610d2c7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef936107b7565b936107b7565b93610d3b6100c3565b91829182610299565b0390a3565b610d7182610d6b610d5c600087906107c3565b91610d66836106f4565b610c64565b90610af4565b610cf9565b610d8a610d85600083906107c3565b6106f4565b80610d9d610d97856101d9565b916101d9565b10610dc657610db0610dc19184906108d4565b610dbc600084906107c3565b610af4565b610cb7565b90610de5909192600093849363391434e360e21b8552600485016108a1565b0390fdfea26469706673582212200ed6389499adb935e81c8d9703bb74e2832475309b10e845c134d8f6cbeaeac364736f6c634300081c0033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000145370696e6e65725665726966696564546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000145370696e6e65725665726966696564546f6b656e000000000000000000000000

Deployed Bytecode

0x60806040526004361015610013575b61052e565b61001e6000356100bd565b806306fdde03146100b8578063095ea7b3146100b357806318160ddd146100ae57806323b872dd146100a9578063313ce567146100a457806342966c681461009f57806370a082311461009a57806395d89b4114610095578063a9059cbb146100905763dd62ed3e0361000e576104f8565b610494565b61045f565b61042a565b6103d8565b61037e565b61031f565b6102af565b610256565b610169565b60e01c90565b60405190565b600080fd5b600080fd5b60009103126100de57565b6100ce565b5190565b60209181520190565b60005b838110610104575050906000910152565b8060209183015181850152016100f3565b601f801991011690565b61013e61014760209361014c93610135816100e3565b938480936100e7565b958691016100f0565b610115565b0190565b610166916020820191600081840391015261011f565b90565b34610199576101793660046100d3565b610195610184610695565b61018c6100c3565b91829182610150565b0390f35b6100c9565b60018060a01b031690565b6101b29061019e565b90565b6101be816101a9565b036101c557565b600080fd5b905035906101d7826101b5565b565b90565b6101e5816101d9565b036101ec57565b600080fd5b905035906101fe826101dc565b565b9190604083820312610229578061021d61022692600086016101ca565b936020016101f1565b90565b6100ce565b151590565b61023c9061022e565b9052565b919061025490600060208501940190610233565b565b346102875761028361027261026c366004610200565b906106b0565b61027a6100c3565b91829182610240565b0390f35b6100c9565b610295906101d9565b9052565b91906102ad9060006020850194019061028c565b565b346102df576102bf3660046100d3565b6102db6102ca610701565b6102d26100c3565b91829182610299565b0390f35b6100c9565b909160608284031261031a5761031761030084600085016101ca565b9361030e81602086016101ca565b936040016101f1565b90565b6100ce565b346103505761034c61033b6103353660046102e4565b91610717565b6103436100c3565b91829182610240565b0390f35b6100c9565b60ff1690565b61036490610355565b9052565b919061037c9060006020850194019061035b565b565b346103ae5761038e3660046100d3565b6103aa61039961076d565b6103a16100c3565b91829182610368565b0390f35b6100c9565b906020828203126103cd576103ca916000016101f1565b90565b6100ce565b60000190565b34610406576103f06103eb3660046103b3565b610783565b6103f86100c3565b80610402816103d2565b0390f35b6100c9565b9060208282031261042557610422916000016101ca565b90565b6100ce565b3461045a5761045661044561044036600461040b565b6107db565b61044d6100c3565b91829182610299565b0390f35b6100c9565b3461048f5761046f3660046100d3565b61048b61047a6107fa565b6104826100c3565b91829182610150565b0390f35b6100c9565b346104c5576104c16104b06104aa366004610200565b90610810565b6104b86100c3565b91829182610240565b0390f35b6100c9565b91906040838203126104f357806104e76104f092600086016101ca565b936020016101ca565b90565b6100ce565b346105295761052561051461050e3660046104ca565b9061084a565b61051c6100c3565b91829182610299565b0390f35b6100c9565b600080fd5b606090565b634e487b7160e01b600052602260045260246000fd5b906001600283049216801561056e575b602083101461056957565b610538565b91607f169161055e565b60209181520190565b600052602060002090565b90600092918054906105a76105a08361054e565b8094610578565b9160018116908160001461060057506001146105c3575b505050565b6105d09192939450610581565b916000925b8184106105e857505001903880806105be565b600181602092959395548486015201910192906105d5565b92949550505060ff19168252151560200201903880806105be565b906106259161058c565b90565b634e487b7160e01b600052604160045260246000fd5b9061064890610115565b810190811067ffffffffffffffff82111761066257604052565b610628565b90610687610680926106776100c3565b9384809261061b565b038361063e565b565b61069290610667565b90565b61069d610533565b506106a86003610689565b90565b600090565b6106cd916106bc6106ab565b506106c5610877565b919091610884565b600190565b600090565b60001c90565b90565b6106ec6106f1916106d7565b6106dd565b90565b6106fe90546106e0565b90565b6107096106d2565b5061071460026106f4565b90565b91610741926107246106ab565b50610739610730610877565b829084916108e2565b9190916109b2565b600190565b600090565b90565b90565b61076561076061076a9261074b565b61074e565b610355565b90565b610775610746565b506107806012610751565b90565b61078d9033610a55565b565b6107a361079e6107a89261019e565b61074e565b61019e565b90565b6107b49061078f565b90565b6107c0906107ab565b90565b906107cd906107b7565b600052602052604060002090565b6107f26107f7916107ea6106d2565b5060006107c3565b6106f4565b90565b610802610533565b5061080d6004610689565b90565b61082d9161081c6106ab565b50610825610877565b9190916109b2565b600190565b9061083c906107b7565b600052602052604060002090565b61086f9161086561086a9261085d6106d2565b506001610832565b6107c3565b6106f4565b90565b600090565b61087f610872565b503390565b916108929291600192610b14565b565b61089d906101a9565b9052565b6040906108cb6108d294969593966108c160608401986000850190610894565b602083019061028c565b019061028c565b565b906108df91036101d9565b90565b9291926108f081839061084a565b90816109066109006000196101d9565b916101d9565b03610913575b5050509050565b81610926610920876101d9565b916101d9565b1061094d57610944939461093b9193926108d4565b90600092610b14565b8038808061090c565b5061096d849291926000938493637dc7a0d960e11b8552600485016108a1565b0390fd5b90565b61098861098361098d92610971565b61074e565b61019e565b90565b61099990610974565b90565b91906109b090600060208501940190610894565b565b91826109cf6109c96109c46000610990565b6101a9565b916101a9565b14610a2c57816109f06109ea6109e56000610990565b6101a9565b916101a9565b14610a0357610a0192919091610c72565b565b610a28610a106000610990565b600091829163ec442f0560e01b83526004830161099c565b0390fd5b610a51610a396000610990565b6000918291634b637e8f60e11b83526004830161099c565b0390fd5b9081610a72610a6c610a676000610990565b6101a9565b916101a9565b14610a8f57610a8d9190610a866000610990565b9091610c72565b565b610ab4610a9c6000610990565b6000918291634b637e8f60e11b83526004830161099c565b0390fd5b60001b90565b90610acb60001991610ab8565b9181191691161790565b610ae9610ae4610aee926101d9565b61074e565b6101d9565b90565b90565b90610b09610b04610b1092610ad5565b610af1565b8254610abe565b9055565b909281610b32610b2c610b276000610990565b6101a9565b916101a9565b14610c005783610b53610b4d610b486000610990565b6101a9565b916101a9565b14610bd757610b7783610b72610b6b60018690610832565b87906107c3565b610af4565b610b81575b505050565b919091610bcc610bba610bb47f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925936107b7565b936107b7565b93610bc36100c3565b91829182610299565b0390a3388080610b7c565b610bfc610be46000610990565b6000918291634a1406b160e11b83526004830161099c565b0390fd5b610c25610c0d6000610990565b600091829163e602df0560e01b83526004830161099c565b0390fd5b634e487b7160e01b600052601160045260246000fd5b610c4e610c54919392936101d9565b926101d9565b8201809211610c5f57565b610c29565b90610c6f91016101d9565b90565b91909180610c91610c8b610c866000610990565b6101a9565b916101a9565b14600014610d7657610cb6610caf83610caa60026106f4565b610c3f565b6002610af4565b5b82610cd3610ccd610cc86000610990565b6101a9565b916101a9565b14600014610d4957610cf8610cf183610cec60026106f4565b6108d4565b6002610af4565b5b919091610d44610d32610d2c7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef936107b7565b936107b7565b93610d3b6100c3565b91829182610299565b0390a3565b610d7182610d6b610d5c600087906107c3565b91610d66836106f4565b610c64565b90610af4565b610cf9565b610d8a610d85600083906107c3565b6106f4565b80610d9d610d97856101d9565b916101d9565b10610dc657610db0610dc19184906108d4565b610dbc600084906107c3565b610af4565b610cb7565b90610de5909192600093849363391434e360e21b8552600485016108a1565b0390fdfea26469706673582212200ed6389499adb935e81c8d9703bb74e2832475309b10e845c134d8f6cbeaeac364736f6c634300081c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000145370696e6e65725665726966696564546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000145370696e6e65725665726966696564546f6b656e000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): SpinnerVerifiedToken
Arg [1] : symbol_ (string): SpinnerVerifiedToken
Arg [2] : maxSupply_ (uint256): 100000000

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000000000000000000000000000000000000005f5e100
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [4] : 5370696e6e65725665726966696564546f6b656e000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [6] : 5370696e6e65725665726966696564546f6b656e000000000000000000000000


[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.