ETH Price: $3,094.91 (-0.55%)
 

Overview

Max Total Supply

2,576,541,410,075,008,306.898625 ERC20 ***

Holders

0

Transfers

-
0

Market

Onchain Market Cap

-

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 6 Decimals)

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

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
UniswapV2DynamicERC20

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.24;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {
    IERC20Metadata
} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

import {
    IUniswapV2DynamicPriceRouter
} from "../router/IUniswapV2DynamicPriceRouter.sol";
import {DynamicERC20} from "../abstract/DynamicERC20.sol";

/*
 ____                 _            _   __  __ _       _   
|  _ \ _ __ ___   __| |_   _  ___| |_|  \/  (_)_ __ | |_ 
| |_) | '__/ _ \ / _` | | | |/ __| __| |\/| | | '_ \| __|
|  __/| | | (_) | (_| | |_| | (__| |_| |  | | | | | | |_ 
|_|   |_|  \___/ \__,_|\__,_|\___|\__|_|  |_|_|_| |_|\__|
 
 NFT based payment system to mint products onchain with one-time payments and 
 recurring permissionless subscriptions.

 https://productmint.io
*/

/**
 * @title UniswapV2DynamicERC20
 * @notice A dynamic ERC20 token that uses Uniswap V2 to get the current swap price.
 * @dev A UniswapV2DynamicERC20 cannot be minted, burned, or transferred
 *
 * Used within the ProductMint system to act as a proxy for the base token against the quote token.
 * The base token is used to charge for payment.
 * The quote token is used for price targeting.
 * A dynamic price router is used to get the current swap price at a dex such as Uniswap.
 *
 * For example, assume the base token is WETH and the quote token is USDC.
 * An organization can use the DynamicERC20 to create a pricing model that targets a price of 100 USDC.
 * Then, when a user purchases a product, 100 USDC worth of WETH will be transferred to the organization.
 */
contract UniswapV2DynamicERC20 is DynamicERC20, Ownable2Step {
    constructor(
        string memory _name,
        string memory _symbol,
        address _baseToken,
        address _quoteToken,
        address _dynamicPriceRouter,
        address[] memory _baseToQuotePath,
        address[] memory _quoteToBasePath
    )
        DynamicERC20(
            _name,
            _symbol,
            _baseToken,
            _quoteToken,
            _dynamicPriceRouter
        )
        Ownable(_msgSender())
    {
        _setBaseToQuotePath(_baseToQuotePath);
        _setQuoteToBasePath(_quoteToBasePath);
    }

    /**
     * IDynamicERC20
     */

    function getBaseTokenPrice() external view returns (uint256) {
        return _getQuoteTokenAmount(10 ** IERC20Metadata(baseToken).decimals());
    }

    function balanceOfQuote(address _account) external view returns (uint256) {
        return _getQuoteTokenAmount(IERC20(baseToken).balanceOf(_account));
    }

    function allowanceQuote(
        address owner,
        address spender
    ) external view returns (uint256) {
        return
            _getQuoteTokenAmount(IERC20(baseToken).allowance(owner, spender));
    }

    function getBaseTokenAmount(
        uint256 quoteTokenAmount
    ) external view returns (address, uint256) {
        return (baseToken, _getBaseTokenAmount(quoteTokenAmount));
    }

    function getQuoteTokenAmount(
        uint256 baseTokenAmount
    ) external view returns (address, uint256) {
        return (quoteToken, _getQuoteTokenAmount(baseTokenAmount));
    }

    function _getBaseTokenAmount(
        uint256 amount
    ) internal view returns (uint256) {
        if (amount == 0) return 0;
        return
            IUniswapV2DynamicPriceRouter(dynamicPriceRouter)
                .getPriceFeesRemoved(amount, quoteToBasePath);
    }

    function _getQuoteTokenAmount(
        uint256 amount
    ) internal view returns (uint256) {
        if (amount == 0) return 0;
        return
            IUniswapV2DynamicPriceRouter(dynamicPriceRouter)
                .getPriceFeesRemoved(amount, baseToQuotePath);
    }

    /**
     * Base to quote path
     */

    /**
     * @notice Emitted when the base to quote path is set
     * @param dynamicERC20 The address of the current dynamic ERC20 contract
     * @param baseToken The address of the base token
     * @param quoteToken The address of the quote token
     * @param baseToQuotePath The path used to convert the base token to the quote token
     */
    event UniswapV2BaseToQuotePathSet(
        address indexed dynamicERC20,
        address indexed baseToken,
        address indexed quoteToken,
        address[] baseToQuotePath
    );

    function setBaseToQuotePath(
        address[] calldata _baseToQuotePath
    ) external onlyOwner {
        _setBaseToQuotePath(_baseToQuotePath);
    }

    function _setBaseToQuotePath(address[] memory _baseToQuotePath) internal {
        _checkBaseToQuotePath(_baseToQuotePath);
        _checkPriceValid(_baseToQuotePath);

        baseToQuotePath = _baseToQuotePath;

        emit UniswapV2BaseToQuotePathSet(
            address(this),
            baseToken,
            quoteToken,
            _baseToQuotePath
        );
    }

    /**
     * Quote to base path
     */

    /**
     * @notice Emitted when the quote to base path is set
     * @param dynamicERC20 The address of the current dynamic ERC20 contract
     * @param quoteToBasePath The path used to convert the quote token to the base token
     */
    event UniswapV2QuoteToBasePathSet(
        address indexed dynamicERC20,
        address indexed baseToken,
        address indexed quoteToken,
        address[] quoteToBasePath
    );

    function setQuoteToBasePath(
        address[] calldata _quoteToBasePath
    ) external onlyOwner {
        _setQuoteToBasePath(_quoteToBasePath);
    }

    function _setQuoteToBasePath(address[] memory _quoteToBasePath) internal {
        _checkQuoteToBasePath(_quoteToBasePath);
        _checkPriceValid(_quoteToBasePath);

        quoteToBasePath = _quoteToBasePath;

        emit UniswapV2QuoteToBasePathSet(
            address(this),
            baseToken,
            quoteToken,
            _quoteToBasePath
        );
    }

    /**
     * Path updates
     */

    /**
     * @dev Error when attempting to set an invalid path
     */
    error InvalidPath(address[] _path);

    function _checkPriceValid(address[] memory _path) internal view {
        try
            IUniswapV2DynamicPriceRouter(dynamicPriceRouter)
                .getPriceFeesRemoved(
                    10 ** IERC20Metadata(_path[0]).decimals(),
                    _path
                )
        {} catch {
            revert InvalidPath(_path);
        }
    }

    /**
     * Dynamic price router updates
     */

    function setDynamicPriceRouter(
        address _dynamicPriceRouter
    ) external onlyOwner {
        _setDynamicPriceRouter(_dynamicPriceRouter);
    }

    function _setDynamicPriceRouter(
        address _dynamicPriceRouter
    ) internal override {
        require(
            IERC165(_dynamicPriceRouter).supportsInterface(
                type(IUniswapV2DynamicPriceRouter).interfaceId
            ),
            "Does not implement IUniswapV2DynamicPriceRouter"
        );

        super._setDynamicPriceRouter(_dynamicPriceRouter);
    }
}

// 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);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.20;

import {Ownable} from "./Ownable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This extension of the {Ownable} contract includes a two-step mechanism to transfer
 * ownership, where the new owner must call {acceptOwnership} in order to replace the
 * old one. This can help prevent common mistakes, such as transfers of ownership to
 * incorrect accounts, or to contracts that are unable to interact with the
 * permission system.
 *
 * The initial owner is specified at deployment time in the constructor for `Ownable`. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Returns the address of the pending owner.
     */
    function pendingOwner() public view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     *
     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        if (pendingOwner() != sender) {
            revert OwnableUnauthorizedAccount(sender);
        }
        _transferOwnership(sender);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.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 ERC-20 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.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// 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;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.24;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {
    IERC20Metadata
} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

import {IDynamicERC20} from "../tokens/IDynamicERC20.sol";
import {IDynamicPriceRouter} from "../router/IDynamicPriceRouter.sol";

/**
 * @title DynamicERC20
 * @notice DynamicERC20 is an abstract contract that implements the IDynamicERC20 interface.
 * It is used to create dynamic ERC20 tokens that can be used to pay for products.
 *
 * This contract should be used to create Dynamic tokens using dex routers.
 */
abstract contract DynamicERC20 is
    ERC165,
    IERC20,
    IERC20Metadata,
    IDynamicERC20
{
    // Name for the token
    string private _name;

    // Symbol for the token
    string private _symbol;

    // Token used for payment
    address public immutable baseToken;

    // Token used for price targeting
    address public immutable quoteToken;

    // Path used to convert the base token to the quote token
    address[] internal baseToQuotePath;

    // Path used to convert the quote token to the base token
    address[] internal quoteToBasePath;

    // Dynamic price router to interact with the dex
    address public dynamicPriceRouter;

    constructor(
        string memory name_,
        string memory symbol_,
        address _baseToken,
        address _quoteToken,
        address _dynamicPriceRouter
    ) {
        require(_baseToken != address(0), "Base token cannot be zero address");
        require(
            _quoteToken != address(0),
            "Quote token cannot be zero address"
        );
        require(
            _baseToken != _quoteToken,
            "Base and quote token cannot be the same"
        );

        _name = name_;
        _symbol = symbol_;

        baseToken = _baseToken;
        quoteToken = _quoteToken;

        _setDynamicPriceRouter(_dynamicPriceRouter);
    }

    /**
     * IDynamicERC20
     */

    function routerName() external view virtual returns (string memory) {
        return IDynamicPriceRouter(dynamicPriceRouter).ROUTER_NAME();
    }

    function getBaseToQuotePath()
        external
        view
        virtual
        returns (address[] memory)
    {
        return baseToQuotePath;
    }

    function getQuoteToBasePath()
        external
        view
        virtual
        returns (address[] memory)
    {
        return quoteToBasePath;
    }

    /**
     * IERC20Metadata
     */

    function name() external view virtual returns (string memory) {
        return _name;
    }

    function symbol() external view virtual returns (string memory) {
        return _symbol;
    }

    function decimals() external view virtual returns (uint8) {
        return IERC20Metadata(quoteToken).decimals();
    }

    /**
     * IERC20
     */

    error TransferNotAllowed();
    error ApproveNotAllowed();

    function totalSupply() external view virtual returns (uint256) {
        return IERC20(baseToken).totalSupply();
    }

    function balanceOf(
        address account
    ) external view virtual returns (uint256) {
        return IERC20(baseToken).balanceOf(account);
    }

    /**
     * @dev Not allowed to transfer the token.
     */
    function transfer(address, uint256) external pure returns (bool) {
        revert TransferNotAllowed();
    }

    function allowance(
        address owner,
        address spender
    ) external view virtual returns (uint256) {
        return IERC20(baseToken).allowance(owner, spender);
    }

    /**
     * @dev Not allowed to approve the token.
     */
    function approve(address, uint256) external pure returns (bool) {
        revert ApproveNotAllowed();
    }

    /**
     * @dev Not allowed to transfer the token.
     */
    function transferFrom(
        address,
        address,
        uint256
    ) external pure returns (bool) {
        revert TransferNotAllowed();
    }

    /**
     * Dynamic price router updates
     */

    /**
     * @notice Emitted when the dynamic price router is set
     * @param dynamicERC20 The address of the current dynamic ERC20 contract
     * @param dynamicPriceRouter The address of the dynamic price router
     */
    event DynamicPriceRouterSet(
        address indexed dynamicERC20,
        address indexed dynamicPriceRouter
    );

    function _setDynamicPriceRouter(
        address _dynamicPriceRouter
    ) internal virtual {
        dynamicPriceRouter = _dynamicPriceRouter;

        emit DynamicPriceRouterSet(address(this), _dynamicPriceRouter);
    }

    /**
     * Checks
     */

    function _checkBaseToQuotePath(address[] memory _path) internal virtual {
        require(_path.length > 1, "Path must have at least 2 tokens");
        require(_path[0] == baseToken, "Base token must be first in path");
        require(
            _path[_path.length - 1] == quoteToken,
            "Quote token must be last in path"
        );
    }

    function _checkQuoteToBasePath(address[] memory _path) internal virtual {
        require(_path.length > 1, "Path must have at least 2 tokens");
        require(_path[0] == quoteToken, "Quote token must be first in path");
        require(
            _path[_path.length - 1] == baseToken,
            "Base token must be last in path"
        );
    }

    /**
     * ERC165
     */

    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override returns (bool) {
        return
            interfaceId == type(IDynamicERC20).interfaceId ||
            interfaceId == type(IERC20).interfaceId ||
            interfaceId == type(IERC20Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }
}

File 10 of 12 : IDynamicPriceRouter.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.24;

interface IDynamicPriceRouter {
    /**
     * @notice Get the name of the underlying price router.
     * @return The name of the underlying price router. i.e. "uniswap-v2" or "uniswap-v3"
     */
    function ROUTER_NAME() external view returns (string memory);
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.24;

import {IDynamicPriceRouter} from "./IDynamicPriceRouter.sol";

/**
 * @title IUniswapV2DynamicPriceRouter
 * @notice Interface for a dynamic price router that uses Uniswap V2.
 */
interface IUniswapV2DynamicPriceRouter is IDynamicPriceRouter {
    /**
     * @notice Get the direct swap price for the final token in the given path with Uniswap fees included.
     * @param amountIn The amount of token to convert.
     * @param path The path to use for the conversion.
     * @return The amount of token at the end of the path received.
     */
    function getPrice(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256);

    /**
     * @notice Get the direct swap price for the final token in the given path with Uniswap fees excluded.
     * @dev We do a best approximation of the price without fees.
     * @param amountIn The amount of token to convert.
     * @param path The path to use for the conversion.
     * @return The amount of token at the end of the path received.
     */
    function getPriceFeesRemoved(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256);
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.24;

/**
 * @title IDynamicERC20
 * @notice An interface for a DynamicERC20 contract allowing for targeted pricing against a quote token.
 */
interface IDynamicERC20 {
    /**
     * @notice Get the name of the dynamic price router
     * @return The name of the dynamic price router
     */
    function routerName() external view returns (string memory);

    /**
     * @notice Get the address of the dynamic price router
     * @return The address of the dynamic price router
     */
    function dynamicPriceRouter() external view returns (address);

    /**
     * @notice The ERC20 token used to charge for payment
     * @return The contract address of the base token
     */
    function baseToken() external view returns (address);

    /**
     * @dev The ERC20 token used for price targeting
     * @return The contract address of the quote token
     */
    function quoteToken() external view returns (address);

    /**
     * @notice Get the path used to convert the base token to the quote token
     * @return The path used to pass through the dex
     */
    function getBaseToQuotePath() external view returns (address[] memory);

    /**
     * @notice Get the path used to convert the quote token to the base token
     * @return The path used to pass through the dex
     */
    function getQuoteToBasePath() external view returns (address[] memory);

    /**
     * @notice Get the current swap price of the base token in terms of the quote token
     * @return The amount of quote token per 1 base token
     */
    function getBaseTokenPrice() external returns (uint256);

    /**
     * @notice Get the balance of the base token in terms of the quote token pricing
     * @param account The address to get the balance of
     * @return The balance of the base token in quote token terms
     */
    function balanceOfQuote(address account) external returns (uint256);

    /**
     * @notice Get the allowance of the base token in terms of the quote token pricing
     * @param owner The address to get the allowance of
     * @return The allowance of the base token in quote token terms
     */
    function allowanceQuote(
        address owner,
        address spender
    ) external returns (uint256);

    /**
     * @notice Get the amount of base tokens that would be received for a given amount of quote tokens
     * @param quoteTokenAmount The amount of quote tokens to convert to base tokens
     * @return baseToken The address of the base token
     * @return baseTokenAmount The amount of base tokens that would be received
     */
    function getBaseTokenAmount(
        uint256 quoteTokenAmount
    ) external returns (address baseToken, uint256 baseTokenAmount);

    /**
     * @notice Get the amount of quote tokens that would be received for a given amount of base tokens
     * @param baseTokenAmount The amount of base tokens to convert to quote tokens
     * @return quoteToken The address of the quote token
     * @return quoteTokenAmount The amount of quote tokens that would be received
     */
    function getQuoteTokenAmount(
        uint256 baseTokenAmount
    ) external returns (address quoteToken, uint256 quoteTokenAmount);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "evmVersion": "paris",
  "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":"address","name":"_baseToken","type":"address"},{"internalType":"address","name":"_quoteToken","type":"address"},{"internalType":"address","name":"_dynamicPriceRouter","type":"address"},{"internalType":"address[]","name":"_baseToQuotePath","type":"address[]"},{"internalType":"address[]","name":"_quoteToBasePath","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApproveNotAllowed","type":"error"},{"inputs":[{"internalType":"address[]","name":"_path","type":"address[]"}],"name":"InvalidPath","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":"TransferNotAllowed","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":"dynamicERC20","type":"address"},{"indexed":true,"internalType":"address","name":"dynamicPriceRouter","type":"address"}],"name":"DynamicPriceRouterSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":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":true,"internalType":"address","name":"dynamicERC20","type":"address"},{"indexed":true,"internalType":"address","name":"baseToken","type":"address"},{"indexed":true,"internalType":"address","name":"quoteToken","type":"address"},{"indexed":false,"internalType":"address[]","name":"baseToQuotePath","type":"address[]"}],"name":"UniswapV2BaseToQuotePathSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"dynamicERC20","type":"address"},{"indexed":true,"internalType":"address","name":"baseToken","type":"address"},{"indexed":true,"internalType":"address","name":"quoteToken","type":"address"},{"indexed":false,"internalType":"address[]","name":"quoteToBasePath","type":"address[]"}],"name":"UniswapV2QuoteToBasePathSet","type":"event"},{"inputs":[],"name":"acceptOwnership","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":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowanceQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOfQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dynamicPriceRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseToQuotePath","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quoteTokenAmount","type":"uint256"}],"name":"getBaseTokenAmount","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQuoteToBasePath","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"baseTokenAmount","type":"uint256"}],"name":"getQuoteTokenAmount","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"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":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routerName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_baseToQuotePath","type":"address[]"}],"name":"setBaseToQuotePath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dynamicPriceRouter","type":"address"}],"name":"setDynamicPriceRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_quoteToBasePath","type":"address[]"}],"name":"setQuoteToBasePath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b5060405162002a1638038062002a16833981016040819052620000349162000a99565b3387878787876001600160a01b038316620000a05760405162461bcd60e51b815260206004820152602160248201527f4261736520746f6b656e2063616e6e6f74206265207a65726f206164647265736044820152607360f81b60648201526084015b60405180910390fd5b6001600160a01b038216620001035760405162461bcd60e51b815260206004820152602260248201527f51756f746520746f6b656e2063616e6e6f74206265207a65726f206164647265604482015261737360f01b606482015260840162000097565b816001600160a01b0316836001600160a01b031603620001765760405162461bcd60e51b815260206004820152602760248201527f4261736520616e642071756f746520746f6b656e2063616e6e6f74206265207460448201526668652073616d6560c81b606482015260840162000097565b600062000184868262000c1b565b50600162000193858262000c1b565b506001600160a01b03808416608052821660a052620001b28162000214565b5050506001600160a01b0383169150620001e5905057604051631e4fbdf760e01b81526000600482015260240162000097565b620001f081620002fa565b50620001fc8262000315565b62000207816200039f565b5050505050505062000f26565b6040516301ffc9a760e01b815263b130abe360e01b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa15801562000260573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000286919062000ce7565b620002ec5760405162461bcd60e51b815260206004820152602f60248201527f446f6573206e6f7420696d706c656d656e742049556e6973776170563244796e60448201526e30b6b4b1a83934b1b2a937baba32b960891b606482015260840162000097565b620002f7816200041e565b50565b600680546001600160a01b0319169055620002f7816200046a565b6200032081620004bc565b6200032b8162000610565b80516200034090600290602084019062000894565b5060a0516001600160a01b03166080516001600160a01b0316306001600160a01b03167f25b4c0059a7a45c3fb2e9a613393e8a0b8339d669153d7add5c83611d89074808460405162000394919062000d59565b60405180910390a450565b620003aa8162000736565b620003b58162000610565b8051620003ca90600390602084019062000894565b5060a0516001600160a01b03166080516001600160a01b0316306001600160a01b03167f3105ebf8cfe0d8803d5b103773a21806a6c43fa57501763b771be3db158bfcd58460405162000394919062000d59565b600480546001600160a01b0319166001600160a01b03831690811790915560405130907fd208b3f2137ba34e4b2ea29e6e0558a1395796409f6b8328f2cbd5ff9159bc1590600090a350565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001815111620004fe5760405162461bcd60e51b81526020600482018190526024820152600080516020620029f6833981519152604482015260640162000097565b6080516001600160a01b03168160008151811062000520576200052062000d6e565b60200260200101516001600160a01b031614620005805760405162461bcd60e51b815260206004820181905260248201527f4261736520746f6b656e206d75737420626520666972737420696e2070617468604482015260640162000097565b60a0516001600160a01b031681600183516200059d919062000d9a565b81518110620005b057620005b062000d6e565b60200260200101516001600160a01b031614620002f75760405162461bcd60e51b815260206004820181905260248201527f51756f746520746f6b656e206d757374206265206c61737420696e2070617468604482015260640162000097565b60045481516001600160a01b039091169063bd3f03f99083906000906200063b576200063b62000d6e565b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000681573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006a7919062000db6565b620006b490600a62000ed8565b836040518363ffffffff1660e01b8152600401620006d492919062000ee9565b602060405180830381865afa92505050801562000710575060408051601f3d908101601f191682019092526200070d9181019062000f0c565b60015b6200073257806040516354da4f1960e01b815260040162000097919062000d59565b5050565b6001815111620007785760405162461bcd60e51b81526020600482018190526024820152600080516020620029f6833981519152604482015260640162000097565b60a0516001600160a01b0316816000815181106200079a576200079a62000d6e565b60200260200101516001600160a01b031614620008045760405162461bcd60e51b815260206004820152602160248201527f51756f746520746f6b656e206d75737420626520666972737420696e207061746044820152600d60fb1b606482015260840162000097565b6080516001600160a01b0316816001835162000821919062000d9a565b8151811062000834576200083462000d6e565b60200260200101516001600160a01b031614620002f75760405162461bcd60e51b815260206004820152601f60248201527f4261736520746f6b656e206d757374206265206c61737420696e207061746800604482015260640162000097565b828054828255906000526020600020908101928215620008ec579160200282015b82811115620008ec57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620008b5565b50620008fa929150620008fe565b5090565b5b80821115620008fa5760008155600101620008ff565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000956576200095662000915565b604052919050565b600082601f8301126200097057600080fd5b81516001600160401b038111156200098c576200098c62000915565b6020620009a2601f8301601f191682016200092b565b8281528582848701011115620009b757600080fd5b60005b83811015620009d7578581018301518282018401528201620009ba565b506000928101909101919091529392505050565b80516001600160a01b038116811462000a0357600080fd5b919050565b600082601f83011262000a1a57600080fd5b815160206001600160401b0382111562000a385762000a3862000915565b8160051b62000a498282016200092b565b928352848101820192828101908785111562000a6457600080fd5b83870192505b8483101562000a8e5762000a7e83620009eb565b8252918301919083019062000a6a565b979650505050505050565b600080600080600080600060e0888a03121562000ab557600080fd5b87516001600160401b038082111562000acd57600080fd5b62000adb8b838c016200095e565b985060208a015191508082111562000af257600080fd5b62000b008b838c016200095e565b975062000b1060408b01620009eb565b965062000b2060608b01620009eb565b955062000b3060808b01620009eb565b945060a08a015191508082111562000b4757600080fd5b62000b558b838c0162000a08565b935060c08a015191508082111562000b6c57600080fd5b5062000b7b8a828b0162000a08565b91505092959891949750929550565b600181811c9082168062000b9f57607f821691505b60208210810362000bc057634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000c16576000816000526020600020601f850160051c8101602086101562000bf15750805b601f850160051c820191505b8181101562000c125782815560010162000bfd565b5050505b505050565b81516001600160401b0381111562000c375762000c3762000915565b62000c4f8162000c48845462000b8a565b8462000bc6565b602080601f83116001811462000c87576000841562000c6e5750858301515b600019600386901b1c1916600185901b17855562000c12565b600085815260208120601f198616915b8281101562000cb85788860151825594840194600190910190840162000c97565b508582101562000cd75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121562000cfa57600080fd5b8151801515811462000d0b57600080fd5b9392505050565b60008151808452602080850194506020840160005b8381101562000d4e5781516001600160a01b03168752958201959082019060010162000d27565b509495945050505050565b60208152600062000d0b602083018462000d12565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111562000db05762000db062000d84565b92915050565b60006020828403121562000dc957600080fd5b815160ff8116811462000d0b57600080fd5b600181815b8085111562000e1c57816000190482111562000e005762000e0062000d84565b8085161562000e0e57918102915b93841c939080029062000de0565b509250929050565b60008262000e355750600162000db0565b8162000e445750600062000db0565b816001811462000e5d576002811462000e685762000e88565b600191505062000db0565b60ff84111562000e7c5762000e7c62000d84565b50506001821b62000db0565b5060208310610133831016604e8410600b841016171562000ead575081810a62000db0565b62000eb9838362000ddb565b806000190482111562000ed05762000ed062000d84565b029392505050565b600062000d0b60ff84168362000e24565b82815260406020820152600062000f04604083018462000d12565b949350505050565b60006020828403121562000f1f57600080fd5b5051919050565b60805160a051611a3362000fc36000396000818161023f015281816105f6015281816107d701528181610cde01528181610db50152818161104e01526112aa0152600081816103c001528181610552015281816106fa0152818161088b0152818161097c01528181610a1601528181610b3a01528181610bac01528181610d0801528181610ddf01528181610fb3015261134f0152611a336000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806379ba509711610104578063aebab157116100a2578063dd62ed3e11610071578063dd62ed3e146103ea578063e30c3978146103fd578063e71dc5e51461040e578063f2fde38b1461042157600080fd5b8063aebab15714610395578063be41d5bc146103a8578063c55dae63146103bb578063cb27a434146103e257600080fd5b80638da5cb5b116100de5780638da5cb5b1461035b57806395d89b411461036c5780639bd230f314610374578063a9059cbb1461038757600080fd5b806379ba50971461032d5780637a19c83d146103355780638caecde51461034857600080fd5b806339ff2da2116101715780636702fcac1161014b5780636702fcac146102cb5780636bb26dba146102fd57806370a0823114610312578063715018a61461032557600080fd5b806339ff2da2146102a65780634971c79a146102ae5780634b230342146102b657600080fd5b806318160ddd116101ad57806318160ddd14610224578063217a4b701461023a57806323b872dd14610279578063313ce5671461028c57600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063095ea7b314610211575b600080fd5b6101e76101e23660046114ba565b610434565b60405190151581526020015b60405180910390f35b6102046104a1565b6040516101f39190611508565b6101e761021f366004611557565b610533565b61022c61054e565b6040519081526020016101f3565b6102617f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101f3565b6101e7610287366004611581565b6105d7565b6102946105f2565b60405160ff90911681526020016101f3565b610204610676565b61022c6106f3565b6102c96102c43660046115bd565b61078a565b005b6102de6102d9366004611632565b6107d2565b604080516001600160a01b0390931683526020830191909152016101f3565b610305610808565b6040516101f39190611690565b61022c6103203660046116a3565b610869565b6102c96108f9565b6102c961090d565b61022c6103433660046116a3565b610956565b61022c6103563660046116be565b6109e8565b6005546001600160a01b0316610261565b610204610a4c565b6102c96103823660046115bd565b610a5b565b6101e7610287366004611557565b6102c96103a33660046116a3565b610a9f565b600454610261906001600160a01b031681565b6102617f000000000000000000000000000000000000000000000000000000000000000081565b610305610ab0565b61022c6103f83660046116be565b610b10565b6006546001600160a01b0316610261565b6102de61041c366004611632565b610ba7565b6102c961042f3660046116a3565b610bd4565b60006001600160e01b03198216631f9aa5f160e31b148061046557506001600160e01b031982166336372b0760e01b145b8061048057506001600160e01b0319821663a219a02560e01b145b8061049b57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546104b0906116f1565b80601f01602080910402602001604051908101604052809291908181526020018280546104dc906116f1565b80156105295780601f106104fe57610100808354040283529160200191610529565b820191906000526020600020905b81548152906001019060200180831161050c57829003601f168201915b5050505050905090565b6000604051632028747160e01b815260040160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d2919061172b565b905090565b6000604051638cd22d1960e01b815260040160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d29190611744565b6060600460009054906101000a90046001600160a01b03166001600160a01b0316630e05f6766040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105d2919081019061177d565b60006105d27f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077a9190611744565b61078590600a611924565b610c45565b610792610c89565b6107ce828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610cb692505050565b5050565b6000807f00000000000000000000000000000000000000000000000000000000000000006107ff84610c45565b91509150915091565b6060600380548060200260200160405190810160405280929190818152602001828054801561052957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610842575050505050905090565b6040516370a0823160e01b81526001600160a01b0382811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906370a08231906024015b602060405180830381865afa1580156108d5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049b919061172b565b610901610c89565b61090b6000610d74565b565b60065433906001600160a01b0316811461094a5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61095381610d74565b50565b6040516370a0823160e01b81526001600160a01b03828116600483015260009161049b917f000000000000000000000000000000000000000000000000000000000000000016906370a08231906024015b602060405180830381865afa1580156109c4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610785919061172b565b604051636eb1769f60e11b81526001600160a01b0383811660048301528281166024830152600091610a45917f0000000000000000000000000000000000000000000000000000000000000000169063dd62ed3e906044016109a7565b9392505050565b6060600180546104b0906116f1565b610a63610c89565b6107ce828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610d8d92505050565b610aa7610c89565b61095381610e40565b60606002805480602002602001604051908101604052809291908181526020018280548015610529576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610842575050505050905090565b604051636eb1769f60e11b81526001600160a01b03838116600483015282811660248301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063dd62ed3e90604401602060405180830381865afa158015610b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a45919061172b565b6000807f00000000000000000000000000000000000000000000000000000000000000006107ff84610f1c565b610bdc610c89565b600680546001600160a01b0383166001600160a01b03199091168117909155610c0d6005546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600081600003610c5757506000919050565b6004805460405163bd3f03f960e01b81526001600160a01b039091169163bd3f03f9916108b891869160029101611933565b6005546001600160a01b0316331461090b5760405163118cdaa760e01b8152336004820152602401610941565b610cbf81610f60565b610cc8816110f3565b8051610cdb906002906020840190611440565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316306001600160a01b03167f25b4c0059a7a45c3fb2e9a613393e8a0b8339d669153d7add5c83611d890748084604051610d699190611690565b60405180910390a450565b600680546001600160a01b031916905561095381611205565b610d9681611257565b610d9f816110f3565b8051610db2906003906020840190611440565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316306001600160a01b03167f3105ebf8cfe0d8803d5b103773a21806a6c43fa57501763b771be3db158bfcd584604051610d699190611690565b6040516301ffc9a760e01b815263b130abe360e01b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015610e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaf9190611991565b610f135760405162461bcd60e51b815260206004820152602f60248201527f446f6573206e6f7420696d706c656d656e742049556e6973776170563244796e60448201526e30b6b4b1a83934b1b2a937baba32b960891b6064820152608401610941565b610953816113f4565b600081600003610f2e57506000919050565b6004805460405163bd3f03f960e01b81526001600160a01b039091169163bd3f03f9916108b891869160039101611933565b6001815111610fb15760405162461bcd60e51b815260206004820181905260248201527f50617468206d7573742068617665206174206c65617374203220746f6b656e736044820152606401610941565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681600081518110610fee57610fee6119b3565b60200260200101516001600160a01b03161461104c5760405162461bcd60e51b815260206004820181905260248201527f4261736520746f6b656e206d75737420626520666972737420696e20706174686044820152606401610941565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001835161108591906119c9565b81518110611095576110956119b3565b60200260200101516001600160a01b0316146109535760405162461bcd60e51b815260206004820181905260248201527f51756f746520746f6b656e206d757374206265206c61737420696e20706174686044820152606401610941565b60045481516001600160a01b039091169063bd3f03f990839060009061111b5761111b6119b3565b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611160573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111849190611744565b61118f90600a611924565b836040518363ffffffff1660e01b81526004016111ad9291906119dc565b602060405180830381865afa9250505080156111e6575060408051601f3d908101601f191682019092526111e39181019061172b565b60015b6107ce57806040516354da4f1960e01b81526004016109419190611690565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60018151116112a85760405162461bcd60e51b815260206004820181905260248201527f50617468206d7573742068617665206174206c65617374203220746f6b656e736044820152606401610941565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816000815181106112e5576112e56119b3565b60200260200101516001600160a01b03161461134d5760405162461bcd60e51b815260206004820152602160248201527f51756f746520746f6b656e206d75737420626520666972737420696e207061746044820152600d60fb1b6064820152608401610941565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001835161138691906119c9565b81518110611396576113966119b3565b60200260200101516001600160a01b0316146109535760405162461bcd60e51b815260206004820152601f60248201527f4261736520746f6b656e206d757374206265206c61737420696e2070617468006044820152606401610941565b600480546001600160a01b0319166001600160a01b03831690811790915560405130907fd208b3f2137ba34e4b2ea29e6e0558a1395796409f6b8328f2cbd5ff9159bc1590600090a350565b828054828255906000526020600020908101928215611495579160200282015b8281111561149557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611460565b506114a19291506114a5565b5090565b5b808211156114a157600081556001016114a6565b6000602082840312156114cc57600080fd5b81356001600160e01b031981168114610a4557600080fd5b60005b838110156114ff5781810151838201526020016114e7565b50506000910152565b60208152600082518060208401526115278160408501602087016114e4565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461155257600080fd5b919050565b6000806040838503121561156a57600080fd5b6115738361153b565b946020939093013593505050565b60008060006060848603121561159657600080fd5b61159f8461153b565b92506115ad6020850161153b565b9150604084013590509250925092565b600080602083850312156115d057600080fd5b823567ffffffffffffffff808211156115e857600080fd5b818501915085601f8301126115fc57600080fd5b81358181111561160b57600080fd5b8660208260051b850101111561162057600080fd5b60209290920196919550909350505050565b60006020828403121561164457600080fd5b5035919050565b60008151808452602080850194506020840160005b838110156116855781516001600160a01b031687529582019590820190600101611660565b509495945050505050565b602081526000610a45602083018461164b565b6000602082840312156116b557600080fd5b610a458261153b565b600080604083850312156116d157600080fd5b6116da8361153b565b91506116e86020840161153b565b90509250929050565b600181811c9082168061170557607f821691505b60208210810361172557634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561173d57600080fd5b5051919050565b60006020828403121561175657600080fd5b815160ff81168114610a4557600080fd5b634e487b7160e01b600052604160045260246000fd5b60006020828403121561178f57600080fd5b815167ffffffffffffffff808211156117a757600080fd5b818401915084601f8301126117bb57600080fd5b8151818111156117cd576117cd611767565b604051601f8201601f19908116603f011681019083821181831017156117f5576117f5611767565b8160405282815287602084870101111561180e57600080fd5b61181f8360208301602088016114e4565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561187b5781600019048211156118615761186161182a565b8085161561186e57918102915b93841c9390800290611845565b509250929050565b6000826118925750600161049b565b8161189f5750600061049b565b81600181146118b557600281146118bf576118db565b600191505061049b565b60ff8411156118d0576118d061182a565b50506001821b61049b565b5060208310610133831016604e8410600b84101617156118fe575081810a61049b565b6119088383611840565b806000190482111561191c5761191c61182a565b029392505050565b6000610a4560ff841683611883565b600060408201848352602060406020850152818554808452606086019150866000526020600020935060005b818110156119845784546001600160a01b03168352600194850194928401920161195f565b5090979650505050505050565b6000602082840312156119a357600080fd5b81518015158114610a4557600080fd5b634e487b7160e01b600052603260045260246000fd5b8181038181111561049b5761049b61182a565b8281526040602082015260006119f5604083018461164b565b94935050505056fea2646970667358221220010d22d06d443982ab6747b918a4f147524563fb657637be8943b6752884d25564736f6c6343000818003350617468206d7573742068617665206174206c65617374203220746f6b656e7300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a4aa728d6c1de8ae3ecb9be91b8ab80456336c62000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000001c556e69737761702056322044796e616d696320574554482f5553444300000000000000000000000000000000000000000000000000000000000000000000000a64574554482d55534443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c806379ba509711610104578063aebab157116100a2578063dd62ed3e11610071578063dd62ed3e146103ea578063e30c3978146103fd578063e71dc5e51461040e578063f2fde38b1461042157600080fd5b8063aebab15714610395578063be41d5bc146103a8578063c55dae63146103bb578063cb27a434146103e257600080fd5b80638da5cb5b116100de5780638da5cb5b1461035b57806395d89b411461036c5780639bd230f314610374578063a9059cbb1461038757600080fd5b806379ba50971461032d5780637a19c83d146103355780638caecde51461034857600080fd5b806339ff2da2116101715780636702fcac1161014b5780636702fcac146102cb5780636bb26dba146102fd57806370a0823114610312578063715018a61461032557600080fd5b806339ff2da2146102a65780634971c79a146102ae5780634b230342146102b657600080fd5b806318160ddd116101ad57806318160ddd14610224578063217a4b701461023a57806323b872dd14610279578063313ce5671461028c57600080fd5b806301ffc9a7146101d457806306fdde03146101fc578063095ea7b314610211575b600080fd5b6101e76101e23660046114ba565b610434565b60405190151581526020015b60405180910390f35b6102046104a1565b6040516101f39190611508565b6101e761021f366004611557565b610533565b61022c61054e565b6040519081526020016101f3565b6102617f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b6040516001600160a01b0390911681526020016101f3565b6101e7610287366004611581565b6105d7565b6102946105f2565b60405160ff90911681526020016101f3565b610204610676565b61022c6106f3565b6102c96102c43660046115bd565b61078a565b005b6102de6102d9366004611632565b6107d2565b604080516001600160a01b0390931683526020830191909152016101f3565b610305610808565b6040516101f39190611690565b61022c6103203660046116a3565b610869565b6102c96108f9565b6102c961090d565b61022c6103433660046116a3565b610956565b61022c6103563660046116be565b6109e8565b6005546001600160a01b0316610261565b610204610a4c565b6102c96103823660046115bd565b610a5b565b6101e7610287366004611557565b6102c96103a33660046116a3565b610a9f565b600454610261906001600160a01b031681565b6102617f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b610305610ab0565b61022c6103f83660046116be565b610b10565b6006546001600160a01b0316610261565b6102de61041c366004611632565b610ba7565b6102c961042f3660046116a3565b610bd4565b60006001600160e01b03198216631f9aa5f160e31b148061046557506001600160e01b031982166336372b0760e01b145b8061048057506001600160e01b0319821663a219a02560e01b145b8061049b57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546104b0906116f1565b80601f01602080910402602001604051908101604052809291908181526020018280546104dc906116f1565b80156105295780601f106104fe57610100808354040283529160200191610529565b820191906000526020600020905b81548152906001019060200180831161050c57829003601f168201915b5050505050905090565b6000604051632028747160e01b815260040160405180910390fd5b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d2919061172b565b905090565b6000604051638cd22d1960e01b815260040160405180910390fd5b60007f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d29190611744565b6060600460009054906101000a90046001600160a01b03166001600160a01b0316630e05f6766040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105d2919081019061177d565b60006105d27f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077a9190611744565b61078590600a611924565b610c45565b610792610c89565b6107ce828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610cb692505050565b5050565b6000807f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486107ff84610c45565b91509150915091565b6060600380548060200260200160405190810160405280929190818152602001828054801561052957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610842575050505050905090565b6040516370a0823160e01b81526001600160a01b0382811660048301526000917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2909116906370a08231906024015b602060405180830381865afa1580156108d5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049b919061172b565b610901610c89565b61090b6000610d74565b565b60065433906001600160a01b0316811461094a5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61095381610d74565b50565b6040516370a0823160e01b81526001600160a01b03828116600483015260009161049b917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a08231906024015b602060405180830381865afa1580156109c4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610785919061172b565b604051636eb1769f60e11b81526001600160a01b0383811660048301528281166024830152600091610a45917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2169063dd62ed3e906044016109a7565b9392505050565b6060600180546104b0906116f1565b610a63610c89565b6107ce828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610d8d92505050565b610aa7610c89565b61095381610e40565b60606002805480602002602001604051908101604052809291908181526020018280548015610529576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610842575050505050905090565b604051636eb1769f60e11b81526001600160a01b03838116600483015282811660248301526000917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29091169063dd62ed3e90604401602060405180830381865afa158015610b83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a45919061172b565b6000807f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26107ff84610f1c565b610bdc610c89565b600680546001600160a01b0383166001600160a01b03199091168117909155610c0d6005546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600081600003610c5757506000919050565b6004805460405163bd3f03f960e01b81526001600160a01b039091169163bd3f03f9916108b891869160029101611933565b6005546001600160a01b0316331461090b5760405163118cdaa760e01b8152336004820152602401610941565b610cbf81610f60565b610cc8816110f3565b8051610cdb906002906020840190611440565b507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03167f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316306001600160a01b03167f25b4c0059a7a45c3fb2e9a613393e8a0b8339d669153d7add5c83611d890748084604051610d699190611690565b60405180910390a450565b600680546001600160a01b031916905561095381611205565b610d9681611257565b610d9f816110f3565b8051610db2906003906020840190611440565b507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03167f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316306001600160a01b03167f3105ebf8cfe0d8803d5b103773a21806a6c43fa57501763b771be3db158bfcd584604051610d699190611690565b6040516301ffc9a760e01b815263b130abe360e01b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015610e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaf9190611991565b610f135760405162461bcd60e51b815260206004820152602f60248201527f446f6573206e6f7420696d706c656d656e742049556e6973776170563244796e60448201526e30b6b4b1a83934b1b2a937baba32b960891b6064820152608401610941565b610953816113f4565b600081600003610f2e57506000919050565b6004805460405163bd3f03f960e01b81526001600160a01b039091169163bd3f03f9916108b891869160039101611933565b6001815111610fb15760405162461bcd60e51b815260206004820181905260248201527f50617468206d7573742068617665206174206c65617374203220746f6b656e736044820152606401610941565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031681600081518110610fee57610fee6119b3565b60200260200101516001600160a01b03161461104c5760405162461bcd60e51b815260206004820181905260248201527f4261736520746f6b656e206d75737420626520666972737420696e20706174686044820152606401610941565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316816001835161108591906119c9565b81518110611095576110956119b3565b60200260200101516001600160a01b0316146109535760405162461bcd60e51b815260206004820181905260248201527f51756f746520746f6b656e206d757374206265206c61737420696e20706174686044820152606401610941565b60045481516001600160a01b039091169063bd3f03f990839060009061111b5761111b6119b3565b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611160573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111849190611744565b61118f90600a611924565b836040518363ffffffff1660e01b81526004016111ad9291906119dc565b602060405180830381865afa9250505080156111e6575060408051601f3d908101601f191682019092526111e39181019061172b565b60015b6107ce57806040516354da4f1960e01b81526004016109419190611690565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60018151116112a85760405162461bcd60e51b815260206004820181905260248201527f50617468206d7573742068617665206174206c65617374203220746f6b656e736044820152606401610941565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316816000815181106112e5576112e56119b3565b60200260200101516001600160a01b03161461134d5760405162461bcd60e51b815260206004820152602160248201527f51756f746520746f6b656e206d75737420626520666972737420696e207061746044820152600d60fb1b6064820152608401610941565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316816001835161138691906119c9565b81518110611396576113966119b3565b60200260200101516001600160a01b0316146109535760405162461bcd60e51b815260206004820152601f60248201527f4261736520746f6b656e206d757374206265206c61737420696e2070617468006044820152606401610941565b600480546001600160a01b0319166001600160a01b03831690811790915560405130907fd208b3f2137ba34e4b2ea29e6e0558a1395796409f6b8328f2cbd5ff9159bc1590600090a350565b828054828255906000526020600020908101928215611495579160200282015b8281111561149557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611460565b506114a19291506114a5565b5090565b5b808211156114a157600081556001016114a6565b6000602082840312156114cc57600080fd5b81356001600160e01b031981168114610a4557600080fd5b60005b838110156114ff5781810151838201526020016114e7565b50506000910152565b60208152600082518060208401526115278160408501602087016114e4565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461155257600080fd5b919050565b6000806040838503121561156a57600080fd5b6115738361153b565b946020939093013593505050565b60008060006060848603121561159657600080fd5b61159f8461153b565b92506115ad6020850161153b565b9150604084013590509250925092565b600080602083850312156115d057600080fd5b823567ffffffffffffffff808211156115e857600080fd5b818501915085601f8301126115fc57600080fd5b81358181111561160b57600080fd5b8660208260051b850101111561162057600080fd5b60209290920196919550909350505050565b60006020828403121561164457600080fd5b5035919050565b60008151808452602080850194506020840160005b838110156116855781516001600160a01b031687529582019590820190600101611660565b509495945050505050565b602081526000610a45602083018461164b565b6000602082840312156116b557600080fd5b610a458261153b565b600080604083850312156116d157600080fd5b6116da8361153b565b91506116e86020840161153b565b90509250929050565b600181811c9082168061170557607f821691505b60208210810361172557634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561173d57600080fd5b5051919050565b60006020828403121561175657600080fd5b815160ff81168114610a4557600080fd5b634e487b7160e01b600052604160045260246000fd5b60006020828403121561178f57600080fd5b815167ffffffffffffffff808211156117a757600080fd5b818401915084601f8301126117bb57600080fd5b8151818111156117cd576117cd611767565b604051601f8201601f19908116603f011681019083821181831017156117f5576117f5611767565b8160405282815287602084870101111561180e57600080fd5b61181f8360208301602088016114e4565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561187b5781600019048211156118615761186161182a565b8085161561186e57918102915b93841c9390800290611845565b509250929050565b6000826118925750600161049b565b8161189f5750600061049b565b81600181146118b557600281146118bf576118db565b600191505061049b565b60ff8411156118d0576118d061182a565b50506001821b61049b565b5060208310610133831016604e8410600b84101617156118fe575081810a61049b565b6119088383611840565b806000190482111561191c5761191c61182a565b029392505050565b6000610a4560ff841683611883565b600060408201848352602060406020850152818554808452606086019150866000526020600020935060005b818110156119845784546001600160a01b03168352600194850194928401920161195f565b5090979650505050505050565b6000602082840312156119a357600080fd5b81518015158114610a4557600080fd5b634e487b7160e01b600052603260045260246000fd5b8181038181111561049b5761049b61182a565b8281526040602082015260006119f5604083018461164b565b94935050505056fea2646970667358221220010d22d06d443982ab6747b918a4f147524563fb657637be8943b6752884d25564736f6c63430008180033

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

00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a4aa728d6c1de8ae3ecb9be91b8ab80456336c62000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000001c556e69737761702056322044796e616d696320574554482f5553444300000000000000000000000000000000000000000000000000000000000000000000000a64574554482d55534443000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

-----Decoded View---------------
Arg [0] : _name (string): Uniswap V2 Dynamic WETH/USDC
Arg [1] : _symbol (string): dWETH-USDC
Arg [2] : _baseToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [3] : _quoteToken (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [4] : _dynamicPriceRouter (address): 0xA4aa728d6C1De8aE3ECB9Be91B8aB80456336c62
Arg [5] : _baseToQuotePath (address[]): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [6] : _quoteToBasePath (address[]): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48,0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

-----Encoded View---------------
17 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [4] : 000000000000000000000000a4aa728d6c1de8ae3ecb9be91b8ab80456336c62
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [6] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [7] : 000000000000000000000000000000000000000000000000000000000000001c
Arg [8] : 556e69737761702056322044796e616d696320574554482f5553444300000000
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [10] : 64574554482d5553444300000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [12] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [13] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [15] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [16] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2


Loading...
Loading
Loading...
Loading
[ 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.